Browse Source

[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>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
cc40fcbf8b
2 changed files with 33 additions and 1 deletions
  1. 18
    0
      src/arch/x86/prefix/mromprefix.S
  2. 15
    1
      src/arch/x86/prefix/undiloader.S

+ 18
- 0
src/arch/x86/prefix/mromprefix.S View File

@@ -456,6 +456,24 @@ pci_set_mem_access:
456 456
 	ret
457 457
 	.size	pci_set_mem_access, . - pci_set_mem_access
458 458
 
459
+/* Update image source address for UNDI loader
460
+ *
461
+ * Parameters:
462
+ *   %esi : Image source address
463
+ * Returns:
464
+ *   %esi : Image source address
465
+ */
466
+	.section ".prefix", "ax", @progbits
467
+	.globl	undiloader_source
468
+undiloader_source:
469
+	/* Always use expansion ROM BAR directly when installing via
470
+	 * the UNDI loader entry point, since the PMM-allocated block
471
+	 * may collide with whatever is calling the UNDI loader entry
472
+	 * point.
473
+	 */
474
+	xorl	%esi, %esi
475
+	ret
476
+
459 477
 /* Payload prefix
460 478
  *
461 479
  * We include a dummy ROM header to cover the "hidden" portion of the

+ 15
- 1
src/arch/x86/prefix/undiloader.S View File

@@ -35,7 +35,8 @@ undiloader:
35 35
 	movw	%es:12(%di), %bx
36 36
 	movw	%es:14(%di), %ax
37 37
 	movl	image_source, %esi
38
-	movl	decompress_to, %edi
38
+	call	undiloader_source
39
+	xorl	%edi, %edi
39 40
 	orl	$0xffffffff, %ebp	/* Allow arbitrary relocation */
40 41
 	call	install_prealloc
41 42
 	popw	%di
@@ -57,3 +58,16 @@ undiloader:
57 58
 	popl	%edi
58 59
 	popl	%esi
59 60
 	lret
61
+
62
+/* Update image source address for UNDI loader
63
+ *
64
+ * Parameters:
65
+ *   %esi : Image source address
66
+ * Returns:
67
+ *   %esi : Image source address
68
+ */
69
+	.section ".prefix", "ax", @progbits
70
+	.globl	undiloader_source
71
+	.weak	undiloader_source
72
+undiloader_source:
73
+	ret

Loading…
Cancel
Save