aboutsummaryrefslogtreecommitdiffstats
path: root/arch/riscv/mm/init.c
diff options
context:
space:
mode:
authorQinglin Pan <panqinglin2020@iscas.ac.cn>2022-01-27 10:48:43 +0800
committerPalmer Dabbelt <palmer@rivosinc.com>2022-02-14 16:32:45 -0800
commit011f09d1205285b215003a6c65408609ef78abac (patch)
treee26e022ee042bd8d8a41eb244355017bae2d6da6 /arch/riscv/mm/init.c
parentriscv: mm: Prepare pt_ops helper functions for sv57 (diff)
downloadlinux-dev-011f09d1205285b215003a6c65408609ef78abac.tar.xz
linux-dev-011f09d1205285b215003a6c65408609ef78abac.zip
riscv: mm: Set sv57 on defaultly
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>
Diffstat (limited to 'arch/riscv/mm/init.c')
-rw-r--r--arch/riscv/mm/init.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 425377c97c40..df8ddde2e750 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -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);
}