On 18/04/2023 11:13, Metin Kaya wrote:
Implement in-KVM support for Xen's HVMOP_flush_tlbs hypercall, which
allows the guest to flush all vCPU's TLBs. KVM doesn't provide an
ioctl() to precisely flush guest TLBs, and punting to userspace would
likely negate the performance benefits of avoiding a TLB shootdown in
the guest.
Signed-off-by: Metin Kaya <metikaya@xxxxxxxxxxxx>
---
v3:
- Addressed comments for v2.
- Verified with XTF/invlpg test case.
v2:
- Removed an irrelevant URL from commit message.
---
arch/x86/kvm/xen.c | 15 +++++++++++++++
include/xen/interface/hvm/hvm_op.h | 3 +++
2 files changed, 18 insertions(+)
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 40edf4d1974c..a63c48e8d8fa 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -21,6 +21,7 @@
#include <xen/interface/vcpu.h>
#include <xen/interface/version.h>
#include <xen/interface/event_channel.h>
+#include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/sched.h>
#include <asm/xen/cpuid.h>
@@ -1330,6 +1331,17 @@ static bool kvm_xen_hcall_sched_op(struct kvm_vcpu *vcpu, bool longmode,
return false;
}
+static bool kvm_xen_hcall_hvm_op(struct kvm_vcpu *vcpu, int cmd, u64 arg, u64 *r)
+{
+ if (cmd == HVMOP_flush_tlbs && !arg) {
+ kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_TLB_FLUSH_GUEST);
+ *r = 0;
+ return true;
+ }
+
+ return false;
+}
This code structure means that arg != NULL will result in the guest
seeing ENOSYS rather than EINVAL.
Paul
+
struct compat_vcpu_set_singleshot_timer {
uint64_t timeout_abs_ns;
uint32_t flags;
@@ -1501,6 +1513,9 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
timeout |= params[1] << 32;
handled = kvm_xen_hcall_set_timer_op(vcpu, timeout, &r);
break;
+ case __HYPERVISOR_hvm_op:
+ handled = kvm_xen_hcall_hvm_op(vcpu, params[0], params[1], &r);
+ break;
}
default:
break;
diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
index 03134bf3cec1..240d8149bc04 100644
--- a/include/xen/interface/hvm/hvm_op.h
+++ b/include/xen/interface/hvm/hvm_op.h
@@ -16,6 +16,9 @@ struct xen_hvm_param {
};
DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_param);
+/* Flushes guest TLBs for all vCPUs: @arg must be 0. */
+#define HVMOP_flush_tlbs 5
+
/* Hint from PV drivers for pagetable destruction. */
#define HVMOP_pagetable_dying 9
struct xen_hvm_pagetable_dying {