[PATCH 0/4] KVM: x86: hyper-v: Forward unimplemented hypercalls to userspace

From: David Woodhouse

Date: Wed Nov 11 2026 - 15:59:04 EST


From: David Woodhouse <dwmw@xxxxxxxxxxxx>

KVM implements a fixed set of Hyper-V hypercalls and fails every other
code with HV_STATUS_INVALID_HYPERCALL_CODE. A VMM that wants to
implement more of the TLFS, such as the VSM hypercalls Windows uses for
Virtualization Based Security, never sees them.

This series adds KVM_CAP_HYPERV_FORWARD_HCALL. As with KVM_CAP_XEN_HVM
and KVM_CAP_EXIT_HYPERCALL, KVM_CHECK_EXTENSION returns a bitmask of
features and KVM_ENABLE_CAP takes the subset to enable, rejecting any
bit the kernel does not report:

- KVM_HYPERV_HCALL_FORWARD_UNKNOWN (bit 0) sends the hypercalls KVM
does not implement, and extended hypercalls in fast form, out
through the existing KVM_EXIT_HYPERV_HCALL exit.

- KVM_HYPERV_HCALL_RAISE_UD (bit 1) lets userspace complete such an
exit by raising #UD at the hypercall instruction, which the TLFS
specifies for some invalid uses, instead of returning a status.
Userspace asks for that with KVM_HYPERV_HCALL_UD in a new 'flags'
field after the hypercall parameters; KVM zeroes it on every exit,
and refuses bits it does not know. The field fits in the existing
union, so struct kvm_run does not grow.

Further mask bits will follow for HvCallVtlCall and HvCallVtlReturn on
VMs with planes, so that KVM can handle VTL transitions in the kernel.

Patch 3 reports HV_X64_HYPERCALL_XMM_OUTPUT_AVAILABLE, since a VMM
handling a forwarded fast hypercall can write the XMM output itself.
Patch 4 adds a selftest.

This is orthogonal to KVM_CAP_HCALL_FAULT_EXIT in the memory attributes
series, which Vitaly asked about on v3 [2]. That one is about a memory
fault *during* the processing of a hypercall KVM does implement, which
it turns into KVM_EXIT_MEMORY_FAULT. This one is about the hypercalls
KVM does not implement at all. A forwarded hypercall goes out to
userspace before KVM touches any guest memory on its behalf, so the two
never meet, and a VMM can use either without the other.

This is the first part of the VSM work posted as an RFC [1] that does
not depend on planes or memory attributes.

The series is based on v7.4-rc2 and also applies cleanly to
kvm-x86/next (cbe54fc3462b). It has been compile-tested on x86_64 with
and without CONFIG_KVM_HYPERV.

Tested on v7.4-rc2 with this series and the KVM_TRANSLATE fix posted
alongside it, on an Intel Xeon 6 system (itself a KVM guest, so VMX
there is nested) and on a bare-metal AMD EPYC (Zen 4) system. The new
hyperv_forward_hcall selftest passes on both, as do hyperv_clock,
hyperv_cpuid, hyperv_extended_hypercalls, hyperv_features, hyperv_ipi
and hyperv_tlb_flush. hyperv_evmcs passes on Intel and hyperv_svm_test
on AMD, each skipping on the other vendor.

[1] https://lore.kernel.org/kvm/20261017122501.610248-1-dwmw2@xxxxxxxxxxxxx/
[2] https://lore.kernel.org/kvm/kupv77y5yrc.fsf@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/

David Woodhouse (4):
KVM: x86: hyper-v: Add KVM_CAP_HYPERV_FORWARD_HCALL
KVM: x86: hyper-v: Let userspace fault a forwarded hypercall
KVM: x86: hyper-v: Advertise XMM fast hypercall output
KVM: selftests: Add Hyper-V hypercall forwarding test

Documentation/virt/kvm/api.rst | 65 +++++
arch/x86/include/asm/kvm_host.h | 2 +
arch/x86/kvm/hyperv.c | 38 ++-
arch/x86/kvm/hyperv.h | 9 +
arch/x86/kvm/x86.c | 14 +
include/uapi/linux/kvm.h | 7 +
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../selftests/kvm/x86/hyperv_forward_hcall.c | 268 ++++++++++++++++++
8 files changed, 402 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86/hyperv_forward_hcall.c


base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb
--
2.50.1