From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Cc: Ard Biesheuvel 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: [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: , X-List-Received-Date: Sun, 20 Nov 2016 17:12:57 -0000 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(-) 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 -- 2.7.4