diff options
Diffstat (limited to 'arch/riscv')
-rw-r--r-- | arch/riscv/lib/delay.c | 2 | ||||
-rw-r--r-- | arch/riscv/mm/fault.c | 13 |
2 files changed, 14 insertions, 1 deletions
diff --git a/arch/riscv/lib/delay.c b/arch/riscv/lib/delay.c index dce8ae24c6d3..ee6853c1e341 100644 --- a/arch/riscv/lib/delay.c +++ b/arch/riscv/lib/delay.c @@ -88,7 +88,7 @@ EXPORT_SYMBOL(__delay); void udelay(unsigned long usecs) { - unsigned long ucycles = usecs * lpj_fine * UDELAY_MULT; + u64 ucycles = (u64)usecs * lpj_fine * UDELAY_MULT; if (unlikely(usecs > MAX_UDELAY_US)) { __delay((u64)usecs * riscv_timebase / 1000000ULL); diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index 88401d5125bc..523dbfbac03d 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -29,6 +29,7 @@ #include <asm/pgalloc.h> #include <asm/ptrace.h> +#include <asm/tlbflush.h> /* * This routine handles page faults. It determines the address and the @@ -281,6 +282,18 @@ vmalloc_fault: pte_k = pte_offset_kernel(pmd_k, addr); if (!pte_present(*pte_k)) goto no_context; + + /* + * The kernel assumes that TLBs don't cache invalid + * entries, but in RISC-V, SFENCE.VMA specifies an + * ordering constraint, not a cache flush; it is + * necessary even after writing invalid entries. + * Relying on flush_tlb_fix_spurious_fault would + * suffice, but the extra traps reduce + * performance. So, eagerly SFENCE.VMA. + */ + local_flush_tlb_page(addr); + return; } } |