On 18/04/2023 11:48, Paul Durrant wrote: >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 Yes, because of this comment in David's email: "I don't even know that we care about in-kernel acceleration for the -EINVAL case. We could just return false for that, and let userspace (report and) handle it." > >> + >> 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 { >