summaryrefslogtreecommitdiffstats
path: root/EdkShellBinPkg
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-06-19 01:41:15 +0000
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>2014-06-19 01:41:15 +0000
commitb0bc24aff5205e71aebbb7a15872974bb131d0f3 (patch)
tree8715af6dbca849b76dd3774ca531d7f81f698b72 /EdkShellBinPkg
parent183ecff5668f46073548a7d10291b41d35052b12 (diff)
downloadedk2-b0bc24aff5205e71aebbb7a15872974bb131d0f3.tar.gz
edk2-b0bc24aff5205e71aebbb7a15872974bb131d0f3.tar.bz2
edk2-b0bc24aff5205e71aebbb7a15872974bb131d0f3.zip
The following call tree exposes a bug in the lifetime (ie. too late
creation) of PciIoDevice->DevicePath. The bug can be triggered when PciBusDxe is built into OVMF, with qemu/KVM device assignment of a PCI-express device on the default 440FX machine type. OVMF correctly discovers that the device is PCIe and begins probing extended configuration space for the device. The root bridge has no way to access extended config space and correctly errors, sending us into the error reporting chain seen below. It's possible that this error path could also be reproduced on physical hardware when a PCI-to-PCIe bridge is present. GatherDeviceInfo() | GatherPpbInfo() | GatherP2CInfo() [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] CreatePciIoDevice() [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] AllocateZeroPool() LocateCapabilityRegBlock() [MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c] PciIoDevice->IsPciExp = TRUE LocatePciExpressCapabilityRegBlock() [MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c] PciIoConfigRead() via funcptr [MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c] RootBridgeIoPciRead() via funcptr [PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c] FAILS REPORT_STATUS_CODE_WITH_DEVICE_PATH() [MdePkg/Include/Library/ReportStatusCodeLib.h] ReportStatusCodeWithDevicePath() [MdeModulePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c] ASSERT (DevicePath != NULL) <--+ CreatePciDevicePath() | [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] sets PciIoDevice->DevicePath ----------+ In English: - CreatePciIoDevice() allocates a zeroed out PCI_IO_DEVICE structure. - PciIoConfigRead() tries to access the (extended) config space, and fails. - PciIoConfigRead() wants to report a status code (read error) for the device path. - Unfortuantely, PciIoDevice->DevicePath is still NULL at that point. - The ASSERT() in ReportStatusCodeWithDevicePath() fires. Fix it by moving CreatePciDevicePath() into CreatePciIoDevice(), allowing PciIoDevice->DevicePath to be initialized before we begin probing the device capabilities: GatherDeviceInfo() | GatherPpbInfo() | GatherP2CInfo() [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] CreatePciIoDevice() [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] AllocateZeroPool() CreatePciDevicePath() [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] sets PciIoDevice->DevicePath -----------+ LocateCapabilityRegBlock() | [MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c] PciIoDevice->IsPciExp = TRUE | LocatePciExpressCapabilityRegBlock() | [MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c] PciIoConfigRead() via funcptr | [MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c] RootBridgeIoPciRead() via funcptr | [PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c] FAILS | REPORT_STATUS_CODE_WITH_DEVICE_PATH() | [MdePkg/Include/Library/ReportStatusCodeLib.h] ReportStatusCodeWithDevicePath() | [MdeModulePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c] ASSERT (DevicePath != NULL) <-----+ Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15567 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkShellBinPkg')
0 files changed, 0 insertions, 0 deletions