Commit 8242f9ed authored by Binbin Wu's avatar Binbin Wu Committed by Zhiquan Li
Browse files

KVM: x86: Introduce get_untagged_addr() in kvm_x86_ops and call it in emulator

mainline inclusion
from mainline-v6.8-rc1
commit 37a41847b770c722e98ace72f3851fb49b360c08
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I94GWL
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=37a41847b770c722e98ace72f3851fb49b360c08



--------------------------------

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.

When enabled feature like Intel Linear Address Masking (LAM) or AMD Upper
Address Ignore (UAI), linear addresses may be tagged with metadata that
needs to be dropped prior to canonicality checks, i.e. the metadata is
ignored.

Introduce get_untagged_addr() to kvm_x86_ops to hide the vendor specific
code, as sadly LAM and UAI have different semantics.  Pass the emulator
flags to allow vendor specific implementation to precisely identify the
access type (LAM doesn't untag certain accesses).

Intel-SIG: commit 37a41847b770 KVM: x86: Introduce get_untagged_addr()
in kvm_x86_ops and call it in emulator
Backport KVM Linear Address Masking (LAM) support.

Signed-off-by: default avatarBinbin Wu <binbin.wu@linux.intel.com>
Reviewed-by: default avatarChao Gao <chao.gao@intel.com>
Tested-by: default avatarXuelian Guo <xuelian.guo@intel.com>
Link: https://lore.kernel.org/r/20230913124227.12574-9-binbin.wu@linux.intel.com


[sean: massage changelog]
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
[ Zhiquan Li: amend commit log ]
Signed-off-by: default avatarZhiquan Li <zhiquan1.li@intel.com>
parent 8069809a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -135,6 +135,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_OPTIONAL(get_untagged_addr)

#undef KVM_X86_OP
#undef KVM_X86_OP_OPTIONAL
+2 −0
Original line number Diff line number Diff line
@@ -1767,6 +1767,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 {
+1 −1
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -230,6 +230,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. */
+10 −0
Original line number Diff line number Diff line
@@ -8395,6 +8395,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,
@@ -8439,6 +8448,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)