Skip to content

Commit 20e03d7

Browse files
SiFiveHollandpalmer-dabbelt
authored andcommitted
riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma
commit 3f1e782 ("riscv: add ASID-based tlbflushing methods") added calls to the sfence.vma instruction with rs2 != x0. These single-ASID instruction variants are also affected by SiFive errata CIP-1200. Until now, the errata workaround was not needed for the single-ASID sfence.vma variants, because they were only used when the ASID allocator was enabled, and the affected SiFive platforms do not support multiple ASIDs. However, we are going to start using those sfence.vma variants regardless of ASID support, so now we need alternatives covering them. Signed-off-by: Samuel Holland <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent c6026d3 commit 20e03d7

File tree

3 files changed

+29
-25
lines changed

3 files changed

+29
-25
lines changed

arch/riscv/include/asm/errata_list.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,21 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault), \
4343
CONFIG_ERRATA_SIFIVE_CIP_453)
4444
#else /* !__ASSEMBLY__ */
4545

46-
#define ALT_FLUSH_TLB_PAGE(x) \
46+
#define ALT_SFENCE_VMA_ASID(asid) \
47+
asm(ALTERNATIVE("sfence.vma x0, %0", "sfence.vma", SIFIVE_VENDOR_ID, \
48+
ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
49+
: : "r" (asid) : "memory")
50+
51+
#define ALT_SFENCE_VMA_ADDR(addr) \
4752
asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
4853
ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
4954
: : "r" (addr) : "memory")
5055

56+
#define ALT_SFENCE_VMA_ADDR_ASID(addr, asid) \
57+
asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID, \
58+
ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
59+
: : "r" (addr), "r" (asid) : "memory")
60+
5161
/*
5262
* _val is marked as "will be overwritten", so need to set it to 0
5363
* in the default case.

arch/riscv/include/asm/tlbflush.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,27 @@ static inline void local_flush_tlb_all(void)
2222
__asm__ __volatile__ ("sfence.vma" : : : "memory");
2323
}
2424

25+
static inline void local_flush_tlb_all_asid(unsigned long asid)
26+
{
27+
if (asid != FLUSH_TLB_NO_ASID)
28+
ALT_SFENCE_VMA_ASID(asid);
29+
else
30+
local_flush_tlb_all();
31+
}
32+
2533
/* Flush one page from local TLB */
2634
static inline void local_flush_tlb_page(unsigned long addr)
2735
{
28-
ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
36+
ALT_SFENCE_VMA_ADDR(addr);
37+
}
38+
39+
static inline void local_flush_tlb_page_asid(unsigned long addr,
40+
unsigned long asid)
41+
{
42+
if (asid != FLUSH_TLB_NO_ASID)
43+
ALT_SFENCE_VMA_ADDR_ASID(addr, asid);
44+
else
45+
local_flush_tlb_page(addr);
2946
}
3047

3148
void flush_tlb_all(void);

arch/riscv/mm/tlbflush.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,6 @@
77
#include <asm/sbi.h>
88
#include <asm/mmu_context.h>
99

10-
static inline void local_flush_tlb_all_asid(unsigned long asid)
11-
{
12-
if (asid != FLUSH_TLB_NO_ASID)
13-
__asm__ __volatile__ ("sfence.vma x0, %0"
14-
:
15-
: "r" (asid)
16-
: "memory");
17-
else
18-
local_flush_tlb_all();
19-
}
20-
21-
static inline void local_flush_tlb_page_asid(unsigned long addr,
22-
unsigned long asid)
23-
{
24-
if (asid != FLUSH_TLB_NO_ASID)
25-
__asm__ __volatile__ ("sfence.vma %0, %1"
26-
:
27-
: "r" (addr), "r" (asid)
28-
: "memory");
29-
else
30-
local_flush_tlb_page(addr);
31-
}
32-
3310
/*
3411
* Flush entire TLB if number of entries to be flushed is greater
3512
* than the threshold below.

0 commit comments

Comments
 (0)