Skip to contentSkip to conversation

arm64: mm: Implement 4 levels of translation tables

PATCH New Jungseok Lee 4 participants 6 messages Jul 29, 2014 – Aug 14, 2014 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): CAGoO6fLT6B_vx+Wtm6bKHD6YkjQcM8f=deD7SDP3BR_uC+1c5w@mail.gmail.com

#1 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

On Jul 28 08:40:07 PDT 2014, Joel Schopp wrote:

Hi Joel,

Quoted 1 line · Catalin Marinas

[ ... ]

Quoted 8 lines
Quoted 8 lines
arch/arm64/Kconfig +0 -0
index 4daf11f5b403..24cbe72c0da9 100644
@@ -196,12 +196,18 @@ config ARM64_VA_BITS_42
 bool "42-bit"
 depends on ARM64_64K_PAGES
 
Quoted 8 lines
Quoted 6 lines
arch/arm64/Kconfig +5 -0
+config ARM64_VA_BITS_48
+ bool "48-bit"
+ depends on !KVM
+ depends on ARM64_4K_PAGES
+

endchoice

Shouldn't we be able to support 48 bit VA with 3 level 64K pages? If so why the dependency on ARM64_4K_PAGES?

Have you reviewed [PATCH 13/11] thread? It supports 3 levels with 64KB page. In addition, ARM64_VA_BITS_48 depends on only BROKEN.

Quoted 4 lines

More generally it seems like a problem to tie the equate the VA_BITS the page table could address with the VA_BITS the hardware could address. Even with 4 level 4K page tables that can address 48 bits the hardware may only support say 42 bit address space.

I leave comments below.

Quoted 13 lines
Quoted 13 lines

config ARM64_VA_BITS
int
default 39 if ARM64_VA_BITS_39
default 42 if ARM64_VA_BITS_42
+ default 48 if ARM64_VA_BITS_48

config ARM64_2_LEVELS
def_bool y if ARM64_64K_PAGES && ARM64_VA_BITS_42

arch/arm64/Kconfig +0 -0
@@ -209,6 +215,9 @@ config ARM64_2_LEVELS

config ARM64_3_LEVELS
def_bool y if ARM64_4K_PAGES && ARM64_VA_BITS_39

Quoted 6 lines

arch/arm64/Kconfig

Quoted 3 lines
arch/arm64/Kconfig +3 -0
+config ARM64_4_LEVELS
+ def_bool y if ARM64_4K_PAGES && ARM64_VA_BITS_48
+

It seems like we should also do ARM64_4K_PAGES and ARM64_VA_BITS_42 as a valid combination for ARM64_4_LEVELS. At least if we are assuming the VA_BITS correspond to hardware.

I don't understand why VA_BITS should correspond to hardware. For example, should ARM64_VA_BITS_36 be supported for 36-bit address spaces SoCs?

Quoted 97 lines
Quoted 97 lines

config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
help

arch/arm64/include/asm/page.h +10 -3
index 6bf139188792..cf9afa0366b6 100644
@@ -33,19 +33,26 @@
 
 /*
 * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require a pgd and a next level table to (section) map the
- * kernel. The the swapper also maaps the FDT (see __create_page_tables for
+ * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
+ * map the kernel. The swapper also maps the FDT (see __create_page_tables for
 * more information).
 */
+#ifdef CONFIG_ARM64_4_LEVELS
+#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
+#define IDMAP_DIR_SIZE (3 * PAGE_SIZE)
+#else
 #define SWAPPER_DIR_SIZE (2 * PAGE_SIZE)
 #define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
+#endif
 
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_ARM64_2_LEVELS
 #include <asm/pgtable-2level-types.h>
-#else
+#elif defined(CONFIG_ARM64_3_LEVELS)
 #include <asm/pgtable-3level-types.h>
+#else
+#include <asm/pgtable-4level-types.h>
 #endif
 
 extern void __cpu_clear_user_page(void *p, unsigned long user);
arch/arm64/include/asm/pgalloc.h +20 -0
index 48298376e46a..8d745fae4c2d 100644
@@ -26,6 +26,26 @@
 
 #define check_pgt_cache() do { } while (0)
 
