diff options
author | Aaron Durbin <adurbin@chromium.org> | 2015-10-07 17:22:42 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@gmail.com> | 2015-10-11 23:56:46 +0000 |
commit | ed253c8fd80573b2182aa5fd27033750cff48c0b (patch) | |
tree | 00cb4f59ce9bf9fe07fb3655677fe5348195ba09 /src/lib | |
parent | fb9e378f2d239df8f3bd582f4f9d862f31748cbb (diff) | |
download | coreboot-ed253c8fd80573b2182aa5fd27033750cff48c0b.tar.xz |
cbfs: don't load x86 programs over the top of read-only media
On x86 the early stages are currently execute-in-place which
means they live in the memory-mapped spi flash. However, when
loading romstage from verstage the romstage is
execute-in-place so it's unnecessary to write over a read-only
media -- not to mention writing to read-only memory is wrong
to begin with.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built and booted glados. Noted reduction of 20ms when
loading romstage.
Change-Id: I7cd399302a3925a05fbce82600b4c50ea66a0fcb
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11823
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/cbfs.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 05b939cdfe..9cdc365963 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -220,6 +220,16 @@ int cbfs_prog_stage_load(struct prog *pstage) load = (void *)(uintptr_t)stage.load; entry = (void *)(uintptr_t)stage.entry; + /* Hacky way to not load programs over read only media. The stages + * that would hit this path initialize themselves. */ + if (ENV_VERSTAGE && IS_ENABLED(CONFIG_ARCH_X86) && + IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) { + void *mapping = rdev_mmap(fh, foffset, fsize); + rdev_munmap(fh, mapping); + if (mapping == load) + goto out; + } + if (stage.compression == CBFS_COMPRESS_NONE) { if (rdev_readat(fh, load, foffset, fsize) != fsize) return -1; @@ -242,6 +252,8 @@ int cbfs_prog_stage_load(struct prog *pstage) memset(&load[fsize], 0, stage.memlen - fsize); arch_segment_loaded((uintptr_t)load, stage.memlen, SEG_FINAL); + +out: prog_set_area(pstage, load, stage.memlen); prog_set_entry(pstage, entry, NULL); |