diff options
| -rw-r--r-- | arch/riscv/kernel/head.S | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 987d4648aad9..370c66ce187a 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S | |||
| @@ -96,7 +96,9 @@ relocate: | |||
| 96 | 96 | ||
| 97 | /* | 97 | /* |
| 98 | * Load trampoline page directory, which will cause us to trap to | 98 | * Load trampoline page directory, which will cause us to trap to |
| 99 | * stvec if VA != PA, or simply fall through if VA == PA | 99 | * stvec if VA != PA, or simply fall through if VA == PA. We need a |
| 100 | * full fence here because setup_vm() just wrote these PTEs and we need | ||
| 101 | * to ensure the new translations are in use. | ||
| 100 | */ | 102 | */ |
| 101 | la a0, trampoline_pg_dir | 103 | la a0, trampoline_pg_dir |
| 102 | srl a0, a0, PAGE_SHIFT | 104 | srl a0, a0, PAGE_SHIFT |
| @@ -115,8 +117,14 @@ relocate: | |||
| 115 | la gp, __global_pointer$ | 117 | la gp, __global_pointer$ |
| 116 | .option pop | 118 | .option pop |
| 117 | 119 | ||
| 118 | /* Switch to kernel page tables */ | 120 | /* |
| 121 | * Switch to kernel page tables. A full fence is necessary in order to | ||
| 122 | * avoid using the trampoline translations, which are only correct for | ||
| 123 | * the first superpage. Fetching the fence is guarnteed to work | ||
| 124 | * because that first superpage is translated the same way. | ||
| 125 | */ | ||
| 119 | csrw CSR_SATP, a2 | 126 | csrw CSR_SATP, a2 |
| 127 | sfence.vma | ||
| 120 | 128 | ||
| 121 | ret | 129 | ret |
| 122 | 130 | ||