+#ifdef CONFIG_ARM64_4_LEVELS
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return (pud_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
+}
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+ BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+ free_page((unsigned long)pud);
+}
+
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+{
+ set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE));
+}
+
+#endif  /* CONFIG_ARM64_4_LEVELS */
+
 #ifndef CONFIG_ARM64_2_LEVELS
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
arch/arm64/include/asm/pgtable-hwdef.h +4 -2
index c7c603b489b8..fddcc3efa569 100644
@@ -18,8 +18,10 @@
 
 #ifdef CONFIG_ARM64_2_LEVELS
 #include <asm/pgtable-2level-hwdef.h>
-#else
+#elif defined(CONFIG_ARM64_3_LEVELS)
 #include <asm/pgtable-3level-hwdef.h>
+#else
+#include <asm/pgtable-4level-hwdef.h>
 #endif
 
 /*
@@ -27,7 +29,7 @@
 *
 * Level 1 descriptor (PUD).
 */
-
+#define PUD_TYPE_TABLE (_AT(pudval_t, 3) << 0)
 #define PUD_TABLE_BIT (_AT(pgdval_t, 1) << 1)
 #define PUD_TYPE_MASK (_AT(pgdval_t, 3) << 0)
 #define PUD_TYPE_SECT (_AT(pgdval_t, 1) << 0)
arch/arm64/include/asm/pgtable.h +0 -0
index 6d5854972a77..d9b23efdaded 100644
Quoted 8 lines

arch/arm64/include/asm/pgtable.h line 37

Quoted 4 lines
arch/arm64/include/asm/pgtable.h +0 -0
@@ -35,7 +35,11 @@
 * VMALLOC and SPARSEMEM_VMEMMAP ranges.
 */
 #define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS)

Here's a good example of where we run into trouble equating page table addressable bits with hardware addressable bits. If VA_BITS is 48 due to 4K 4 level page tables but is running on a 42 bit system this will end up being out of range.

Is your concern that CPU issues 48-bit address to MMU on 42-bit hardware? Have you tested this patch series on your hardware?

- Jungseok Lee

#2 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

Quoted 9 lines
Quoted 5 lines

Here's a good example of where we run into trouble equating page table addressable bits with hardware addressable bits. If VA_BITS is 48 due to 4K 4 level page tables but is running on a 42 bit system this will end up being out of range.

Is your concern that CPU issues 48-bit address to MMU on 42-bit hardware? Have you tested this patch series on your hardware?

- Jungseok Lee

That is my concern. I did test the patch on my hardware with the following results:
64k pages, 2 levels 42 bit VA - worked (no regression) 64k pages, 3 levels 48 bit VA- didn't boot
4k pages, 4 levels 42 bit VA - didn't boot
4k pages, 4 levels 48 bit VA - didn't boot

#3 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

Quoted 8 lines · Joel Schopp
Quoted 8 lines
Quoted 5 lines

Here's a good example of where we run into trouble equating page table addressable bits with hardware addressable bits. If VA_BITS is 48 due to 4K 4 level page tables but is running on a 42 bit system this will end up being out of range.

Is your concern that CPU issues 48-bit address to MMU on 42-bit hardware? Have you tested this patch series on your hardware?

Quoted 8 lines
Quoted 1 line

- Jungseok Lee

That is my concern. I did test the patch on my hardware with the following results:
64k pages, 2 levels 42 bit VA - worked (no regression) 64k pages, 3 levels 48 bit VA- didn't boot
4k pages, 4 levels 42 bit VA - didn't boot
4k pages, 4 levels 48 bit VA - didn't boot

Let me break the concern down into two small parts.

The first one is a relation between VA and PA. Let me visualize the above description in the following way. I assume that Cortex-A57 is used and connected to bus with 42-bit address line.

SoC Boundary

|---------------------------------------------
| Cortex-A57 Boundary                        |
| ---------------                            |
| | CPU --> MMU | --> BUS --> Memory Controller --> RAM 
| ------48------- 42      42                 |  42
|---------------------------------------------

In this configuration, there is no problem since 48-bit VA is handled in Cortex-A57 boundary. Cortex-A57 can support up to 48-bit VA and 44-bit PA.

