On Wed, Mar 16, 2022, Oliver Upton wrote: > KVM handles the VMCALL/VMMCALL instructions very strangely. Even though > both of these instructions really should #UD when executed on the wrong > vendor's hardware (i.e. VMCALL on SVM, VMMCALL on VMX), KVM replaces the > guest's instruction with the appropriate instruction for the vendor. > Nonetheless, older guest kernels without commit c1118b3602c2 ("x86: kvm: > use alternatives for VMCALL vs. VMMCALL if kernel text is read-only") > do not patch in the appropriate instruction using alternatives, likely > motivating KVM's intervention. > > Add a quirk allowing userspace to opt out of hypercall patching. A quirk may not be appropriate, per Paolo, the whole cross-vendor thing is intentional. https://lore.kernel.org/all/20211210222903.3417968-1-seanjc@xxxxxxxxxx > If the quirk is disabled, KVM synthesizes a #UD in the guest. ... > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index d3a9ce07a565..685c4bc453b4 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -9291,6 +9291,17 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt) > char instruction[3]; > unsigned long rip = kvm_rip_read(vcpu); > > + /* > + * If the quirk is disabled, synthesize a #UD and let the guest pick up > + * the pieces. > + */ > + if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_FIX_HYPERCALL_INSN)) { > + ctxt->exception.error_code_valid = false; > + ctxt->exception.vector = UD_VECTOR; > + ctxt->have_exception = true; > + return X86EMUL_PROPAGATE_FAULT; This should return X86EMUL_UNHANDLEABLE instead of manually injecting a #UD. That will also end up generating a #UD in most cases, but will play nice with KVM_CAP_EXIT_ON_EMULATION_FAILURE.