From patchwork Sun Nov 20 17:12:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 83157 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp1082586qge; Sun, 20 Nov 2016 09:12:59 -0800 (PST) X-Received: by 10.98.81.70 with SMTP id f67mr12524491pfb.179.1479661979011; Sun, 20 Nov 2016 09:12:59 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id y128si18193047pgy.46.2016.11.20.09.12.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Nov 2016 09:12:58 -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 dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 26B1081D6A; Sun, 20 Nov 2016 09:12:58 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) (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 EA69781D5C for ; Sun, 20 Nov 2016 09:12:56 -0800 (PST) Received: by mail-wm0-x230.google.com with SMTP id g23so111055514wme.1 for ; Sun, 20 Nov 2016 09:12:56 -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; bh=DLCvPlFPMj6oQA8wZSsm/5OvECPO21dipyIgV8u4c5E=; b=JQ2oyTa0SwMXg9Wt+CHqXIb+NqVzh0Wkgqql/aC6sA1iTTgQJUuRN/0oqRXdET8LvQ iAYytQaF8pOl2omMMxi8hhYZZ3uDLqE/KjCA0o+uxjhqs4EfcUYTFJZ38CV58BfploAl qnCkxGiU8JnruLpSGODkygTRUKVuCsZTTzgKI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=DLCvPlFPMj6oQA8wZSsm/5OvECPO21dipyIgV8u4c5E=; b=kjZkqkw41PLNI4mXqjaYQr6aZvvuawyKIj1miOGgLisAsbWEqWYBNqq6RAeFTPIbI2 Vl2CkSV+Y/cC+aK8hz3Utly9XYkd6vuvT5FR2VQ+W/Vrc2uSt6YGp3ddNEfGSLNnYTD8 Vq/gtP9B7rwZLMrOCjzcMspFaZPLw3MTvM/YSh/m/Ro82VvolOuDLgt84nO7qJ+8poei ad/V1z4J5WjxBF1n1cL1peYRGR/TGmUTQpxkToatz8g9prhmkDoh+AL7bfYJxqsb7TKC ijkc1eryXbr0qI+DFjkgtanDMdmUPFTLL2/mGHA4gpEsA8uksJIsGK1QgEpByN0+724S Bo0Q== X-Gm-Message-State: AKaTC02hJfoP/mQF5H7hnJ4/ZawpwOYUJfpAR7OUOfekSv68k+LYaTSk1anv5RhCdES2nDXa X-Received: by 10.28.198.67 with SMTP id w64mr9650382wmf.13.1479661975064; Sun, 20 Nov 2016 09:12:55 -0800 (PST) Received: from localhost.localdomain ([105.137.104.147]) by smtp.gmail.com with ESMTPSA id f67sm14803694wmd.13.2016.11.20.09.12.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 20 Nov 2016 09:12:54 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, heyi.guo@linaro.org Date: Sun, 20 Nov 2016 17:12:50 +0000 Message-Id: <1479661970-10517-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 Subject: [edk2] [PATCH] ArmPkg/ArmMmuLib: support page tables in cacheable memory only 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" Translation table walks are always cache coherent on ARMv8-A, so cache maintenance on page tables is never needed. Since there is a risk of loss of coherency when using mismatched attributes, and given that memory is mapped cacheable except for extraordinary cases (such as non-coherent DMA), restrict the page table walker to performing cacheable accesses to the translation tables. For DEBUG builds, retain some of the logic so that we can double check that the memory holding the root translation table is indeed located in memory that is mapped cacheable. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 49 ++++++++++---------- 1 file changed, 24 insertions(+), 25 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/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 1fb3bbec6347..c78297084207 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -627,6 +627,19 @@ ArmConfigureMmu ( return RETURN_UNSUPPORTED; } + // + // Translation table walks are always cache coherent on ARMv8-A, so cache + // maintenance on page tables is never needed. Since there is a risk of + // loss of coherency when using mismatched attributes, and given that memory + // is mapped cacheable except for extraordinary cases (such as non-coherent + // DMA), have the page table walker perform cached accesses as well, and + // assert below that that matches the attributes we use for CPU accesses to + // the region. + // + TCR |= TCR_SH_INNER_SHAREABLE | + TCR_RGN_OUTER_WRITE_BACK_ALLOC | + TCR_RGN_INNER_WRITE_BACK_ALLOC; + // Set TCR ArmSetTCR (TCR); @@ -672,11 +685,15 @@ ArmConfigureMmu ( TranslationTableAttribute = TT_ATTR_INDX_INVALID; while (MemoryTable->Length != 0) { - // Find the memory attribute for the Translation Table - if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && - ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) { - TranslationTableAttribute = MemoryTable->Attributes; - } + + DEBUG_CODE_BEGIN (); + // Find the memory attribute for the Translation Table + if ((UINTN)TranslationTable >= MemoryTable->PhysicalBase && + (UINTN)TranslationTable + RootTableEntrySize <= MemoryTable->PhysicalBase + + MemoryTable->Length) { + TranslationTableAttribute = MemoryTable->Attributes; + } + DEBUG_CODE_END (); Status = FillTranslationTable (TranslationTable, MemoryTable); if (RETURN_ERROR (Status)) { @@ -685,26 +702,8 @@ ArmConfigureMmu ( MemoryTable++; } - // Translate the Memory Attributes into Translation Table Register Attributes - if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) || - (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) { - TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_NON_CACHEABLE | TCR_RGN_INNER_NON_CACHEABLE; - } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) || - (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) { - TCR |= TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WRITE_BACK_ALLOC | TCR_RGN_INNER_WRITE_BACK_ALLOC; - } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) || - (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) { - TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_WRITE_THROUGH | TCR_RGN_INNER_WRITE_THROUGH; - } else { - // If we failed to find a mapping that contains the root translation table then it probably means the translation table - // is not mapped in the given memory map. - ASSERT (0); - Status = RETURN_UNSUPPORTED; - goto FREE_TRANSLATION_TABLE; - } - - // Set again TCR after getting the Translation Table attributes - ArmSetTCR (TCR); + ASSERT (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK || + TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK); ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC