From patchwork Thu Mar 2 10:36:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94769 Delivered-To: patch@linaro.org Received: by 10.140.82.71 with SMTP id g65csp97986qgd; Thu, 2 Mar 2017 02:36:29 -0800 (PST) X-Received: by 10.84.129.195 with SMTP id b61mr17422453plb.83.1488450989293; Thu, 02 Mar 2017 02:36:29 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id t6si7103808pgo.14.2017.03.02.02.36.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Mar 2017 02:36:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id DFA4F821EE; Thu, 2 Mar 2017 02:36:28 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wr0-x231.google.com (mail-wr0-x231.google.com [IPv6:2a00:1450:400c:c0c::231]) (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 5692B821EA for ; Thu, 2 Mar 2017 02:36:27 -0800 (PST) Received: by mail-wr0-x231.google.com with SMTP id l37so48840116wrc.1 for ; Thu, 02 Mar 2017 02:36:27 -0800 (PST) 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=j/8+AoKb4bAx3+ZecY4BTi1i2oPBQLHxgD/4Cg0KLco=; b=Lh+MvLjWPsXpbtJAEG//mXWVKDEjM1pa3CIfBjaVsaNnjvTOD83aehGxssd1ZXSPwr 2f0EBmBgRnBwH0FU1I0tC4ZIDCd78tCqUHRmYjTEMsL2KNvddtie3yqVto7dPHmti8hO Rmk9Dttl01otjugaFK3MxGQ3F2lSrMJxnb4/8= 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=j/8+AoKb4bAx3+ZecY4BTi1i2oPBQLHxgD/4Cg0KLco=; b=BFGq08neR7maJ3RshW3nhQ6xUwQTPvRyZRH+ocENzE/U+JOUkmvI4/TSiLEf7YrAD2 qWZqepXcKGdHWUb/dX3bPzs8G0aHMcVa1K/sg26a0WwF+Aqr+w/gUuDeGGKzA74C7dzl uEtZYoXqrTaszTwqoZpjo6p2ISE8TI804/8j61aymwSOeXr6U4W4BzIcHB182x48wQMQ 6teEiP20XKSOT9J+uIX191ZkxiahRKzpMqsfJceN4Uoc2rgzYaR0iBFw6PAgy8DRjXrX BZb+SO50l4Yu0MH8+Rc2JQHdEMieQPVD71VhqFCyd9MhMPLLQtWEE8VVY1oytaWdAmCj qIiQ== X-Gm-Message-State: AMke39ktngtEHcI0Uk06aTc88CxehFObrOLNgo8NpV4zAy9loHWPndXXLKsbmx2wChktX+y8 X-Received: by 10.223.145.227 with SMTP id 90mr12172763wri.156.1488450985828; Thu, 02 Mar 2017 02:36:25 -0800 (PST) Received: from localhost.localdomain ([105.147.1.203]) by smtp.gmail.com with ESMTPSA id l138sm4306971wmd.7.2017.03.02.02.36.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Mar 2017 02:36:25 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, lersek@redhat.com Date: Thu, 2 Mar 2017 10:36:13 +0000 Message-Id: <1488450976-16257-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 1/4] ArmPkg/CpuDxe ARM: avoid splitting page table sections unnecessarily 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: Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Currently, any range passed to CpuArchProtocol::SetMemoryAttributes is fully broken down into page mappings if the start or the size of the region happens to be misaliged relative to the section size of 1 MB. This is going to hurt when we enable strict memory permissions, given that we remap the entire RAM space non-executable (modulo the code bits) when the CpuArchProtocol is installed. So refactor the code to iterate over the range in a way that ensures that all naturally aligned section sized subregions are not broken up. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 47 ++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c index 89e429925ba9..ce4d529bda67 100644 --- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c @@ -679,6 +679,7 @@ SetMemoryAttributes ( ) { EFI_STATUS Status; + UINT64 ChunkLength; // // Ignore invocations that only modify permission bits @@ -687,14 +688,44 @@ SetMemoryAttributes ( return EFI_SUCCESS; } - if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) { - // Is the base and length a multiple of 1 MB? - DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); - Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask); - } else { - // Base and/or length is not a multiple of 1 MB - DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); - Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask); + while (Length > 0) { + if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) && + Length >= TT_DESCRIPTOR_SECTION_SIZE) { + + ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE; + + DEBUG ((DEBUG_PAGE, + "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", + BaseAddress, ChunkLength, Attributes)); + + Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes, + VirtualMask); + } 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 that. + // + ChunkLength = TT_DESCRIPTOR_SECTION_SIZE - + (BaseAddress % TT_DESCRIPTOR_SECTION_SIZE); + if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) { + ChunkLength = Length; + } + + DEBUG ((DEBUG_PAGE, + "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n", + BaseAddress, ChunkLength, Attributes)); + + Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes, + VirtualMask); + } + + if (EFI_ERROR (Status)) { + break; + } + + BaseAddress += ChunkLength; + Length -= ChunkLength; } // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks From patchwork Thu Mar 2 10:36:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94770 Delivered-To: patch@linaro.org Received: by 10.140.82.71 with SMTP id g65csp97999qgd; Thu, 2 Mar 2017 02:36:31 -0800 (PST) X-Received: by 10.99.173.6 with SMTP id g6mr14256137pgf.75.1488450991497; Thu, 02 Mar 2017 02:36:31 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id f10si7064299pge.327.2017.03.02.02.36.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Mar 2017 02:36:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1B023821F0; Thu, 2 Mar 2017 02:36:31 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wr0-x22d.google.com (mail-wr0-x22d.google.com [IPv6:2a00:1450:400c:c0c::22d]) (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 6FF62821F0 for ; Thu, 2 Mar 2017 02:36:29 -0800 (PST) Received: by mail-wr0-x22d.google.com with SMTP id u108so48836024wrb.3 for ; Thu, 02 Mar 2017 02:36:29 -0800 (PST) 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=bAt+sSWWKR/8da7JOOGSwMRyRFvzANtyenwx9PD79EI=; b=FoUBEGHAwDKgl+uKFNWk3Ej7BI/fc6rvJd/I7E7cvKeSpEQe+PGo5Smp4GFAtsTvyW ksLqJslADAOxrCLjaI+EMhLZEYS+XzQaYYqCdEUjG51fhrK6aSBZ0liF8pdb5crbjOJG E4DSSvgYYRZ8HTSsqTMG8uTkjeDLyHNLCSTnA= 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=bAt+sSWWKR/8da7JOOGSwMRyRFvzANtyenwx9PD79EI=; b=DWsk2bxXeTTxleLCnMzmbr9/PzsXYzhcXHm13Hj30Oo+R+F0yJAB1HXK+ZF979Sc/g g1gaskyK/4MCwraX47GivpQmIbIKWjHiCAEszZP2NQYHLwxMGCw+abGvrJpEzqKqPqdN DrB/NkYWCu90Uzpa4oCe7LspBA0yF8kPD6YSoZza84v1hcFtue4zO7/w04VfeEyOgZo8 WipklimytDHXC+xT7S5CJ6pYsiLuyDoXc8Xsiy8qAfY7c8qFMkIRoF/09H0BC6/QzfN/ Tsi+3SppGkOmysMNuvwGI3xhAURlSfa5b8RNH80VLY46uVb6lQgU6W42KMY6DuKI/Wnu 2OCA== X-Gm-Message-State: AMke39lxTbD7b7AAvtlduzh/Q5qCW544VFbqI/b5kZMQeyt9nBPmqw4Apks6r2+sZHQMb/RS X-Received: by 10.223.167.71 with SMTP id e7mr11903006wrd.154.1488450987980; Thu, 02 Mar 2017 02:36:27 -0800 (PST) Received: from localhost.localdomain ([105.147.1.203]) by smtp.gmail.com with ESMTPSA id l138sm4306971wmd.7.2017.03.02.02.36.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Mar 2017 02:36:27 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, lersek@redhat.com Date: Thu, 2 Mar 2017 10:36:14 +0000 Message-Id: <1488450976-16257-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 2/4] ArmPkg/CpuDxe ARM: avoid unnecessary cache/TLB maintenance 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: Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Page and section entries in the page tables are updated using the helper ArmUpdateTranslationTableEntry(), which cleans the page table entry to the PoC, and invalidates the TLB entry covering the page described by the entry being updated. Since we may be updating section entries, we might be leaving stale TLB entries at this point (for all pages in the section except the first one), which will be invalidated wholesale at the end of SetMemoryAttributes(). At that point, all caches are cleaned *and* invalidated as well. This cache maintenance is costly and unnecessary. The TLB maintenance is only necessary if we updated any section entries, since any page by page entries that have been updated will have been invalidated individually by ArmUpdateTranslationTableEntry(). So drop the clean/invalidate of the caches, and only perform the full TLB flush if UpdateSectionEntries() was called, or if sections were split by UpdatePageEntries(). Finally, make the cache maintenance on the remapped regions themselves conditional on whether any memory type attributes were modified. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 60 +++++++++++--------- 1 file changed, 34 insertions(+), 26 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c index ce4d529bda67..26b637e7658f 100644 --- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c @@ -347,10 +347,11 @@ SyncCacheConfig ( EFI_STATUS UpdatePageEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN EFI_PHYSICAL_ADDRESS VirtualMask + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN EFI_PHYSICAL_ADDRESS VirtualMask, + OUT BOOLEAN *FlushTlbs ) { EFI_STATUS Status; @@ -446,6 +447,9 @@ UpdatePageEntries ( // Re-read descriptor Descriptor = FirstLevelTable[FirstLevelIdx]; + if (FlushTlbs != NULL) { + *FlushTlbs = TRUE; + } } // Obtain page table base address @@ -471,15 +475,16 @@ UpdatePageEntries ( if (CurrentPageTableEntry != PageTableEntry) { Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); - if ((CurrentPageTableEntry & TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) == TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) { - // The current section mapping is cacheable so Clean/Invalidate the MVA of the page - // Note assumes switch(Attributes), not ARMv7 possibilities - WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE); - } // Only need to update if we are changing the entry PageTable[PageTableIndex] = 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_CACHE_POLICY_MASK) != 0) { + WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE); + } } Status = EFI_SUCCESS; @@ -581,7 +586,12 @@ UpdateSectionEntries ( // has this descriptor already been coverted to pages? if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) { // forward this 1MB range to page table function instead - Status = UpdatePageEntries ((FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, VirtualMask); + Status = UpdatePageEntries ( + (FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, + TT_DESCRIPTOR_SECTION_SIZE, + Attributes, + VirtualMask, + NULL); } else { // still a section entry @@ -596,15 +606,16 @@ UpdateSectionEntries ( if (CurrentDescriptor != Descriptor) { Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT); - if ((CurrentDescriptor & TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) == TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) { - // The current section mapping is cacheable so Clean/Invalidate the MVA of the section - // Note assumes switch(Attributes), not ARMv7 possabilities - WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB); - } // Only need to update if we are changing the descriptor FirstLevelTable[FirstLevelIdx + i] = Descriptor; ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva); + + // Clean/invalidate the cache for this section, but only + // if we are modifying the memory type attributes + if (((CurrentDescriptor ^ Descriptor) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) != 0) { + WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB); + } } Status = EFI_SUCCESS; @@ -680,6 +691,7 @@ SetMemoryAttributes ( { EFI_STATUS Status; UINT64 ChunkLength; + BOOLEAN FlushTlbs; // // Ignore invocations that only modify permission bits @@ -688,6 +700,7 @@ SetMemoryAttributes ( return EFI_SUCCESS; } + FlushTlbs = FALSE; while (Length > 0) { if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) && Length >= TT_DESCRIPTOR_SECTION_SIZE) { @@ -700,6 +713,8 @@ SetMemoryAttributes ( Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes, VirtualMask); + + FlushTlbs = TRUE; } else { // @@ -717,7 +732,7 @@ SetMemoryAttributes ( BaseAddress, ChunkLength, Attributes)); Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes, - VirtualMask); + VirtualMask, &FlushTlbs); } if (EFI_ERROR (Status)) { @@ -728,16 +743,9 @@ SetMemoryAttributes ( Length -= ChunkLength; } - // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks - // flush and invalidate pages - //TODO: Do we really need to invalidate the caches everytime we change the memory attributes ? - ArmCleanInvalidateDataCache (); - - ArmInvalidateInstructionCache (); - - // Invalidate all TLB entries so changes are synced - ArmInvalidateTlb (); - + if (FlushTlbs) { + ArmInvalidateTlb (); + } return Status; } From patchwork Thu Mar 2 10:36:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94771 Delivered-To: patch@linaro.org Received: by 10.140.82.71 with SMTP id g65csp98017qgd; Thu, 2 Mar 2017 02:36:33 -0800 (PST) X-Received: by 10.98.135.68 with SMTP id i65mr14901244pfe.28.1488450993486; Thu, 02 Mar 2017 02:36:33 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id u1si7085942plj.264.2017.03.02.02.36.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Mar 2017 02:36:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 548CA821F4; Thu, 2 Mar 2017 02:36:32 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wr0-x231.google.com (mail-wr0-x231.google.com [IPv6:2a00:1450:400c:c0c::231]) (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 8DBDE821F3 for ; Thu, 2 Mar 2017 02:36:31 -0800 (PST) Received: by mail-wr0-x231.google.com with SMTP id u48so48885898wrc.0 for ; Thu, 02 Mar 2017 02:36:31 -0800 (PST) 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=TZ0ZjzvDZEOT1Wt+rVlJNmzdFphtXp7K+OHPh34YCnM=; b=FkuUEJiJvgUU2oQkIZ5zD2JCwQoMOm5YyFmiuKrwn6qkiZGKaqwlVWCSmnKo5786k0 lIRkobSRGn6eBwC6IUMpTYYfE7NELQbV6Lhuz16xNT/4OwVyxVzBvCiVwD4uwH2SMI4o AKkDa8JTtYYAr7pgK4tU1MeQDBH/3fMY4EeAo= 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=TZ0ZjzvDZEOT1Wt+rVlJNmzdFphtXp7K+OHPh34YCnM=; b=gW9TiIN388ZfQuEVrPttJz1vc6z1A0vOQioVAJUHHAb6mZGrEwsK1RQnXhBrp/a3nq aHL/JqrV0WlhezQdQCluRBA+t71lFLCX25wuSDzUykrlxE9FzK6l+xXySE7268qoJtgt Ac0u+ZwyxqpLOyYvwU/7UKFkaPkVILl4BRCPJV+v9OX+5maUCQW0QyWLpqUcK24+3wjW VgckdR2oc3uP5euzH8eNmWlofP62+MLZdvRtAjmoQ3Csz/7a/TRDCDukOiJDgJrXN6/k BUSV+nuoxCWUtfhR0D8OI1g+KJ23kkL1fZlbRCdUbXWo+lEPTUzsxxLUxCEtE2oZhpfF rUNw== X-Gm-Message-State: AMke39mZtDBPwcpyvvA7W2nuU2xDeRiezqVPr23e1Lw3oTMjMyF4O7egIAr58GjOKt49pVXF X-Received: by 10.223.164.140 with SMTP id g12mr10780591wrb.87.1488450990006; Thu, 02 Mar 2017 02:36:30 -0800 (PST) Received: from localhost.localdomain ([105.147.1.203]) by smtp.gmail.com with ESMTPSA id l138sm4306971wmd.7.2017.03.02.02.36.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Mar 2017 02:36:29 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, lersek@redhat.com Date: Thu, 2 Mar 2017 10:36:15 +0000 Message-Id: <1488450976-16257-4-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 3/4] ArmPkg/CpuDxe ARM: honour RO/XP attributes in SetMemoryAttributes() 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: Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Enable the use of strict memory permissions on ARM by processing the EFI_MEMORY_RO and EFI_MEMORY_XP rather than ignoring them. As before, calls to CpuArchProtocol::SetMemoryAttributes that only set RO/XP bits will preserve the cacheability attributes. Permissions attributes are not preserved when setting the memory type only: the way the memory permission attributes are defined does not allows for that, and so this situation does not deviate from other architectures. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 151 ++++++++------------ 1 file changed, 62 insertions(+), 89 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c index 26b637e7658f..6dd749dadf8b 100644 --- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c @@ -374,50 +374,41 @@ UpdatePageEntries ( // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone) // EntryValue: values at bit positions specified by EntryMask - EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK; - EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE; + EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK; + if ((Attributes & EFI_MEMORY_XP) != 0) { + EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN; + } else { + EntryValue = 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 we can safely use a switch statement - switch (Attributes) { - case EFI_MEMORY_UC: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 - break; - - case EFI_MEMORY_WC: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to normal non-cachable - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 - break; - - case EFI_MEMORY_WT: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 - break; - - case EFI_MEMORY_WB: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 - break; - - case EFI_MEMORY_WP: - case EFI_MEMORY_XP: - case EFI_MEMORY_UCE: - // cannot be implemented UEFI definition unclear for ARM - // Cause a page fault if these ranges are accessed. - EntryValue = TT_DESCRIPTOR_PAGE_TYPE_FAULT; - DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); - break; + if ((Attributes & EFI_MEMORY_UC) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // map to strongly ordered + EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 + } else if ((Attributes & EFI_MEMORY_WC) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // map to normal non-cachable + EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 + } else if ((Attributes & EFI_MEMORY_WT) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // write through with no-allocate + EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 + } else if ((Attributes & EFI_MEMORY_WB) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; + // write back (with allocate) + EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 + } - default: - return EFI_UNSUPPORTED; + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW; } // Obtain page table base @@ -520,53 +511,42 @@ UpdateSectionEntries ( // EntryValue: values at bit positions specified by EntryMask // Make sure we handle a section range that is unmapped - EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK; + EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK | + TT_DESCRIPTOR_SECTION_AP_MASK; EntryValue = 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 we can safely use a switch statement - switch(Attributes) { - case EFI_MEMORY_UC: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 - break; - - case EFI_MEMORY_WC: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to normal non-cachable - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 - break; - - case EFI_MEMORY_WT: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 - break; - - case EFI_MEMORY_WB: - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 - break; - - case EFI_MEMORY_WP: - case EFI_MEMORY_XP: - case EFI_MEMORY_RP: - case EFI_MEMORY_UCE: - // cannot be implemented UEFI definition unclear for ARM - // Cause a page fault if these ranges are accessed. - EntryValue = TT_DESCRIPTOR_SECTION_TYPE_FAULT; - DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); - break; + if ((Attributes & EFI_MEMORY_UC) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // map to strongly ordered + EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 + } else if ((Attributes & EFI_MEMORY_WC) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // map to normal non-cachable + EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 + } else if ((Attributes & EFI_MEMORY_WT) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // write through with no-allocate + EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 + } else if ((Attributes & EFI_MEMORY_WB) != 0) { + // modify cacheability attributes + EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; + // write back (with allocate) + EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 + } + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW; + } - default: - return EFI_UNSUPPORTED; + if ((Attributes & EFI_MEMORY_XP) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK; } // obtain page table base @@ -693,13 +673,6 @@ SetMemoryAttributes ( UINT64 ChunkLength; BOOLEAN FlushTlbs; - // - // Ignore invocations that only modify permission bits - // - if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) { - return EFI_SUCCESS; - } - FlushTlbs = FALSE; while (Length > 0) { if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) && From patchwork Thu Mar 2 10:36:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94772 Delivered-To: patch@linaro.org Received: by 10.140.82.71 with SMTP id g65csp98038qgd; Thu, 2 Mar 2017 02:36:36 -0800 (PST) X-Received: by 10.98.147.10 with SMTP id b10mr14583059pfe.177.1488450996456; Thu, 02 Mar 2017 02:36:36 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id k65si5864590pfj.246.2017.03.02.02.36.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Mar 2017 02:36:36 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 91F30821F3; Thu, 2 Mar 2017 02:36:34 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org 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 2DF0E821EA for ; Thu, 2 Mar 2017 02:36:33 -0800 (PST) Received: by mail-wr0-x22b.google.com with SMTP id u48so48886360wrc.0 for ; Thu, 02 Mar 2017 02:36:33 -0800 (PST) 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=lDUYVgE3a8FHzQLzU7xRWE2USka51gLWZbeM4GzwwK8=; b=Hd+/nOY5/jncmlAHsZhNq3R2znzQ+6DHmlpavlgy5LL+mZG2SEe2a9nQDhYGOqL0g0 OSNJlVvG5G9RoDJzdEsJp7fv1+HGqIlXjJk5855JocLdS5C797JuzELsTOgbyovZshCK NjM8k0Rl2A+khSliNPvDa6gSsVhxD7HthaVwU= 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=lDUYVgE3a8FHzQLzU7xRWE2USka51gLWZbeM4GzwwK8=; b=hVniGUIz0xnYeI9mXzTpQuvXHgtzihZX4v/fmMghNUdBTeMfpDWFKee3nC7+jOvVM/ eo+1wBaPjSl3K30B9mKzMn+hjMYNDzPBNzvyIYOnkvSWLeuNSmRpAmODMLhF8rPofE9+ tKgNwkzsk7xitiLLGtfNMy0rES0tMonE3A1jPOD8uI5K4vYG1cO3Hto79v85h2muZNE6 1QmnsVmAzhCenw+5pZ5HvMFW4476pdskbsyFDfOu0tmq0WFxHZDOzbqCdCnR0HUkia6K 0Ns3ydXzmCbI4VEfupgjSQA827fwLX5Yks+HO0HudMxjfm6OYGe9CO8eOhHCqaobix9k oJTg== X-Gm-Message-State: AMke39mw4UbFfgxmcIn+RUbpu89RANiPLHK9pHIMkjrYW+noW4gMF5uo5a2PmM/QQnPmMHaI X-Received: by 10.223.155.211 with SMTP id e19mr11073461wrc.74.1488450991772; Thu, 02 Mar 2017 02:36:31 -0800 (PST) Received: from localhost.localdomain ([105.147.1.203]) by smtp.gmail.com with ESMTPSA id l138sm4306971wmd.7.2017.03.02.02.36.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Mar 2017 02:36:31 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, lersek@redhat.com Date: Thu, 2 Mar 2017 10:36:16 +0000 Message-Id: <1488450976-16257-5-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488450976-16257-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 4/4] ArmVirtPkg: enable PE/COFF image and memory protection for ARM 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: Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Like for AARCH64, enable PE/COFF image and NX memory protection for all 32-bit ARM virt platforms. Note that this does not [yet] protect EfiLoaderData regions, due to compatibility issues with GRUB. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Laszlo Ersek --- ArmVirtPkg/ArmVirt.dsc.inc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index a91b27f13cf2..acfb71d3ff6c 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -18,7 +18,7 @@ [Defines] DEFINE TTY_TERMINAL = FALSE [BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION] - GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000 + GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000 @@ -373,10 +373,6 @@ [PcdsFixedAtBuild.common] gArmVirtTokenSpaceGuid.PcdTerminalTypeGuidBuffer|{0x80, 0x6d, 0x91, 0x7d, 0xb1, 0x5b, 0x8c, 0x45, 0xa4, 0x8f, 0xe2, 0x5f, 0xdd, 0x51, 0xef, 0x94} !endif -[PcdsFixedAtBuild.ARM] - gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|40 - -[PcdsFixedAtBuild.AARCH64] # # Enable strict image permissions for all images. (This applies # only to images that were built with >= 4 KB section alignment.) @@ -390,6 +386,9 @@ [PcdsFixedAtBuild.AARCH64] # gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1 +[PcdsFixedAtBuild.ARM] + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|40 + [Components.common] # # Networking stack