OSDN Git Service

riscv: mm: Set sv57 on defaultly
authorQinglin Pan <panqinglin2020@iscas.ac.cn>
Thu, 27 Jan 2022 02:48:43 +0000 (10:48 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Tue, 15 Feb 2022 00:32:45 +0000 (16:32 -0800)
This patch sets sv57 on defaultly if CONFIG_64BIT. And do fallback to try
to set sv48 on boot time if sv57 is not supported in current hardware.

Signed-off-by: Qinglin Pan <panqinglin2020@iscas.ac.cn>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/Kconfig
arch/riscv/include/asm/csr.h
arch/riscv/include/asm/page.h
arch/riscv/kernel/cpu.c
arch/riscv/mm/init.c

index 5adcbd9..81682a1 100644 (file)
@@ -151,7 +151,7 @@ config PAGE_OFFSET
        hex
        default 0xC0000000 if 32BIT
        default 0x80000000 if 64BIT && !MMU
-       default 0xffffaf8000000000 if 64BIT
+       default 0xff60000000000000 if 64BIT
 
 config KASAN_SHADOW_OFFSET
        hex
@@ -202,7 +202,7 @@ config FIX_EARLYCON_MEM
 
 config PGTABLE_LEVELS
        int
-       default 4 if 64BIT
+       default 5 if 64BIT
        default 2
 
 config LOCKDEP_SUPPORT
index ae71169..299abde 100644 (file)
@@ -47,6 +47,7 @@
 #define SATP_PPN       _AC(0x00000FFFFFFFFFFF, UL)
 #define SATP_MODE_39   _AC(0x8000000000000000, UL)
 #define SATP_MODE_48   _AC(0x9000000000000000, UL)
+#define SATP_MODE_57   _AC(0xa000000000000000, UL)
 #define SATP_ASID_BITS 16
 #define SATP_ASID_SHIFT        44
 #define SATP_ASID_MASK _AC(0xFFFF, UL)
index 160e3a1..6187794 100644 (file)
@@ -41,6 +41,7 @@
  * By default, CONFIG_PAGE_OFFSET value corresponds to SV48 address space so
  * define the PAGE_OFFSET value for SV39.
  */
+#define PAGE_OFFSET_L4         _AC(0xffffaf8000000000, UL)
 #define PAGE_OFFSET_L3         _AC(0xffffffd800000000, UL)
 #else
 #define PAGE_OFFSET            _AC(CONFIG_PAGE_OFFSET, UL)
index ad0a7e9..3e7e35d 100644 (file)
@@ -79,7 +79,9 @@ static void print_mmu(struct seq_file *f)
 #if defined(CONFIG_32BIT)
        strncpy(sv_type, "sv32", 5);
 #elif defined(CONFIG_64BIT)
-       if (pgtable_l4_enabled)
+       if (pgtable_l5_enabled)
+               strncpy(sv_type, "sv57", 5);
+       else if (pgtable_l4_enabled)
                strncpy(sv_type, "sv48", 5);
        else
                strncpy(sv_type, "sv39", 5);
index 425377c..df8ddde 100644 (file)
@@ -38,14 +38,14 @@ EXPORT_SYMBOL(kernel_map);
 #endif
 
 #ifdef CONFIG_64BIT
-u64 satp_mode = !IS_ENABLED(CONFIG_XIP_KERNEL) ? SATP_MODE_48 : SATP_MODE_39;
+u64 satp_mode = !IS_ENABLED(CONFIG_XIP_KERNEL) ? SATP_MODE_57 : SATP_MODE_39;
 #else
 u64 satp_mode = SATP_MODE_32;
 #endif
 EXPORT_SYMBOL(satp_mode);
 
 bool pgtable_l4_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL);
-bool pgtable_l5_enabled = false;
+bool pgtable_l5_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL);
 EXPORT_SYMBOL(pgtable_l4_enabled);
 EXPORT_SYMBOL(pgtable_l5_enabled);
 
@@ -659,6 +659,13 @@ static __init pgprot_t pgprot_from_va(uintptr_t va)
 #endif /* CONFIG_STRICT_KERNEL_RWX */
 
 #ifdef CONFIG_64BIT
+static void __init disable_pgtable_l5(void)
+{
+       pgtable_l5_enabled = false;
+       kernel_map.page_offset = PAGE_OFFSET_L4;
+       satp_mode = SATP_MODE_48;
+}
+
 static void __init disable_pgtable_l4(void)
 {
        pgtable_l4_enabled = false;
@@ -675,12 +682,12 @@ static void __init disable_pgtable_l4(void)
 static __init void set_satp_mode(void)
 {
        u64 identity_satp, hw_satp;
-       uintptr_t set_satp_mode_pmd;
+       uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK;
+       bool check_l4 = false;
 
-       set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK;
-       create_pgd_mapping(early_pg_dir,
-                          set_satp_mode_pmd, (uintptr_t)early_pud,
-                          PGDIR_SIZE, PAGE_TABLE);
+       create_p4d_mapping(early_p4d,
+                       set_satp_mode_pmd, (uintptr_t)early_pud,
+                       P4D_SIZE, PAGE_TABLE);
        create_pud_mapping(early_pud,
                           set_satp_mode_pmd, (uintptr_t)early_pmd,
                           PUD_SIZE, PAGE_TABLE);
@@ -692,6 +699,11 @@ static __init void set_satp_mode(void)
                           set_satp_mode_pmd + PMD_SIZE,
                           set_satp_mode_pmd + PMD_SIZE,
                           PMD_SIZE, PAGE_KERNEL_EXEC);
+retry:
+       create_pgd_mapping(early_pg_dir,
+                          set_satp_mode_pmd,
+                          check_l4 ? (uintptr_t)early_pud : (uintptr_t)early_p4d,
+                          PGDIR_SIZE, PAGE_TABLE);
 
        identity_satp = PFN_DOWN((uintptr_t)&early_pg_dir) | satp_mode;
 
@@ -700,10 +712,17 @@ static __init void set_satp_mode(void)
        hw_satp = csr_swap(CSR_SATP, 0ULL);
        local_flush_tlb_all();
 
-       if (hw_satp != identity_satp)
+       if (hw_satp != identity_satp) {
+               if (!check_l4) {
+                       disable_pgtable_l5();
+                       check_l4 = true;
+                       goto retry;
+               }
                disable_pgtable_l4();
+       }
 
        memset(early_pg_dir, 0, PAGE_SIZE);
+       memset(early_p4d, 0, PAGE_SIZE);
        memset(early_pud, 0, PAGE_SIZE);
        memset(early_pmd, 0, PAGE_SIZE);
 }