From 20f7840e3ff87e365d96fb7affe48f316ab8c225 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 14 Jul 2015 12:02:20 +0000 Subject: [PATCH] OvmfPkg: PciHostBridgeDxe: use private buffer in RootBridgeIoConfiguration() On output, the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Configuration() function produces a pointer to a buffer of ACPI 2.0 resource descriptors: Resources A pointer to the ACPI 2.0 resource descriptors that describe the current configuration of this PCI root bridge. The storage for the ACPI 2.0 resource descriptors is allocated by this function. The caller must treat the return buffer as read-only data, and the buffer must not be freed by the caller. PciHostBridgeDxe currently provides this buffer in a structure with static storage duration. If multiple root bridges existed in parallel, the pointers returned by their Configuration() methods would point to the same static storage. A later Configuration() call would overwrite the storage pointed out by an earlier Configuration() call (which was possibly made for a different, but still alive, root bridge.) Fix this problem by embedding the configuration buffer in PCI_ROOT_BRIDGE_INSTANCE. While we're at it, correct some typos (Desp -> Desc), spell out a missing pack(1) pragma, and improve formatting. Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Regression-tested-by: Gabriel Somlo Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17960 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/PciHostBridgeDxe/PciHostBridge.h | 8 ++++++ OvmfPkg/PciHostBridgeDxe/PciRootBridgeIo.c | 32 ++++++++++++---------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.h b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.h index 05b8cecf80..d2c28bcd20 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.h +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.h @@ -581,6 +581,13 @@ typedef struct { RES_STATUS Status; } PCI_RES_NODE; +#pragma pack(1) +typedef struct { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesc[TypeMax]; + EFI_ACPI_END_TAG_DESCRIPTOR EndDesc; +} RESOURCE_CONFIGURATION; +#pragma pack() + #define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32('e', '2', 'p', 'b') typedef struct { @@ -609,6 +616,7 @@ typedef struct { EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io; + RESOURCE_CONFIGURATION ConfigBuffer; } PCI_ROOT_BRIDGE_INSTANCE; diff --git a/OvmfPkg/PciHostBridgeDxe/PciRootBridgeIo.c b/OvmfPkg/PciHostBridgeDxe/PciRootBridgeIo.c index 5de28b18eb..c61fd1d7db 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/OvmfPkg/PciHostBridgeDxe/PciRootBridgeIo.c @@ -1,6 +1,7 @@ /** @file PCI Root Bridge Io Protocol implementation + Copyright (C) 2015, Red Hat, Inc. Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available @@ -15,19 +16,18 @@ #include "PciHostBridge.h" #include "IoFifo.h" -typedef struct { - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[TypeMax]; - EFI_ACPI_END_TAG_DESCRIPTOR EndDesp; -} RESOURCE_CONFIGURATION; - -RESOURCE_CONFIGURATION Configuration = { - {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0}, - {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0}, - {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0}, - {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0}, - {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0}, - {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}}, - {0x79, 0} +STATIC +CONST +RESOURCE_CONFIGURATION mConfigurationTemplate = { + { + { 0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0 }, // SpaceDesc[TypeIo] + { 0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0 }, // SpaceDesc[TypeMem32] + { 0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0 }, // SpaceDesc[TypePMem32] + { 0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0 }, // SpaceDesc[TypeMem64] + { 0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0 }, // SpaceDesc[TypePMem64] + { 0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0 } // SpaceDesc[TypeBus] + }, + { 0x79, 0 } // EndDesc }; // @@ -2607,12 +2607,14 @@ RootBridgeIoConfiguration ( UINTN Index; PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + CopyMem (&PrivateData->ConfigBuffer, &mConfigurationTemplate, + sizeof mConfigurationTemplate); for (Index = 0; Index < TypeMax; Index++) { if (PrivateData->ResAllocNode[Index].Status == ResAllocated) { EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; - Desc = &Configuration.SpaceDesp[Index]; + Desc = &PrivateData->ConfigBuffer.SpaceDesc[Index]; Desc->AddrRangeMin = PrivateData->ResAllocNode[Index].Base; Desc->AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1; @@ -2620,7 +2622,7 @@ RootBridgeIoConfiguration ( } } - *Resources = &Configuration; + *Resources = &PrivateData->ConfigBuffer; return EFI_SUCCESS; } -- 2.39.2