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

Oleksii Kurochko posted 2 patches 5 hours ago
[PATCH v2 1/2] xen/riscv: add support for local guest TLB flush using HFENCE.VVMA
Posted by Oleksii Kurochko 5 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>
---
Changes in v2:
 - Add missed blanks in asm().
 - Add operand modifier "z" and "J" constraint to be sure that zero register
   will be used when 0 is passed to HFENCE_VVMA().
---
 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..61aaa202fd13
--- /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 %z0, %z1" \
+                  :: "rJ" (vaddr), "rJ" (asid) : "memory" )
+
+#endif /* ASM_RISCV_INSN_DEFS_H */
-- 
2.52.0