mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
riscv: mm: Apply Svinval in update_mmu_cache()
Use Svinval in update_mmu_cache_range() when the extension is available. Signed-off-by: Xu Lu <luxu.kernel@bytedance.com> Link: https://patch.msgid.link/20260715132009.10634-3-luxu.kernel@bytedance.com Tested-by: Klara Modin <klarasmodin@gmail.com> Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
parent
af842aea58
commit
905be00304
|
|
@ -578,6 +578,14 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
|
|||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC))
|
||||
return;
|
||||
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVINVAL)) {
|
||||
local_sfence_w_inval();
|
||||
while (nr--)
|
||||
local_sinval_vma(address + nr * PAGE_SIZE, asid);
|
||||
local_sfence_inval_ir();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The kernel assumes that TLBs don't cache invalid entries, but
|
||||
* in RISC-V, SFENCE.VMA specifies an ordering constraint, not a
|
||||
|
|
|
|||
|
|
@ -20,6 +20,24 @@ static inline unsigned long get_mm_asid(struct mm_struct *mm)
|
|||
return mm ? cntx2asid(atomic_long_read(&mm->context.id)) : FLUSH_TLB_NO_ASID;
|
||||
}
|
||||
|
||||
static inline void local_sfence_inval_ir(void)
|
||||
{
|
||||
asm volatile(SFENCE_INVAL_IR() ::: "memory");
|
||||
}
|
||||
|
||||
static inline void local_sfence_w_inval(void)
|
||||
{
|
||||
asm volatile(SFENCE_W_INVAL() ::: "memory");
|
||||
}
|
||||
|
||||
static inline void local_sinval_vma(unsigned long vma, unsigned long asid)
|
||||
{
|
||||
if (asid != FLUSH_TLB_NO_ASID)
|
||||
asm volatile(SINVAL_VMA(%0, %1) : : "r" (vma), "r" (asid) : "memory");
|
||||
else
|
||||
asm volatile(SINVAL_VMA(%0, zero) : : "r" (vma) : "memory");
|
||||
}
|
||||
|
||||
static inline void local_flush_tlb_all(void)
|
||||
{
|
||||
__asm__ __volatile__ ("sfence.vma" : : : "memory");
|
||||
|
|
|
|||
|
|
@ -11,24 +11,6 @@
|
|||
|
||||
#define has_svinval() riscv_has_extension_unlikely(RISCV_ISA_EXT_SVINVAL)
|
||||
|
||||
static inline void local_sfence_inval_ir(void)
|
||||
{
|
||||
asm volatile(SFENCE_INVAL_IR() ::: "memory");
|
||||
}
|
||||
|
||||
static inline void local_sfence_w_inval(void)
|
||||
{
|
||||
asm volatile(SFENCE_W_INVAL() ::: "memory");
|
||||
}
|
||||
|
||||
static inline void local_sinval_vma(unsigned long vma, unsigned long asid)
|
||||
{
|
||||
if (asid != FLUSH_TLB_NO_ASID)
|
||||
asm volatile(SINVAL_VMA(%0, %1) : : "r" (vma), "r" (asid) : "memory");
|
||||
else
|
||||
asm volatile(SINVAL_VMA(%0, zero) : : "r" (vma) : "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush entire TLB if number of entries to be flushed is greater
|
||||
* than the threshold below.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user