From nobody Tue Apr 30 17:23:48 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1488876142517985.3437233748829; Tue, 7 Mar 2017 00:42:22 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 745F18034E; Tue, 7 Mar 2017 00:42:15 -0800 (PST) Received: from mail-wr0-x22b.google.com (mail-wr0-x22b.google.com [IPv6:2a00:1450:400c:c0c::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E65AD8034D for ; Tue, 7 Mar 2017 00:42:13 -0800 (PST) Received: by mail-wr0-x22b.google.com with SMTP id g10so133624191wrg.2 for ; Tue, 07 Mar 2017 00:42:13 -0800 (PST) Received: from ards-macbook-pro.c.hoisthospitality.com ([109.74.56.122]) by smtp.gmail.com with ESMTPSA id u41sm30097838wrc.24.2017.03.07.00.42.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Mar 2017 00:42:10 -0800 (PST) X-Original-To: edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cDmXFuBDhWoK75yZxpup5TSz6RkIjwNjnoBbpUhRalA=; b=YfJBspfNkUtbcJFk3ULlSn4f7mfKrkfkDOKurQ0XrHbSyPefIfqISyOFtd38/8Rola +PsGo5J+CRRp0RGYIlojzuZq/bgW2D2SLRKu+4D0oMHaRtsBuYPmPcGp1b8orrMcqgIN GY9vC36sNYWJKVJNwTCCBf+RJIFR6alrP0Ub8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cDmXFuBDhWoK75yZxpup5TSz6RkIjwNjnoBbpUhRalA=; b=oiRq0UoOoimdW0xPib5ZPi6st+tvI+4Qv5B+CopWWNsxSBsILkTEhRJwfT7rnG3c4J PX/KPWuwY8VIlZRWe+xOVEX2ntznqKZFgDwJgqA+YTrNfQfgzUwfz5QzHdFWLtAapJUk dIpw4tq3SNKUwJ/lrDhO3aGYefEXnUQrEpSTF/XbHZccfsMfBwp1KxipeAQYrS7Ed8PP xpA5t4NgOcNU4fhTLtKqQQZcPNoTaD13vQgPszQW7SVQZsAvB7qfzDranVCwyenip6pT H35J9fRW98FSrji/dO1E+gTQZTOIqR2LYkGPUhH7Je73Gr9Hem/cNGqoF8lGMrbaYlXb qrCQ== X-Gm-Message-State: AMke39nWrNpVxyjyJHvU5bDPfUB0QcW7/0yEvpnsrbl0Ox2vt2/P8ol5j8jFadCJ6E/xTeps X-Received: by 10.223.172.137 with SMTP id o9mr19503005wrc.66.1488876131896; Tue, 07 Mar 2017 00:42:11 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 7 Mar 2017 09:42:02 +0100 Message-Id: <1488876125-24396-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 1/4] ArmPkg: move ARM version of SetMemoryAttributes to ArmMmuLib X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lersek@redhat.com, Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" ... where it belongs, since AARCH64 already keeps it there, and non DXE users of ArmMmuLib (such as DxeIpl, for the non-executable stack) may need its functionality as well. While at it, rename SetMemoryAttributes to ArmSetMemoryAttributes, and make any functions that are not exported STATIC. Also, replace an explicit gBS->AllocatePages() call [which is DXE specific] with MemoryAllocationLib::AllocatePages(). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 410 -------------------- ArmPkg/Drivers/CpuDxe/CpuDxe.h | 14 +- ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 2 +- ArmPkg/Include/Chipset/ArmV7Mmu.h | 6 + ArmPkg/Include/Library/ArmMmuLib.h | 8 + ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 2 +- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 397 +++++++++++++++++++ 7 files changed, 414 insertions(+), 425 deletions(-) diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mm= u.c index d3c307f48317..12ca5b26673e 100644 --- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c @@ -19,19 +19,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHE= R EXPRESS OR IMPLIED. #include #include "CpuDxe.h" =20 -#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \ - EFI_MEMORY_WC | \ - EFI_MEMORY_WT | \ - EFI_MEMORY_WB | \ - EFI_MEMORY_UCE | \ - EFI_MEMORY_WP) - -// First Level Descriptors -typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR; - -// Second Level Descriptors -typedef UINT32 ARM_PAGE_TABLE_ENTRY; - EFI_STATUS SectionToGcdAttributes ( IN UINT32 SectionAttributes, @@ -350,403 +337,6 @@ SyncCacheConfig ( return EFI_SUCCESS; } =20 - - -EFI_STATUS -UpdatePageEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask, - OUT BOOLEAN *FlushTlbs OPTIONAL - ) -{ - EFI_STATUS Status; - UINT32 EntryValue; - UINT32 EntryMask; - UINT32 FirstLevelIdx; - UINT32 Offset; - UINT32 NumPageEntries; - UINT32 Descriptor; - UINT32 p; - UINT32 PageTableIndex; - UINT32 PageTableEntry; - UINT32 CurrentPageTableEntry; - VOID *Mva; - - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - volatile ARM_PAGE_TABLE_ENTRY *PageTable; - - Status =3D EFI_SUCCESS; - - // EntryMask: bitmask of values to change (1 =3D change this value, 0 = =3D leave alone) - // EntryValue: values at bit positions specified by EntryMask - EntryMask =3D TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK; - if ((Attributes & EFI_MEMORY_XP) !=3D 0) { - EntryValue =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN; - } else { - EntryValue =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE; - } - - // Although the PI spec is unclear on this, the GCD guarantees that only - // one Attribute bit is set at a time, so the order of the conditionals = below - // is irrelevant. If no memory attribute is specified, we preserve whate= ver - // memory type is set in the page tables, and update the permission attr= ibutes - // only. - if (Attributes & EFI_MEMORY_UC) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // T= EX[2:0] =3D 0, C=3D0, B=3D0 - } else if (Attributes & EFI_MEMORY_WC) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to normal non-cachable - EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX = [2:0]=3D 001 =3D 0x2, B=3D0, C=3D0 - } else if (Attributes & EFI_MEMORY_WT) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC= ; // TEX [2:0] =3D 0, C=3D1, B=3D0 - } else if (Attributes & EFI_MEMORY_WB) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // T= EX [2:0] =3D 001, C=3D1, B=3D1 - } else if (Attributes & CACHE_ATTRIBUTE_MASK) { - // catch unsupported memory type attributes - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - if ((Attributes & EFI_MEMORY_RO) !=3D 0) { - EntryValue |=3D TT_DESCRIPTOR_PAGE_AP_RO_RO; - } else { - EntryValue |=3D TT_DESCRIPTOR_PAGE_AP_RW_RW; - } - - // Obtain page table base - FirstLevelTable =3D (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress= (); - - // Calculate number of 4KB page table entries to change - NumPageEntries =3D Length / TT_DESCRIPTOR_PAGE_SIZE; - - // Iterate for the number of 4KB pages to change - Offset =3D 0; - for(p =3D 0; p < NumPageEntries; p++) { - // Calculate index into first level translation table for page table v= alue - - FirstLevelIdx =3D TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Off= set) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // Read the descriptor from the first level page table - Descriptor =3D FirstLevelTable[FirstLevelIdx]; - - // Does this descriptor need to be converted from section entry to 4K = pages? - if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) { - Status =3D ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SEC= TION_BASE_SHIFT); - if (EFI_ERROR(Status)) { - // Exit for loop - break; - } - - // Re-read descriptor - Descriptor =3D FirstLevelTable[FirstLevelIdx]; - if (FlushTlbs !=3D NULL) { - *FlushTlbs =3D TRUE; - } - } - - // Obtain page table base address - PageTable =3D (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(= Descriptor); - - // Calculate index into the page table - PageTableIndex =3D ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_= MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; - ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT); - - // Get the entry - CurrentPageTableEntry =3D PageTable[PageTableIndex]; - - // Mask off appropriate fields - PageTableEntry =3D CurrentPageTableEntry & ~EntryMask; - - // Mask in new attributes and/or permissions - PageTableEntry |=3D EntryValue; - - if (VirtualMask !=3D 0) { - // Make this virtual address point at a physical page - PageTableEntry &=3D ~VirtualMask; - } - - if (CurrentPageTableEntry !=3D PageTableEntry) { - Mva =3D (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SEC= TION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); - - // Only need to update if we are changing the entry - PageTable[PageTableIndex] =3D PageTableEntry; - ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], = Mva); - - // Clean/invalidate the cache for this page, but only - // if we are modifying the memory type attributes - if (((CurrentPageTableEntry ^ PageTableEntry) & TT_DESCRIPTOR_PAGE_C= ACHE_POLICY_MASK) !=3D 0) { - WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE); - } - } - - Status =3D EFI_SUCCESS; - Offset +=3D TT_DESCRIPTOR_PAGE_SIZE; - - } // End first level translation table loop - - return Status; -} - - - -EFI_STATUS -UpdateSectionEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask - ) -{ - EFI_STATUS Status =3D EFI_SUCCESS; - UINT32 EntryMask; - UINT32 EntryValue; - UINT32 FirstLevelIdx; - UINT32 NumSections; - UINT32 i; - UINT32 CurrentDescriptor; - UINT32 Descriptor; - VOID *Mva; - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - - // EntryMask: bitmask of values to change (1 =3D change this value, 0 = =3D leave alone) - // EntryValue: values at bit positions specified by EntryMask - - // Make sure we handle a section range that is unmapped - EntryMask =3D TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN= _MASK | - TT_DESCRIPTOR_SECTION_AP_MASK; - EntryValue =3D TT_DESCRIPTOR_SECTION_TYPE_SECTION; - - // Although the PI spec is unclear on this, the GCD guarantees that only - // one Attribute bit is set at a time, so the order of the conditionals = below - // is irrelevant. If no memory attribute is specified, we preserve whate= ver - // memory type is set in the page tables, and update the permission attr= ibutes - // only. - if (Attributes & EFI_MEMORY_UC) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; /= / TEX[2:0] =3D 0, C=3D0, B=3D0 - } else if (Attributes & EFI_MEMORY_WC) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to normal non-cachable - EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // T= EX [2:0]=3D 001 =3D 0x2, B=3D0, C=3D0 - } else if (Attributes & EFI_MEMORY_WT) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_AL= LOC; // TEX [2:0] =3D 0, C=3D1, B=3D0 - } else if (Attributes & EFI_MEMORY_WB) { - // modify cacheability attributes - EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; /= / TEX [2:0] =3D 001, C=3D1, B=3D1 - } else if (Attributes & CACHE_ATTRIBUTE_MASK) { - // catch unsupported memory type attributes - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - if (Attributes & EFI_MEMORY_RO) { - EntryValue |=3D TT_DESCRIPTOR_SECTION_AP_RO_RO; - } else { - EntryValue |=3D TT_DESCRIPTOR_SECTION_AP_RW_RW; - } - - if (Attributes & EFI_MEMORY_XP) { - EntryValue |=3D TT_DESCRIPTOR_SECTION_XN_MASK; - } - - // obtain page table base - FirstLevelTable =3D (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress= (); - - // calculate index into first level translation table for start of modif= ication - FirstLevelIdx =3D TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_= DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // calculate number of 1MB first level entries this applies to - NumSections =3D Length / TT_DESCRIPTOR_SECTION_SIZE; - - // iterate through each descriptor - for(i=3D0; i> TT_= DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // Get section attributes and convert to page attributes - SectionDescriptor =3D FirstLevelTable[FirstLevelIdx]; - PageDescriptor =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttribut= esToPageAttributes (SectionDescriptor, FALSE); - - // Allocate a page table for the 4KB entries (we use up a full page even= though we only need 1KB) - Status =3D gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1,= &PageTableAddr); - if (EFI_ERROR(Status)) { - return Status; - } - - PageTable =3D (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr; - - // Write the page table entries out - for (Index =3D 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { - PageTable[Index] =3D TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (In= dex << 12)) | PageDescriptor; - } - - // Flush d-cache so descriptors make it back to uncached memory for subs= equent table walks - WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, TT_DESC= RIPTOR_PAGE_SIZE); - - // Formulate page table entry, Domain=3D0, NS=3D0 - PageTableDescriptor =3D (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_= PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; - - // Write the page table entry out, replacing section entry - FirstLevelTable[FirstLevelIdx] =3D PageTableDescriptor; - - return EFI_SUCCESS; -} - - - -EFI_STATUS -SetMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask - ) -{ - EFI_STATUS Status; - UINT64 ChunkLength; - BOOLEAN FlushTlbs; - - if (Length =3D=3D 0) { - return EFI_SUCCESS; - } - - FlushTlbs =3D FALSE; - while (Length > 0) { - if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE =3D=3D 0) && - Length >=3D TT_DESCRIPTOR_SECTION_SIZE) { - - ChunkLength =3D Length - Length % TT_DESCRIPTOR_SECTION_SIZE; - - DEBUG ((DEBUG_PAGE, - "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", - BaseAddress, ChunkLength, Attributes)); - - Status =3D UpdateSectionEntries (BaseAddress, ChunkLength, Attribute= s, - VirtualMask); - - FlushTlbs =3D TRUE; - } else { - - // - // Process page by page until the next section boundary, but only if - // we have more than a section's worth of area to deal with after th= at. - // - ChunkLength =3D TT_DESCRIPTOR_SECTION_SIZE - - (BaseAddress % TT_DESCRIPTOR_SECTION_SIZE); - if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) { - ChunkLength =3D Length; - } - - DEBUG ((DEBUG_PAGE, - "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n", - BaseAddress, ChunkLength, Attributes)); - - Status =3D UpdatePageEntries (BaseAddress, ChunkLength, Attributes, - VirtualMask, &FlushTlbs); - } - - if (EFI_ERROR (Status)) { - break; - } - - BaseAddress +=3D ChunkLength; - Length -=3D ChunkLength; - } - - if (FlushTlbs) { - ArmInvalidateTlb (); - } - return Status; -} - UINT64 EfiAttributeToArmAttribute ( IN UINT64 EfiAttributes diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h index a46db8d25754..a0f71e69ec09 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h @@ -19,6 +19,7 @@ #include =20 #include +#include #include #include #include @@ -112,11 +113,6 @@ SyncCacheConfig ( IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol ); =20 -EFI_STATUS -ConvertSectionToPages ( - IN EFI_PHYSICAL_ADDRESS BaseAddress - ); - /** * Publish ARM Processor Data table in UEFI SYSTEM Table. * @param HobStart Pointer to the beginning of the HOB List= from PEI. @@ -132,14 +128,6 @@ PublishArmProcessorTable( VOID ); =20 -EFI_STATUS -SetMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask - ); - // The ARM Attributes might be defined on 64-bit (case of the long format = description table) UINT64 EfiAttributeToArmAttribute ( diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/C= puMmuCommon.c index 0f36a058407a..d0a3fedd3aa7 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c +++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c @@ -210,7 +210,7 @@ CpuSetMemoryAttributes ( if (EFI_ERROR (Status) || (RegionArmAttributes !=3D ArmAttributes) || ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) { - return SetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0); + return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0); } else { return EFI_SUCCESS; } diff --git a/ArmPkg/Include/Chipset/ArmV7Mmu.h b/ArmPkg/Include/Chipset/Arm= V7Mmu.h index 549a5cd7d45a..4d913824b4ed 100644 --- a/ArmPkg/Include/Chipset/ArmV7Mmu.h +++ b/ArmPkg/Include/Chipset/ArmV7Mmu.h @@ -229,6 +229,12 @@ TT_DESCRIPTOR_PAGE= _AP_RW_RW | \ TT_DESCRIPTOR_PAGE= _CACHE_POLICY_NON_CACHEABLE) =20 +// First Level Descriptors +typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR; + +// Second Level Descriptors +typedef UINT32 ARM_PAGE_TABLE_ENTRY; + UINT32 ConvertSectionAttributesToPageAttributes ( IN UINT32 SectionAttributes, diff --git a/ArmPkg/Include/Library/ArmMmuLib.h b/ArmPkg/Include/Library/Ar= mMmuLib.h index c1d43872d548..d3a302fa8125 100644 --- a/ArmPkg/Include/Library/ArmMmuLib.h +++ b/ArmPkg/Include/Library/ArmMmuLib.h @@ -62,4 +62,12 @@ ArmReplaceLiveTranslationEntry ( IN UINT64 Value ); =20 +EFI_STATUS +ArmSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN EFI_PHYSICAL_ADDRESS VirtualMask + ); + #endif diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Libr= ary/ArmMmuLib/AArch64/ArmMmuLibCore.c index df170d20a2c2..77f108971f3e 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -447,7 +447,7 @@ GcdAttributeToPageAttribute ( } =20 EFI_STATUS -SetMemoryAttributes ( +ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/= ArmMmuLib/Arm/ArmMmuLibCore.c index f981c5bbcab6..8a472a1eb64b 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,13 @@ #define ID_MMFR0_SHR_IMP_HW_COHERENT 1 #define ID_MMFR0_SHR_IGNORED 0xf =20 +#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \ + EFI_MEMORY_WC | \ + EFI_MEMORY_WT | \ + EFI_MEMORY_WB | \ + EFI_MEMORY_UCE | \ + EFI_MEMORY_WP) + UINTN EFIAPI ArmReadIdMmfr0 ( @@ -406,6 +414,395 @@ ArmConfigureMmu ( return RETURN_SUCCESS; } =20 +STATIC +EFI_STATUS +ConvertSectionToPages ( + IN EFI_PHYSICAL_ADDRESS BaseAddress + ) +{ + UINT32 FirstLevelIdx; + UINT32 SectionDescriptor; + UINT32 PageTableDescriptor; + UINT32 PageDescriptor; + UINT32 Index; + + volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; + volatile ARM_PAGE_TABLE_ENTRY *PageTable; + + DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)Base= Address)); + + // Obtain page table base + FirstLevelTable =3D (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress= (); + + // Calculate index into first level translation table for start of modif= ication + FirstLevelIdx =3D TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_= DESCRIPTOR_SECTION_BASE_SHIFT; + ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); + + // Get section attributes and convert to page attributes + SectionDescriptor =3D FirstLevelTable[FirstLevelIdx]; + PageDescriptor =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttribut= esToPageAttributes (SectionDescriptor, FALSE); + + // Allocate a page table for the 4KB entries (we use up a full page even= though we only need 1KB) + PageTable =3D (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1); + if (PageTable =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Write the page table entries out + for (Index =3D 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { + PageTable[Index] =3D TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (In= dex << 12)) | PageDescriptor; + } + + // Flush d-cache so descriptors make it back to uncached memory for subs= equent table walks + WriteBackInvalidateDataCacheRange ((VOID *)PageTable, TT_DESCRIPTOR_PAGE= _SIZE); + + // Formulate page table entry, Domain=3D0, NS=3D0 + PageTableDescriptor =3D (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGE= TABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; + + // Write the page table entry out, replacing section entry + FirstLevelTable[FirstLevelIdx] =3D PageTableDescriptor; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +UpdatePageEntries ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN EFI_PHYSICAL_ADDRESS VirtualMask, + OUT BOOLEAN *FlushTlbs OPTIONAL + ) +{ + EFI_STATUS Status; + UINT32 EntryValue; + UINT32 EntryMask; + UINT32 FirstLevelIdx; + UINT32 Offset; + UINT32 NumPageEntries; + UINT32 Descriptor; + UINT32 p; + UINT32 PageTableIndex; + UINT32 PageTableEntry; + UINT32 CurrentPageTableEntry; + VOID *Mva; + + volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; + volatile ARM_PAGE_TABLE_ENTRY *PageTable; + + Status =3D EFI_SUCCESS; + + // EntryMask: bitmask of values to change (1 =3D change this value, 0 = =3D leave alone) + // EntryValue: values at bit positions specified by EntryMask + EntryMask =3D TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK; + if (Attributes & EFI_MEMORY_XP) { + EntryValue =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN; + } else { + EntryValue =3D TT_DESCRIPTOR_PAGE_TYPE_PAGE; + } + + // Although the PI spec is unclear on this, the GCD guarantees that only + // one Attribute bit is set at a time, so the order of the conditionals = below + // is irrelevant. If no memory attribute is specified, we preserve whate= ver + // memory type is set in the page tables, and update the permission attr= ibutes + // only. + if (Attributes & EFI_MEMORY_UC) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // map to strongly ordered + EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // T= EX[2:0] =3D 0, C=3D0, B=3D0 + } else if (Attributes & EFI_MEMORY_WC) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // map to normal non-cachable + EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX = [2:0]=3D 001 =3D 0x2, B=3D0, C=3D0 + } else if (Attributes & EFI_MEMORY_WT) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // write through with no-allocate + EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC= ; // TEX [2:0] =3D 0, C=3D1, B=3D0 + } else if (Attributes & EFI_MEMORY_WB) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // write back (with allocate) + EntryValue |=3D TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // T= EX [2:0] =3D 001, C=3D1, B=3D1 + } else if (Attributes & CACHE_ATTRIBUTE_MASK) { + // catch unsupported memory type attributes + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + if (Attributes & EFI_MEMORY_RO) { + EntryValue |=3D TT_DESCRIPTOR_PAGE_AP_RO_RO; + } else { + EntryValue |=3D TT_DESCRIPTOR_PAGE_AP_RW_RW; + } + + // Obtain page table base + FirstLevelTable =3D (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress= (); + + // Calculate number of 4KB page table entries to change + NumPageEntries =3D Length / TT_DESCRIPTOR_PAGE_SIZE; + + // Iterate for the number of 4KB pages to change + Offset =3D 0; + for(p =3D 0; p < NumPageEntries; p++) { + // Calculate index into first level translation table for page table v= alue + + FirstLevelIdx =3D TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Off= set) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; + ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); + + // Read the descriptor from the first level page table + Descriptor =3D FirstLevelTable[FirstLevelIdx]; + + // Does this descriptor need to be converted from section entry to 4K = pages? + if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) { + Status =3D ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SEC= TION_BASE_SHIFT); + if (EFI_ERROR(Status)) { + // Exit for loop + break; + } + + // Re-read descriptor + Descriptor =3D FirstLevelTable[FirstLevelIdx]; + if (FlushTlbs !=3D NULL) { + *FlushTlbs =3D TRUE; + } + } + + // Obtain page table base address + PageTable =3D (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(= Descriptor); + + // Calculate index into the page table + PageTableIndex =3D ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_= MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; + ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT); + + // Get the entry + CurrentPageTableEntry =3D PageTable[PageTableIndex]; + + // Mask off appropriate fields + PageTableEntry =3D CurrentPageTableEntry & ~EntryMask; + + // Mask in new attributes and/or permissions + PageTableEntry |=3D EntryValue; + + if (VirtualMask !=3D 0) { + // Make this virtual address point at a physical page + PageTableEntry &=3D ~VirtualMask; + } + + if (CurrentPageTableEntry !=3D PageTableEntry) { + Mva =3D (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SEC= TION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); + + // Clean/invalidate the cache for this page, but only + // if we are modifying the memory type attributes + if (((CurrentPageTableEntry ^ PageTableEntry) & TT_DESCRIPTOR_PAGE_C= ACHE_POLICY_MASK) !=3D 0) { + WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE); + } + + // Only need to update if we are changing the entry + PageTable[PageTableIndex] =3D PageTableEntry; + ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], = Mva); + } + + Status =3D EFI_SUCCESS; + Offset +=3D TT_DESCRIPTOR_PAGE_SIZE; + + } // End first level translation table loop + + return Status; +} + +STATIC +EFI_STATUS +UpdateSectionEntries ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN EFI_PHYSICAL_ADDRESS VirtualMask + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + UINT32 EntryMask; + UINT32 EntryValue; + UINT32 FirstLevelIdx; + UINT32 NumSections; + UINT32 i; + UINT32 CurrentDescriptor; + UINT32 Descriptor; + VOID *Mva; + volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; + + // EntryMask: bitmask of values to change (1 =3D change this value, 0 = =3D leave alone) + // EntryValue: values at bit positions specified by EntryMask + + // Make sure we handle a section range that is unmapped + EntryMask =3D TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN= _MASK | + TT_DESCRIPTOR_SECTION_AP_MASK; + EntryValue =3D TT_DESCRIPTOR_SECTION_TYPE_SECTION; + + // Although the PI spec is unclear on this, the GCD guarantees that only + // one Attribute bit is set at a time, so the order of the conditionals = below + // is irrelevant. If no memory attribute is specified, we preserve whate= ver + // memory type is set in the page tables, and update the permission attr= ibutes + // only. + if (Attributes & EFI_MEMORY_UC) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // map to strongly ordered + EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; /= / TEX[2:0] =3D 0, C=3D0, B=3D0 + } else if (Attributes & EFI_MEMORY_WC) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // map to normal non-cachable + EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // T= EX [2:0]=3D 001 =3D 0x2, B=3D0, C=3D0 + } else if (Attributes & EFI_MEMORY_WT) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // write through with no-allocate + EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_AL= LOC; // TEX [2:0] =3D 0, C=3D1, B=3D0 + } else if (Attributes & EFI_MEMORY_WB) { + // modify cacheability attributes + EntryMask |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // write back (with allocate) + EntryValue |=3D TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; /= / TEX [2:0] =3D 001, C=3D1, B=3D1 + } else if (Attributes & CACHE_ATTRIBUTE_MASK) { + // catch unsupported memory type attributes + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + if (Attributes & EFI_MEMORY_RO) { + EntryValue |=3D TT_DESCRIPTOR_SECTION_AP_RO_RO; + } else { + EntryValue |=3D TT_DESCRIPTOR_SECTION_AP_RW_RW; + } + + if (Attributes & EFI_MEMORY_XP) { + EntryValue |=3D TT_DESCRIPTOR_SECTION_XN_MASK; + } + + // obtain page table base + FirstLevelTable =3D (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress= (); + + // calculate index into first level translation table for start of modif= ication + FirstLevelIdx =3D TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_= DESCRIPTOR_SECTION_BASE_SHIFT; + ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); + + // calculate number of 1MB first level entries this applies to + NumSections =3D Length / TT_DESCRIPTOR_SECTION_SIZE; + + // iterate through each descriptor + for(i=3D0; i 0) { + if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE =3D=3D 0) && + Length >=3D TT_DESCRIPTOR_SECTION_SIZE) { + + ChunkLength =3D Length - Length % TT_DESCRIPTOR_SECTION_SIZE; + + DEBUG ((DEBUG_PAGE, + "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", + BaseAddress, ChunkLength, Attributes)); + + Status =3D UpdateSectionEntries (BaseAddress, ChunkLength, Attribute= s, + VirtualMask); + + FlushTlbs =3D TRUE; + } else { + + // + // Process page by page until the next section boundary, but only if + // we have more than a section's worth of area to deal with after th= at. + // + ChunkLength =3D TT_DESCRIPTOR_SECTION_SIZE - + (BaseAddress % TT_DESCRIPTOR_SECTION_SIZE); + if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) { + ChunkLength =3D Length; + } + + DEBUG ((DEBUG_PAGE, + "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n", + BaseAddress, ChunkLength, Attributes)); + + Status =3D UpdatePageEntries (BaseAddress, ChunkLength, Attributes, + VirtualMask, &FlushTlbs); + } + + if (EFI_ERROR (Status)) { + break; + } + + BaseAddress +=3D ChunkLength; + Length -=3D ChunkLength; + } + + if (FlushTlbs) { + ArmInvalidateTlb (); + } + return Status; +} =20 EFI_STATUS ArmSetMemoryRegionNoExec ( --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Tue Apr 30 17:23:48 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1488876141549331.14959547228375; Tue, 7 Mar 2017 00:42:21 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id B720380351; Tue, 7 Mar 2017 00:42:16 -0800 (PST) Received: from mail-wm0-x236.google.com (mail-wm0-x236.google.com [IPv6:2a00:1450:400c:c09::236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id F1EB38034D for ; Tue, 7 Mar 2017 00:42:14 -0800 (PST) Received: by mail-wm0-x236.google.com with SMTP id t189so5253343wmt.1 for ; Tue, 07 Mar 2017 00:42:14 -0800 (PST) Received: from ards-macbook-pro.c.hoisthospitality.com ([109.74.56.122]) by smtp.gmail.com with ESMTPSA id u41sm30097838wrc.24.2017.03.07.00.42.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Mar 2017 00:42:12 -0800 (PST) X-Original-To: edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cje1j3fVtIY964WsnfvY5lXgsIVu4bZSUZSLo5whQrY=; b=Q69hr5OlbpLOVAzIw4x1IbQu2HmeoSqM0vW9xCkfyHxgyf34ZOoxfPN9v1memdORe3 kHLtfH3er/LiSAhTlUzDCH3o8w4C4g9o5aXYcb/MZCyX145FxSsP39LqJ7hKAc/NH4+u YVGe3Gkyq04tLDrMHzoa3HB8a8QyUbWAjGsWA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cje1j3fVtIY964WsnfvY5lXgsIVu4bZSUZSLo5whQrY=; b=kE5U0fD+Eh7PfmtXl/Az8lM52le2oKAtyxVDY4ImjlQxHM1vnV94Tg8hUDZupqc3Bn PyigaxRiZ0v8uT3WKR1V7Pls1g3L8eTP//CMMuafoo6AqhAO2OzNyXHjucuJSgCQoR4Y QRm6VEKYe+zEpVHSl5r3Xd/UuUrx/+Q9pHpxMKC8pz1xkmnjejIU6el37tDILV9htPX9 oapAe3uIpL8f/tlTdCGcYlySnjRinz66MI81GK9R5ruJaqqKBcsmhqxd3PJqRZxMlhq9 A7LXS/b3wiruz5BDP62AnxEtaOph9hhTCd1XPGzG/a6XfpgI1gJ2IjTfSJDMpBSowa0P kHvQ== X-Gm-Message-State: AMke39kT6d1qbL6VVLRWJki0w8BVUHZHZMLtGJ9T1guNA/8MW/m1XyY0ZXfN9Qb+hlAcKZTO X-Received: by 10.28.179.7 with SMTP id c7mr16751808wmf.128.1488876133333; Tue, 07 Mar 2017 00:42:13 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 7 Mar 2017 09:42:03 +0100 Message-Id: <1488876125-24396-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 2/4] ArmPkg/ArmMmuLib: remove VirtualMask arg from ArmSetMemoryAttributes X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lersek@redhat.com, Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" We no longer make use of the ArmMmuLib 'feature' to create aliased memory ranges with mismatched attributes, and in fact, it was only wired up in the ARM version to begin with. So remove the VirtualMask argument from ArmSetMemoryAttributes()'s prototype, and remove the dead code that referred to it. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 2 +- ArmPkg/Include/Library/ArmMmuLib.h | 3 +-- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 3 +-- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 21 ++++---------------- 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/C= puMmuCommon.c index d0a3fedd3aa7..8150486217cf 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c +++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c @@ -210,7 +210,7 @@ CpuSetMemoryAttributes ( if (EFI_ERROR (Status) || (RegionArmAttributes !=3D ArmAttributes) || ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) { - return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0); + return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes); } else { return EFI_SUCCESS; } diff --git a/ArmPkg/Include/Library/ArmMmuLib.h b/ArmPkg/Include/Library/Ar= mMmuLib.h index d3a302fa8125..fb7fd006417c 100644 --- a/ArmPkg/Include/Library/ArmMmuLib.h +++ b/ArmPkg/Include/Library/ArmMmuLib.h @@ -66,8 +66,7 @@ EFI_STATUS ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask + IN UINT64 Attributes ); =20 #endif diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Libr= ary/ArmMmuLib/AArch64/ArmMmuLibCore.c index 77f108971f3e..8bd1c6fad95f 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -450,8 +450,7 @@ EFI_STATUS ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask + IN UINT64 Attributes ) { EFI_STATUS Status; diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/= ArmMmuLib/Arm/ArmMmuLibCore.c index 8a472a1eb64b..351b6c03a42c 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -471,7 +471,6 @@ UpdatePageEntries ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask, OUT BOOLEAN *FlushTlbs OPTIONAL ) { @@ -587,11 +586,6 @@ UpdatePageEntries ( // Mask in new attributes and/or permissions PageTableEntry |=3D EntryValue; =20 - if (VirtualMask !=3D 0) { - // Make this virtual address point at a physical page - PageTableEntry &=3D ~VirtualMask; - } - if (CurrentPageTableEntry !=3D PageTableEntry) { Mva =3D (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SEC= TION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); =20 @@ -619,8 +613,7 @@ EFI_STATUS UpdateSectionEntries ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask + IN UINT64 Attributes ) { EFI_STATUS Status =3D EFI_SUCCESS; @@ -704,7 +697,6 @@ UpdateSectionEntries ( (FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, - VirtualMask, NULL); } else { // still a section entry @@ -714,9 +706,6 @@ UpdateSectionEntries ( =20 // mask in new attributes and/or permissions Descriptor |=3D EntryValue; - if (VirtualMask !=3D 0) { - Descriptor &=3D ~VirtualMask; - } =20 if (CurrentDescriptor !=3D Descriptor) { Mva =3D (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_= SECTION_BASE_SHIFT); @@ -743,8 +732,7 @@ EFI_STATUS ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask + IN UINT64 Attributes ) { EFI_STATUS Status; @@ -766,8 +754,7 @@ ArmSetMemoryAttributes ( "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", BaseAddress, ChunkLength, Attributes)); =20 - Status =3D UpdateSectionEntries (BaseAddress, ChunkLength, Attribute= s, - VirtualMask); + Status =3D UpdateSectionEntries (BaseAddress, ChunkLength, Attribute= s); =20 FlushTlbs =3D TRUE; } else { @@ -787,7 +774,7 @@ ArmSetMemoryAttributes ( BaseAddress, ChunkLength, Attributes)); =20 Status =3D UpdatePageEntries (BaseAddress, ChunkLength, Attributes, - VirtualMask, &FlushTlbs); + &FlushTlbs); } =20 if (EFI_ERROR (Status)) { --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Tue Apr 30 17:23:48 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1488876144747228.23944337662056; Tue, 7 Mar 2017 00:42:24 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0A0DA80354; Tue, 7 Mar 2017 00:42:18 -0800 (PST) Received: from mail-wr0-x22e.google.com (mail-wr0-x22e.google.com [IPv6:2a00:1450:400c:c0c::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E8EB580350 for ; Tue, 7 Mar 2017 00:42:15 -0800 (PST) Received: by mail-wr0-x22e.google.com with SMTP id l37so133865339wrc.1 for ; Tue, 07 Mar 2017 00:42:15 -0800 (PST) Received: from ards-macbook-pro.c.hoisthospitality.com ([109.74.56.122]) by smtp.gmail.com with ESMTPSA id u41sm30097838wrc.24.2017.03.07.00.42.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Mar 2017 00:42:13 -0800 (PST) X-Original-To: edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZJpVYrph+YZLStcGlcNs07zqB4hj07Q8mNmuYD796W8=; b=eRm+eQADcjAg/LrRaJEG/9k4ryGmTlJ9LHGXNNmqrgaTX/ZNK9XKP6H9H96ULz7UOX LC/pCVQ3L+L6zl+B6zcb7O2IEeCWHgOZpEcx+tFpJGQxfBMW6uqZYrXWScULn8fhaXAJ DrOvoE+qQeu0ifJTPkT/GV+sAkIcdUnM1nW0s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZJpVYrph+YZLStcGlcNs07zqB4hj07Q8mNmuYD796W8=; b=Y0J9GIfo87lqH0/iLWSW9dpaARpS+rMAZSQfah6x3/OhrS4G+cbFgDyN1tFJHaFLsI 3yl5XehZ51wUjckAHF7ACWGGol+xYAovBm5qHjdxBQN4GY9Dv8Yfmwl+TJOn2Fj9B8Xs LZrPEGSI59gC0x0UyP/lRUUiENBRG7ksk1d9L/Ul3y/AfwppyEcHHIDVVQd6I+rjwqmY tWxeUAo91445KlgOaHF8x21dXd/ibkKdltGE++OaM3VRDa2d0beEfQJdNW3eQBuu0u17 73+QYp+UT0MAk0O/QtSeLaD9pO1PexQuiL8u8BpyhUYfA9CFkNuuc9cozN28e4WfPEuV GEmQ== X-Gm-Message-State: AMke39my4upxfepbod2pN/IImrXTQmyBV2QTWBxbSA/B+kRql1UK/sQtmbcCDCCh8WSEjCyy X-Received: by 10.223.129.74 with SMTP id 68mr16764949wrm.183.1488876134573; Tue, 07 Mar 2017 00:42:14 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 7 Mar 2017 09:42:04 +0100 Message-Id: <1488876125-24396-4-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 3/4] ArmPkg/ArmMmuLib ARM: implement memory permission control routines X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lersek@redhat.com, Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that we have the prerequisite functionality available in ArmMmuLib, wire it up into ArmSetMemoryRegionNoExec, ArmClearMemoryRegionNoExec, ArmSetMemoryRegionReadOnly and ArmClearMemoryRegionReadOnly. This is used by the non-executable stack feature that is configured by DxeIpl. NOTE: The current implementation will not combine RO and XP attributes, i.e., setting/clearing a region no-exec will unconditionally clear the read-only attribute, and vice versa. Currently, we only use ArmSetMemoryRegionNoExec(), so for now, we should be able to live with this. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/= ArmMmuLib/Arm/ArmMmuLibCore.c index 351b6c03a42c..b02f6d7fc590 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -37,6 +37,8 @@ #define ID_MMFR0_SHR_IMP_HW_COHERENT 1 #define ID_MMFR0_SHR_IGNORED 0xf =20 +#define __EFI_MEMORY_RWX 0 // no restrictions + #define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \ EFI_MEMORY_WC | \ EFI_MEMORY_WT | \ @@ -797,7 +799,7 @@ ArmSetMemoryRegionNoExec ( IN UINT64 Length ) { - return EFI_UNSUPPORTED; + return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP); } =20 EFI_STATUS @@ -806,7 +808,7 @@ ArmClearMemoryRegionNoExec ( IN UINT64 Length ) { - return EFI_UNSUPPORTED; + return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX); } =20 EFI_STATUS @@ -815,7 +817,7 @@ ArmSetMemoryRegionReadOnly ( IN UINT64 Length ) { - return EFI_UNSUPPORTED; + return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO); } =20 EFI_STATUS @@ -824,7 +826,7 @@ ArmClearMemoryRegionReadOnly ( IN UINT64 Length ) { - return EFI_UNSUPPORTED; + return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX); } =20 RETURN_STATUS --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Tue Apr 30 17:23:48 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1488876146999460.719517443569; Tue, 7 Mar 2017 00:42:26 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4279680357; Tue, 7 Mar 2017 00:42:19 -0800 (PST) Received: from mail-wm0-x234.google.com (mail-wm0-x234.google.com [IPv6:2a00:1450:400c:c09::234]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 37D5780354 for ; Tue, 7 Mar 2017 00:42:17 -0800 (PST) Received: by mail-wm0-x234.google.com with SMTP id v186so83433295wmd.0 for ; Tue, 07 Mar 2017 00:42:17 -0800 (PST) Received: from ards-macbook-pro.c.hoisthospitality.com ([109.74.56.122]) by smtp.gmail.com with ESMTPSA id u41sm30097838wrc.24.2017.03.07.00.42.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Mar 2017 00:42:15 -0800 (PST) X-Original-To: edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3+RThqt92MW5pnVcCKlJsKIdiir8EPBqT09lJeTAoi4=; b=DNbAjZBNlkIYLvCk2Ww+CCgX2xkZEDeqiXWO3WGPmxMtLQC8K6PoRNns+snrlF76GI yAharAolKVGxxSdQW/EjjoszrcIVI3CW7WfdADBOfasDP9zBvzYmzu+oCrU+hPvpAdy8 nQFPb8EUWWT5kFCD2R7RHgThNXxl4mg7ynppQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3+RThqt92MW5pnVcCKlJsKIdiir8EPBqT09lJeTAoi4=; b=IB8mmxqQmcPNstqYJ6AY1VF4YjGS3ObrvMZH0GlnpXkBiYLj43Q1PVhnGAos3lf30u u2kZ98uXGybEZmTWRfaeWyPnYXJCEudnBKkyi7FmPLWeZerv77r9hqulZJPbdpKBPFQd lt0I+GccqCod6IWR4rGOJbmT4akAdgNPkCRmTrrBrAoYWrkgLoM6eDO/9kwvfkwFuCBJ v2fb5DzxHdLTyOmJXDl4MB35hDbRd6ocuMCoVxLeltSm5GpDMTrc+uhNgmxZ69d1A+KF si0plxPhcDh4OWnmfGnp3h0GelA0IBDSJ/Dvsdlwq2sNsKQJt0zwRjIYmMgSt3GqdPA5 /nYA== X-Gm-Message-State: AMke39nP+dWnQLjwNOLRiUzsbw4mYquoObTH9fk3y8G9ALTSZZbLX2CfCB6hLr2F1+zSLK7z X-Received: by 10.28.144.65 with SMTP id s62mr1101139wmd.141.1488876135851; Tue, 07 Mar 2017 00:42:15 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 7 Mar 2017 09:42:05 +0100 Message-Id: <1488876125-24396-5-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488876125-24396-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 4/4] ArmVirtPkg: enable non-executable DXE stack for all platforms X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lersek@redhat.com, Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that ARM has grown support for managing memory permissions in ArmMmuLib, we can enable the non-executable DXE stack for all virt platforms. Note that this includes the AARCH64 Xen platform as well. Note that this is not [entirely] redundant: the non-executable stack is configured before DxeCore is invoked. The image and memory protection features configured during DXE only take affect when the CPU arch protocol implementation is registered. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Laszlo Ersek --- ArmVirtPkg/ArmVirt.dsc.inc | 5 +++++ ArmVirtPkg/ArmVirtQemu.dsc | 2 -- ArmVirtPkg/ArmVirtQemuKernel.dsc | 2 -- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index acfb71d3ff6c..e2d3dcce7945 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -386,6 +386,11 @@ [PcdsFixedAtBuild.common] # gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC0000000= 00007FD1 =20 + # + # Enable the non-executable DXE stack. (This gets set up by DxeIpl) + # + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE + [PcdsFixedAtBuild.ARM] gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|40 =20 diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 615e1fca4877..477dfdcfc764 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -152,8 +152,6 @@ [PcdsFixedAtBuild.common] gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16 =20 [PcdsFixedAtBuild.AARCH64] - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE - # KVM limits it IPA space to 40 bits (1 TB), so there is no need to # support anything bigger, even if the host hardware does gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|40 diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKerne= l.dsc index e4902690123c..fd39c2802a85 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -163,8 +163,6 @@ [PcdsFixedAtBuild.AARCH64] # gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16 =20 - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE - # KVM limits it IPA space to 40 bits (1 TB), so there is no need to # support anything bigger, even if the host hardware does gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|40 --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel