From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.2598.1603914168116783998 for ; Wed, 28 Oct 2020 12:42:48 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: ard.biesheuvel@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CA1921BB2; Wed, 28 Oct 2020 12:42:47 -0700 (PDT) Received: from e123331-lin.nice.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B98FB3F68F; Wed, 28 Oct 2020 12:42:45 -0700 (PDT) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Dandan Bi , Liming Gao , Jian J Wang , Hao A Wu , Sami Mujawar , Laszlo Ersek , Leif Lindholm Subject: [PATCH v2 2/3] MdeModulePkg/AcpiTableDxe: use pool allocation for RSDT/XSDT if possible Date: Wed, 28 Oct 2020 20:42:25 +0100 Message-Id: <20201028194226.21556-3-ard.biesheuvel@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201028194226.21556-1-ard.biesheuvel@arm.com> References: <20201028194226.21556-1-ard.biesheuvel@arm.com> If no memory allocation limit is in effect for ACPI tables, prefer pool allocations over page allocations, to avoid wasting memory on systems where page based allocations are rounded up to 64 KB, such as AArch64. Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 118 ++++++++++++-------- 1 file changed, 72 insertions(+), 46 deletions(-) diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c index e85a98aee6bf..3793291a9668 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c @@ -355,28 +355,39 @@ ReallocateAcpiTableBuffer ( NewMaxTableNumber * sizeof (UINT32); } - // - // Allocate memory in the lower 32 bit of address range for - // compatibility with ACPI 1.0 OS. - // - // This is done because ACPI 1.0 pointers are 32 bit values. - // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. - // There is no architectural reason these should be below 4GB, it is purely - // for convenience of implementation that we force memory below 4GB. - // - PageAddress = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - mAcpiTableAllocType, - EfiACPIReclaimMemory, - EFI_SIZE_TO_PAGES (TotalSize), - &PageAddress - ); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // Allocate memory in the lower 32 bit of address range for + // compatibility with ACPI 1.0 OS. + // + // This is done because ACPI 1.0 pointers are 32 bit values. + // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. + // There is no architectural reason these should be below 4GB, it is purely + // for convenience of implementation that we force memory below 4GB. + // + PageAddress = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + mAcpiTableAllocType, + EfiACPIReclaimMemory, + EFI_SIZE_TO_PAGES (TotalSize), + &PageAddress + ); + } else { + Status = gBS->AllocatePool ( + EfiACPIReclaimMemory, + TotalSize, + (VOID **)&Pointer + ); + } if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } - Pointer = (UINT8 *) (UINTN) PageAddress; + if (mAcpiTableAllocType != AllocateAnyPages) { + Pointer = (UINT8 *)(UINTN)PageAddress; + } + ZeroMem (Pointer, TotalSize); AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer; @@ -406,21 +417,26 @@ ReallocateAcpiTableBuffer ( } CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64))); - // - // Calculate orignal ACPI table buffer size - // - TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT - mEfiAcpiMaxNumTables * sizeof (UINT64); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // Calculate orignal ACPI table buffer size + // + TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT + mEfiAcpiMaxNumTables * sizeof (UINT64); - if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) { - TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT - mEfiAcpiMaxNumTables * sizeof (UINT32) + - sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT - mEfiAcpiMaxNumTables * sizeof (UINT32); + if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) { + TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT + mEfiAcpiMaxNumTables * sizeof (UINT32) + + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT + mEfiAcpiMaxNumTables * sizeof (UINT32); + } + + gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, + EFI_SIZE_TO_PAGES (TotalSize)); + } else { + gBS->FreePool (TempPrivateData.Rsdt1); } - gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize)); - // // Update the Max ACPI table number // @@ -1763,29 +1779,39 @@ AcpiTableAcpiTableConstructor ( mEfiAcpiMaxNumTables * sizeof (UINT32); } - // - // Allocate memory in the lower 32 bit of address range for - // compatibility with ACPI 1.0 OS. - // - // This is done because ACPI 1.0 pointers are 32 bit values. - // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. - // There is no architectural reason these should be below 4GB, it is purely - // for convenience of implementation that we force memory below 4GB. - // - PageAddress = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - mAcpiTableAllocType, - EfiACPIReclaimMemory, - EFI_SIZE_TO_PAGES (TotalSize), - &PageAddress - ); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // Allocate memory in the lower 32 bit of address range for + // compatibility with ACPI 1.0 OS. + // + // This is done because ACPI 1.0 pointers are 32 bit values. + // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. + // There is no architectural reason these should be below 4GB, it is purely + // for convenience of implementation that we force memory below 4GB. + // + PageAddress = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + mAcpiTableAllocType, + EfiACPIReclaimMemory, + EFI_SIZE_TO_PAGES (TotalSize), + &PageAddress + ); + } else { + Status = gBS->AllocatePool ( + EfiACPIReclaimMemory, + TotalSize, + (VOID **)&Pointer + ); + } if (EFI_ERROR (Status)) { gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize)); return EFI_OUT_OF_RESOURCES; } - Pointer = (UINT8 *) (UINTN) PageAddress; + if (mAcpiTableAllocType != AllocateAnyPages) { + Pointer = (UINT8 *)(UINTN)PageAddress; + } ZeroMem (Pointer, TotalSize); AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer; -- 2.17.1