Message ID | 20230913124227.12574-9-binbin.wu@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | LAM and LASS KVM Enabling | expand |
On Wed, Sep 13, 2023, Binbin Wu wrote: > diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h > index e3054e3e46d5..179931b73876 100644 > --- a/arch/x86/include/asm/kvm-x86-ops.h > +++ b/arch/x86/include/asm/kvm-x86-ops.h > @@ -134,6 +134,7 @@ KVM_X86_OP(msr_filter_changed) > KVM_X86_OP(complete_emulated_msr) > KVM_X86_OP(vcpu_deliver_sipi_vector) > KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons); > +KVM_X86_OP(get_untagged_addr) This needs to be KVM_X86_OP_OPTIONAL(), otherwise kvm_ops_update() will complain about SVM not implementing the hook. Hooray for useful warns! (I missed this in review).
On Wed, Sep 13, 2023, Binbin Wu wrote: > Introduce a new interface get_untagged_addr() to kvm_x86_ops to untag > the metadata from linear address. Call the interface in linearization > of instruction emulator for 64-bit mode. > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index ea48ba87dacf..e03313287816 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -8308,6 +8308,15 @@ static void emulator_vm_bugged(struct x86_emulate_ctxt *ctxt) > kvm_vm_bugged(kvm); > } > > +static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt, > + gva_t addr, unsigned int flags) > +{ > + if (!kvm_x86_ops.get_untagged_addr) > + return addr; > + > + return static_call(kvm_x86_get_untagged_addr)(emul_to_vcpu(ctxt), addr, flags); > +} > + > static const struct x86_emulate_ops emulate_ops = { > .vm_bugged = emulator_vm_bugged, > .read_gpr = emulator_read_gpr, > @@ -8352,6 +8361,7 @@ static const struct x86_emulate_ops emulate_ops = { > .leave_smm = emulator_leave_smm, > .triple_fault = emulator_triple_fault, > .set_xcr = emulator_set_xcr, > + .get_untagged_addr = emulator_get_untagged_addr, Oh, and for posterity because I've now thought about this on two separate occasions: We _could_ nullify .get_untagged_addr() if LAM isn't supported, e.g. to save a RETPOLINE when applicable, but that would require making emulate_ops non-const, and so I think it's worth eating the indirect call. I suppose we could gate it on CONFIG_ADDRESS_MASKING, but then we'd have to carry a bunch of #ifdefs in the VMX code, so I don't think that's worth doing either.
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h index e3054e3e46d5..179931b73876 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -134,6 +134,7 @@ KVM_X86_OP(msr_filter_changed) KVM_X86_OP(complete_emulated_msr) KVM_X86_OP(vcpu_deliver_sipi_vector) KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons); +KVM_X86_OP(get_untagged_addr) #undef KVM_X86_OP #undef KVM_X86_OP_OPTIONAL diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 1a4def36d5bb..08e94f30d376 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1751,6 +1751,8 @@ struct kvm_x86_ops { * Returns vCPU specific APICv inhibit reasons */ unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu); + + gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags); }; struct kvm_x86_nested_ops { diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f54e1a2cafa9..7af58b8d57ac 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -701,7 +701,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, *max_size = 0; switch (mode) { case X86EMUL_MODE_PROT64: - *linear = la; + *linear = la = ctxt->ops->get_untagged_addr(ctxt, la, flags); va_bits = ctxt_virt_addr_bits(ctxt); if (!__is_canonical_address(la, va_bits)) goto bad; diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 70f329a685fe..26f402616604 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -231,6 +231,9 @@ struct x86_emulate_ops { int (*leave_smm)(struct x86_emulate_ctxt *ctxt); void (*triple_fault)(struct x86_emulate_ctxt *ctxt); int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr); + + gva_t (*get_untagged_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr, + unsigned int flags); }; /* Type, address-of, and value of an instruction's operand. */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ea48ba87dacf..e03313287816 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8308,6 +8308,15 @@ static void emulator_vm_bugged(struct x86_emulate_ctxt *ctxt) kvm_vm_bugged(kvm); } +static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt, + gva_t addr, unsigned int flags) +{ + if (!kvm_x86_ops.get_untagged_addr) + return addr; + + return static_call(kvm_x86_get_untagged_addr)(emul_to_vcpu(ctxt), addr, flags); +} + static const struct x86_emulate_ops emulate_ops = { .vm_bugged = emulator_vm_bugged, .read_gpr = emulator_read_gpr, @@ -8352,6 +8361,7 @@ static const struct x86_emulate_ops emulate_ops = { .leave_smm = emulator_leave_smm, .triple_fault = emulator_triple_fault, .set_xcr = emulator_set_xcr, + .get_untagged_addr = emulator_get_untagged_addr, }; static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)