[PATCH v1 2/3] xen/riscv: add support for local guest TLB flush using HFENCE.VVMA

Oleksii Kurochko posted 3 patches 6 days, 20 hours ago
[PATCH v1 2/3] xen/riscv: add support for local guest TLB flush using HFENCE.VVMA
Posted by Oleksii Kurochko 6 days, 20 hours ago
Introduce flush_tlb_guest_local() to perform a local TLB flush of the guest's
address space for the current hart. This leverages the RISC-V HFENCE.VVMA
instruction, which is used to invalidate translations in the VS-stage of
address translation.

As for RISC-V binutils >= 2.39 is choosen, we can use hfence.vvma mnemonics
instead of defining hfence.vvma using .insn.

Although it would be possible to use sbi_remote_hfence_vvma() for this purpose,
it is unnecessary in this context since the flush is required only on the
local hart. Using the SBI call would introduce additional overhead without
benefit, resulting in unnecessary performance loss.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/flushtlb.h  |  7 +++++++
 xen/arch/riscv/include/asm/insn-defs.h | 10 ++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/insn-defs.h

diff --git a/xen/arch/riscv/include/asm/flushtlb.h b/xen/arch/riscv/include/asm/flushtlb.h
index 4f64f9757058..b0112d416dbe 100644
--- a/xen/arch/riscv/include/asm/flushtlb.h
+++ b/xen/arch/riscv/include/asm/flushtlb.h
@@ -5,6 +5,7 @@
 #include <xen/bug.h>
 #include <xen/cpumask.h>
 
+#include <asm/insn-defs.h>
 #include <asm/sbi.h>
 
 struct page_info;
@@ -14,6 +15,12 @@ static inline void local_hfence_gvma_all(void)
     asm volatile ( "hfence.gvma zero, zero" ::: "memory" );
 }
 
+/* Flush VS-stage TLB for current hart. */
+static inline void flush_tlb_guest_local(void)
+{
+    HFENCE_VVMA(0, 0);
+}
+
 /* Flush TLB of local processor for address va. */
 static inline void flush_tlb_one_local(vaddr_t va)
 {
diff --git a/xen/arch/riscv/include/asm/insn-defs.h b/xen/arch/riscv/include/asm/insn-defs.h
new file mode 100644
index 000000000000..4d50b5e23c11
--- /dev/null
+++ b/xen/arch/riscv/include/asm/insn-defs.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ASM_RISCV_INSN_DEFS_H
+#define ASM_RISCV_INSN_DEFS_H
+
+#define HFENCE_VVMA(vaddr, asid) \
+    asm volatile ("hfence.vvma %0, %1" \
+                  :: "r"(vaddr), "r"(asid) : "memory")
+
+#endif /* ASM_RISCV_INSN_DEFS_H */
-- 
2.52.0
Re: [PATCH v1 2/3] xen/riscv: add support for local guest TLB flush using HFENCE.VVMA
Posted by Jan Beulich 4 days, 21 hours ago
On 02.02.2026 13:57, Oleksii Kurochko wrote:
> @@ -14,6 +15,12 @@ static inline void local_hfence_gvma_all(void)
>      asm volatile ( "hfence.gvma zero, zero" ::: "memory" );
>  }
>  
> +/* Flush VS-stage TLB for current hart. */
> +static inline void flush_tlb_guest_local(void)
> +{
> +    HFENCE_VVMA(0, 0);

For this use, ...

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/insn-defs.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef ASM_RISCV_INSN_DEFS_H
> +#define ASM_RISCV_INSN_DEFS_H
> +
> +#define HFENCE_VVMA(vaddr, asid) \
> +    asm volatile ("hfence.vvma %0, %1" \
> +                  :: "r"(vaddr), "r"(asid) : "memory")

... don't you want to use "rJ" as the constraints here?

It's further not quite clear to me whether the memory clobber is really
needed. Pretty certainly not for the use in context switch, but perhaps
for other future uses it's better to be there, even if only to be on the
safe side.

Also, style nit: There are a number of blanks missing in this asm().

Jan
Re: [PATCH v1 2/3] xen/riscv: add support for local guest TLB flush using HFENCE.VVMA
Posted by Oleksii Kurochko 4 days ago
On 2/4/26 12:09 PM, Jan Beulich wrote:
> On 02.02.2026 13:57, Oleksii Kurochko wrote:
>> @@ -14,6 +15,12 @@ static inline void local_hfence_gvma_all(void)
>>       asm volatile ( "hfence.gvma zero, zero" ::: "memory" );
>>   }
>>   
>> +/* Flush VS-stage TLB for current hart. */
>> +static inline void flush_tlb_guest_local(void)
>> +{
>> +    HFENCE_VVMA(0, 0);
> For this use, ...
>
>> --- /dev/null
>> +++ b/xen/arch/riscv/include/asm/insn-defs.h
>> @@ -0,0 +1,10 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +
>> +#ifndef ASM_RISCV_INSN_DEFS_H
>> +#define ASM_RISCV_INSN_DEFS_H
>> +
>> +#define HFENCE_VVMA(vaddr, asid) \
>> +    asm volatile ("hfence.vvma %0, %1" \
>> +                  :: "r"(vaddr), "r"(asid) : "memory")
> ... don't you want to use "rJ" as the constraints here?

Even without "rJ" it is using x0 when argument 0 is passed. Just to be on a
safe side I don't mind to add "J".

~ Oleksii