Re: [PATCH v3 06/12] KVM: x86: Forward VMware hypercalls to userspace
From: Jim Mattson
Date: Wed Nov 11 2026 - 19:33:12 EST
On Tue, Nov 10, 2026 at 10:05 PM Zack Rusin <zack.rusin@xxxxxxxxxxxx> wrote:
>
> Add KVM_VMWARE_ENABLE_HYPERCALL. When it is enabled, exit to userspace
> with KVM_EXIT_VMWARE when an L1 vCPU executes VMCALL or VMMCALL with
> VMware's magic value in EAX, and let userspace complete the call by
> updating the guest's registers or by having KVM inject #UD, #GP or #PF.
>
> VMware guests reach the hypervisor through the "backdoor": either the
> I/O-port interface that KVM already emulates or, on newer guests,
> VMCALL or VMMCALL, with the same commands and register conventions.
> VMware's userspace implements the roughly one hundred commands, and
> reviewing the command list on the mailing list found none that needs
> to be handled in KVM (see the Links), so leave them in userspace.
>
> Only claim calls that carry the magic value, so that the same VM can
> still use Xen, Hyper-V or KVM hypercalls. Never claim a call from L2:
> the only L2 hypercall that L0 handles itself is Hyper-V's L2 TLB flush,
> which doesn't use RAX as an input.
>
> Pass operands and results through KVM_SYNC_X86_REGS instead of defining
> a second register ABI; KVM_EXIT_HYPERCALL returns a single value in
> RAX, while backdoor commands use RAX through RBP. Report the CPL and
> leave the privilege policy to userspace, as VMware Tools call the
> backdoor from user mode. Instead of completing the call, userspace can
> have KVM inject a validated #UD, #GP or #PF at the hypercall, and may
> update the registers as well to keep the partial progress of a
> high-bandwidth transfer.
>
> Don't forward hypercalls of vCPUs whose state is protected, as KVM
> can't access their registers: reject the flag for VMs with protected
> state, omit it from their VM-scoped KVM_CHECK_EXTENSION result, and
> ignore it once a vCPU of a VM set up with the legacy KVM_SEV_ES_INIT
> becomes protected.
>
> Link: https://lore.kernel.org/r/c60b32a3-e699-4a8c-8d52-09b34c4d5269@xxxxxxxxxx
> Link: https://lore.kernel.org/r/CADH9ctD1uf_yBA3NXNQu7TJa_TPhLRN=0YZ3j2gGhgmaFRdCFg@xxxxxxxxxxxxxx
> Link: https://lore.kernel.org/r/CADH9ctBivnvP1tNcatLKzd8EDz8Oo6X65660j8ccxYzk3aFzCA@xxxxxxxxxxxxxx
> Link: https://lore.kernel.org/r/aIEmawm9gLflg8zt@xxxxxxxxxx
> Signed-off-by: Zack Rusin <zack.rusin@xxxxxxxxxxxx>
> ---
[ ... ]
> +static int complete_vmware_hypercall_exit(struct kvm_vcpu *vcpu)
> +{
> + struct kvm_vmware_exit *vmware = &vcpu->run->vmware;
> + u32 pad1 = READ_ONCE(vmware->pad1);
> + u32 inject = READ_ONCE(vmware->hcall.exception.inject);
> + u32 pad2 = READ_ONCE(vmware->hcall.exception.pad2);
> + u32 vector = READ_ONCE(vmware->hcall.exception.vector);
> + u32 error_code = READ_ONCE(vmware->hcall.exception.error_code);
> + u64 address = READ_ONCE(vmware->hcall.exception.address);
> +
> + if (pad1 || pad2 || inject > 1)
> + return -EINVAL;
> +
Should this check kvm_is_linear_rip(vcpu, vcpu->arch.cui_linear_rip),
like the fast PIO completions do?