diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2022-06-13 08:57:15 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2022-07-14 18:01:25 +0000 |
commit | a2d4222865d0ef80687403e52976bd691ec2faee (patch) | |
tree | dca021f3b7bafe66937adb7b94e88f5506d403e9 /usr/src | |
parent | aa88555e2aa3d01aff5e421451572bdfcf722282 (diff) | |
download | illumos-joyent-a2d4222865d0ef80687403e52976bd691ec2faee.tar.gz |
14557 Attempts to map PCI BARs without MMIO ends in panics
Reviewed by: C Fraire <cfraire@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/i86pc/io/pci/pci_common.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/usr/src/uts/i86pc/io/pci/pci_common.c b/usr/src/uts/i86pc/io/pci/pci_common.c index feb5fbfd25..fe1918d121 100644 --- a/usr/src/uts/i86pc/io/pci/pci_common.c +++ b/usr/src/uts/i86pc/io/pci/pci_common.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -1018,6 +1019,31 @@ pci_common_get_reg_prop(dev_info_t *dip, pci_regspec_t *pci_rp) for (i = 0; i < number; i++) { if ((assigned_addr[i].pci_phys_hi & PCI_CONF_ADDR_MASK) == phys_hi) { + /* + * When the system does not manage to allocate PCI + * resources for a device, then the value that is stored + * in assigned addresses ends up being the hardware + * default reset value of '0'. On currently supported + * platforms, physical address zero is associated with + * memory; however, on other platforms this may be the + * exception vector table (ARM), etc. and so we opt to + * generally keep the idea in PCI that the reset value + * will not be used for actual MMIO allocations. If such + * a platform comes around where it is worth using that + * bit of MMIO for PCI then we should make this check + * platform-specific. + * + * Note, the +1 in the print statement is because a + * given regs[0] describes B/D/F information for the + * device. + */ + if (assigned_addr[i].pci_phys_mid == 0 && + assigned_addr[i].pci_phys_low == 0) { + dev_err(dip, CE_WARN, "regs[%u] does not have " + "a valid MMIO address", i + 1); + goto err; + } + pci_rp->pci_phys_mid = assigned_addr[i].pci_phys_mid; pci_rp->pci_phys_low = assigned_addr[i].pci_phys_low; ddi_prop_free(assigned_addr); @@ -1025,6 +1051,7 @@ pci_common_get_reg_prop(dev_info_t *dip, pci_regspec_t *pci_rp) } } +err: ddi_prop_free(assigned_addr); return (DDI_FAILURE); } |