The second part is the test result. It's bad actually. So, I've done booting test on for-next/core branch of arm64 linux git, [1], quickly using Model. All combinations, 4KB + 3Level (39-bit VA), 4KB + 4Level (48-bit VA), 64KB + 2Level (42-bit VA) and 64KB + 3Level(48bit VA), boot up successfully.

I hesitate to say anything since I don't have any real hardware. I think people who have real platform, such as Juno, can help to figure it out.

[1]: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git

I add Will in Cc since [1] looks updated by Will now.

- Jungseok Lee

#4 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

Hi Catalin,

IMHO, the Macro MAX_PHYSMEM_BITS needs to be set to 48 in file arch/arm64/include/asm/sparsemem.h

with 40 bit set, for RAM address beyond 40 bit, seeeing below warning message.

WARNING: CPU: 0 PID: 0 at mm/sparse.c:164
mminit_validate_memmodel_limits+0xf8/0x118()

thanks
Ganapat

Quoted 53 lines · Jungseok Lee
Quoted 8 lines · Joel Schopp
Quoted 8 lines
Quoted 5 lines

Here's a good example of where we run into trouble equating page table addressable bits with hardware addressable bits. If VA_BITS is 48 due to 4K 4 level page tables but is running on a 42 bit system this will end up being out of range.

Is your concern that CPU issues 48-bit address to MMU on 42-bit hardware? Have you tested this patch series on your hardware?

Quoted 8 lines
Quoted 1 line

- Jungseok Lee

That is my concern. I did test the patch on my hardware with the following results:
64k pages, 2 levels 42 bit VA - worked (no regression) 64k pages, 3 levels 48 bit VA- didn't boot
4k pages, 4 levels 42 bit VA - didn't boot
4k pages, 4 levels 48 bit VA - didn't boot

Let me break the concern down into two small parts.

The first one is a relation between VA and PA. Let me visualize the above description in the following way. I assume that Cortex-A57 is used and connected to bus with 42-bit address line.

SoC Boundary

|---------------------------------------------
| Cortex-A57 Boundary                        |
| ---------------                            |
| | CPU --> MMU | --> BUS --> Memory Controller --> RAM
| ------48------- 42      42                 |  42
|---------------------------------------------

In this configuration, there is no problem since 48-bit VA is handled in Cortex-A57 boundary. Cortex-A57 can support up to 48-bit VA and 44-bit PA.

The second part is the test result. It's bad actually. So, I've done booting test on for-next/core branch of arm64 linux git, [1], quickly using Model. All combinations, 4KB + 3Level (39-bit VA), 4KB + 4Level (48-bit VA), 64KB + 2Level (42-bit VA) and 64KB + 3Level(48bit VA), boot up successfully.

I hesitate to say anything since I don't have any real hardware. I think people who have real platform, such as Juno, can help to figure it out.

[1]: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git

I add Will in Cc since [1] looks updated by Will now.

- Jungseok Lee
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#5 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

Quoted 6 lines · Ganapatrao Kulkarni

IMHO, the Macro MAX_PHYSMEM_BITS needs to be set to 48 in file arch/arm64/include/asm/sparsemem.h

with 40 bit set, for RAM address beyond 40 bit, seeeing below warning message.

WARNING: CPU: 0 PID: 0 at mm/sparse.c:164
mminit_validate_memmodel_limits+0xf8/0x118()

I agree. Would you mind sending a patch?

Thanks.

Signature · 1 line
Catalin
#6 lore raw

PATCH v7 7/11 arm64: mm: Implement 4 levels of translation tables

Quoted 9 lines · Catalin Marinas
Quoted 6 lines · Ganapatrao Kulkarni

IMHO, the Macro MAX_PHYSMEM_BITS needs to be set to 48 in file arch/arm64/include/asm/sparsemem.h

with 40 bit set, for RAM address beyond 40 bit, seeeing below warning message.

WARNING: CPU: 0 PID: 0 at mm/sparse.c:164
mminit_validate_memmodel_limits+0xf8/0x118()

I agree. Would you mind sending a patch?

Sure I will send you the patch.

Quoted 5 lines

Thanks.

--
Catalin

thanks
Ganapat