summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2008-10-29 02:10:33 +0100
committerMichael Brown2008-10-29 02:16:52 +0100
commit621101c36a61320ba965063658fde0eee94f73e0 (patch)
treef129a65d5eac7860a20450d7f671d1a476c924ef
parent[phantom] Add CLP settings interface (diff)
downloadipxe-621101c36a61320ba965063658fde0eee94f73e0.tar.gz
ipxe-621101c36a61320ba965063658fde0eee94f73e0.tar.xz
ipxe-621101c36a61320ba965063658fde0eee94f73e0.zip
[romprefix] Further sanity checks for the PCI 3 runtime segment address
This extends the sanity checks on the runtime segment address provided in %bx, first implemented in commit 5600955. We now allow the ROM to be placed anywhere above a000:0000 (rather than c000:0000, as before), since this is the region allowed by the PCI 3 spec. If the BIOS asks us to place the runtime image such that it would overlap with the init-time image (which is explicitly prohibited by the PCI 3 spec), then we assume that the BIOS is faulty and ignore the provided runtime segment address. Testing on a SuperMicro BIOS providing overlapping segment addresses shows that ignoring the provided runtime segment address is safe to do in these circumstances.
-rw-r--r--src/arch/i386/prefix/romprefix.S31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index 3351494b..9407e64c 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -190,11 +190,11 @@ init:
stc
movw $0xb101, %ax
int $0x1a
- jc 1f
+ jc no_pci3
cmpl $PCI_SIGNATURE, %edx
- jne 1f
+ jne no_pci3
testb %ah, %ah
- jnz 1f
+ jnz no_pci3
movw $init_message_pci, %si
xorw %di, %di
call print_message
@@ -205,20 +205,33 @@ init:
movb %bl, %al
call print_hex_byte
cmpb $3, %bh
- jb 1f
+ jb no_pci3
/* PCI >=3.0: leave %gs as-is if sane */
movw %gs, %ax
- cmpw $0xc000, %ax
- jae 2f
- /* PCI 3.0 with insane %gs value: print error and ignore %gs */
+ cmpw $0xa000, %ax /* Insane if %gs < 0xa000 */
+ jb pci3_insane
+ movw %cs, %bx /* Sane if %cs == %gs */
+ cmpw %bx, %ax
+ je 1f
+ movzbw romheader_size, %cx /* Sane if %cs+len <= %gs */
+ shlw $5, %cx
+ addw %cx, %bx
+ cmpw %bx, %ax
+ jae 1f
+ movw %cs, %bx /* Sane if %gs+len <= %cs */
+ addw %cx, %ax
+ cmpw %bx, %ax
+ jbe 1f
+pci3_insane: /* PCI 3.0 with insane %gs value: print error and ignore %gs */
movb $'!', %al
call print_character
movw %gs, %ax
call print_hex_word
-1: /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */
+no_pci3:
+ /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */
pushw %cs
popw %gs
-2: popl %edi
+1: popl %edi
popl %edx
popl %ebx