diff mbox

[U-Boot] armv8: Fix MMU table page descriptor

Message ID 1486058314-26922-1-git-send-email-york.sun@nxp.com
State Changes Requested
Delegated to: Tom Rini
Headers show

Commit Message

York Sun Feb. 2, 2017, 5:58 p.m. UTC
Page descriptor uses different format than block descriptor. Both bit 1
and 0 must be set to indicate a valid page.

Signed-off-by: York Sun <york.sun@nxp.com>
CC: Alexander Graf <agraf@suse.de>
---
This issue didn't reveal itself unless we use MMU tables down to page
size.

 arch/arm/cpu/armv8/cache_v8.c    | 2 +-
 arch/arm/include/asm/armv8/mmu.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

Comments

Stephen Warren Feb. 10, 2017, 4:55 p.m. UTC | #1
On 02/02/2017 10:58 AM, York Sun wrote:
> Page descriptor uses different format than block descriptor. Both bit 1
> and 0 must be set to indicate a valid page.

> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c

> @@ -230,7 +230,7 @@ static void add_map(struct mm_region *map)
>  				/* Page fits, create block PTE */
>  				debug("Setting PTE %p to block virt=%llx\n",
>  				      pte, virt);
> -				*pte = phys | attrs;
> +				*pte = phys | attrs | (level == 3 ? PTE_TYPE_PAGE : 0);

The value of attrs already includes PTE_TYPE_BLOCK. Luckily, the bits 
set in the value of PTE_TYPE_BLOCK is a strict subset of the bits set in 
the value of PTE_TYPE_PAGE, so this works fine. Still, it might be 
clearer to explicitly remove PTE_TYPE_BLOCK before adding in 
PTE_TYPE_PAGE, or simply add a comment explaining why the code is OK as 
written.

With one of those fixes,
Reviewed-by: Stephen Warren <swarren@nvidia.com>
diff mbox

Patch

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 6c5630c..afa76c1 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -230,7 +230,7 @@  static void add_map(struct mm_region *map)
 				/* Page fits, create block PTE */
 				debug("Setting PTE %p to block virt=%llx\n",
 				      pte, virt);
-				*pte = phys | attrs;
+				*pte = phys | attrs | (level == 3 ? PTE_TYPE_PAGE : 0);
 				virt += blocksize;
 				phys += blocksize;
 				size -= blocksize;
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index aa0f3c4..58aecb9 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -60,6 +60,7 @@ 
 #define PTE_TYPE_MASK		(3 << 0)
 #define PTE_TYPE_FAULT		(0 << 0)
 #define PTE_TYPE_TABLE		(3 << 0)
+#define PTE_TYPE_PAGE		(3 << 0)
 #define PTE_TYPE_BLOCK		(1 << 0)
 
 #define PTE_TABLE_PXN		(1UL << 59)