summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2016-12-05 15:11:00 +0100
committerMichael Brown2016-12-05 16:21:45 +0100
commitcc40fcbf8b0dedc18431b9281f793c20c6276f96 (patch)
tree55fb4d4089b4c516960ee7828938a94f7bfbeeca /src/arch
parent[undi] Allocate base memory before calling UNDI loader entry point (diff)
downloadipxe-cc40fcbf8b0dedc18431b9281f793c20c6276f96.tar.gz
ipxe-cc40fcbf8b0dedc18431b9281f793c20c6276f96.tar.xz
ipxe-cc40fcbf8b0dedc18431b9281f793c20c6276f96.zip
[romprefix] Avoid using PMM-allocated memory in UNDI loader entry point
The UNDI loader entry point is very likely to be called after POST, when there is a high chance that the PMM-allocated image source area and decompression area have been reused by something else. In particular, using an iPXE .iso to test a separate iPXE ROM's UNDI loader entry point in a qemu VM is likely to crash. SeaBIOS allocates PMM blocks from close to the top of memory and so these blocks have a high chance of colliding with the runtime addresses subsequently chosen by the non-ROM iPXE by scanning the INT 15,e820 memory map. The standard romprefix.S has no choice about relying on the PMM-allocated image source area, since it has no other way to retrieve its compressed payload. In mromprefix.S, the image source area functions only as an optional buffer used to avoid repeated reads from the (potentially slow) expansion ROM BAR by the decompression code. We can therefore always set %esi=0 when calling install_prealloc from the UNDI loader entry point, and simply fall back to reading directly from the expansion ROM BAR. We can always set %edi=0 when calling install_prealloc from the UNDI loader entry point. This will behave as though the decompression area PMM allocation failed, and will therefore use INT 15,88 to find a temporary decompression area somewhere close to 64MB. This is by no means guaranteed to be safe from collisions, but it's probably safer on balance than the PMM-allocated address. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/prefix/mromprefix.S18
-rw-r--r--src/arch/x86/prefix/undiloader.S16
2 files changed, 33 insertions, 1 deletions
diff --git a/src/arch/x86/prefix/mromprefix.S b/src/arch/x86/prefix/mromprefix.S
index b636b92a..568d1c00 100644
--- a/src/arch/x86/prefix/mromprefix.S
+++ b/src/arch/x86/prefix/mromprefix.S
@@ -456,6 +456,24 @@ pci_set_mem_access:
ret
.size pci_set_mem_access, . - pci_set_mem_access
+/* Update image source address for UNDI loader
+ *
+ * Parameters:
+ * %esi : Image source address
+ * Returns:
+ * %esi : Image source address
+ */
+ .section ".prefix", "ax", @progbits
+ .globl undiloader_source
+undiloader_source:
+ /* Always use expansion ROM BAR directly when installing via
+ * the UNDI loader entry point, since the PMM-allocated block
+ * may collide with whatever is calling the UNDI loader entry
+ * point.
+ */
+ xorl %esi, %esi
+ ret
+
/* Payload prefix
*
* We include a dummy ROM header to cover the "hidden" portion of the
diff --git a/src/arch/x86/prefix/undiloader.S b/src/arch/x86/prefix/undiloader.S
index 530b48e8..1d77110e 100644
--- a/src/arch/x86/prefix/undiloader.S
+++ b/src/arch/x86/prefix/undiloader.S
@@ -35,7 +35,8 @@ undiloader:
movw %es:12(%di), %bx
movw %es:14(%di), %ax
movl image_source, %esi
- movl decompress_to, %edi
+ call undiloader_source
+ xorl %edi, %edi
orl $0xffffffff, %ebp /* Allow arbitrary relocation */
call install_prealloc
popw %di
@@ -57,3 +58,16 @@ undiloader:
popl %edi
popl %esi
lret
+
+/* Update image source address for UNDI loader
+ *
+ * Parameters:
+ * %esi : Image source address
+ * Returns:
+ * %esi : Image source address
+ */
+ .section ".prefix", "ax", @progbits
+ .globl undiloader_source
+ .weak undiloader_source
+undiloader_source:
+ ret