aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-11-02 15:38:08 +0000
committerMichael Brown <mcb30@ipxe.org>2023-11-02 15:38:08 +0000
commit36e1a559a28ea9d62eb1f6cde4df8fda3999525e (patch)
treeeb11443623ae089f99d4f07632d65706bfbacf60
parent1f3a37e342ff110a451afcdf15c75a90e643208d (diff)
downloadipxe-36e1a559a28ea9d62eb1f6cde4df8fda3999525e.zip
ipxe-36e1a559a28ea9d62eb1f6cde4df8fda3999525e.tar.gz
ipxe-36e1a559a28ea9d62eb1f6cde4df8fda3999525e.tar.bz2
[pci] Check that ECAM configuration space is within reachable memory
Some machines (observed with an AWS EC2 m7a.large instance) will place the ECAM configuration space window above 4GB, thereby making it unreachable from non-paged 32-bit code. This problem is currently ignored by iPXE, since the address is silently truncated in the call to ioremap(). (Note that other uses of ioremap() are not affected since the PCI core will already have checked for unreachable 64-bit BARs when retrieving the physical address to be mapped.) Fix by adding an explicit check that the region to be mapped starts within the reachable memory address space. (Assume that no machines will be sufficiently peverse to provide a region that straddles the 4GB boundary.) Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/bus/ecam.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/drivers/bus/ecam.c b/src/drivers/bus/ecam.c
index 62baebe..5e3debd 100644
--- a/src/drivers/bus/ecam.c
+++ b/src/drivers/bus/ecam.c
@@ -153,6 +153,14 @@ static int ecam_access ( struct pci_device *pci ) {
base = le64_to_cpu ( ecam.alloc.base );
base += ( ecam.alloc.start * ECAM_SIZE * PCI_BUSDEVFN ( 0, 1, 0, 0 ) );
len = ( ecam.range.count * ECAM_SIZE );
+ if ( base != ( ( unsigned long ) base ) ) {
+ DBGC ( &ecam, "ECAM %04x:[%02x-%02x] could not map "
+ "[%08llx,%08llx) outside CPU range\n",
+ le16_to_cpu ( ecam.alloc.segment ), ecam.alloc.start,
+ ecam.alloc.end, base, ( base + len ) );
+ rc = -ERANGE;
+ goto err_range;
+ }
ecam.regs = ioremap ( base, len );
if ( ! ecam.regs ) {
DBGC ( &ecam, "ECAM %04x:[%02x-%02x] could not map "
@@ -171,6 +179,7 @@ static int ecam_access ( struct pci_device *pci ) {
iounmap ( ecam.regs );
err_ioremap:
+ err_range:
err_find:
ecam.rc = rc;
return rc;