Skip to content

Commit 37a4184

Browse files
Binbin Wusean-jc
authored andcommitted
KVM: x86: Introduce get_untagged_addr() in kvm_x86_ops and call it in emulator
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). Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Chao Gao <chao.gao@intel.com> Tested-by: Xuelian 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: Sean Christopherson <seanjc@google.com>
1 parent 9c8021d commit 37a4184

5 files changed

Lines changed: 17 additions & 1 deletion

File tree

arch/x86/include/asm/kvm-x86-ops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ KVM_X86_OP(msr_filter_changed)
135135
KVM_X86_OP(complete_emulated_msr)
136136
KVM_X86_OP(vcpu_deliver_sipi_vector)
137137
KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons);
138+
KVM_X86_OP_OPTIONAL(get_untagged_addr)
138139

139140
#undef KVM_X86_OP
140141
#undef KVM_X86_OP_OPTIONAL

arch/x86/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,8 @@ struct kvm_x86_ops {
17621762
* Returns vCPU specific APICv inhibit reasons
17631763
*/
17641764
unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu);
1765+
1766+
gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
17651767
};
17661768

17671769
struct kvm_x86_nested_ops {

arch/x86/kvm/emulate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
701701
*max_size = 0;
702702
switch (mode) {
703703
case X86EMUL_MODE_PROT64:
704-
*linear = la;
704+
*linear = la = ctxt->ops->get_untagged_addr(ctxt, la, flags);
705705
va_bits = ctxt_virt_addr_bits(ctxt);
706706
if (!__is_canonical_address(la, va_bits))
707707
goto bad;

arch/x86/kvm/kvm_emulate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ struct x86_emulate_ops {
230230
int (*leave_smm)(struct x86_emulate_ctxt *ctxt);
231231
void (*triple_fault)(struct x86_emulate_ctxt *ctxt);
232232
int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr);
233+
234+
gva_t (*get_untagged_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr,
235+
unsigned int flags);
233236
};
234237

235238
/* Type, address-of, and value of an instruction's operand. */

arch/x86/kvm/x86.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8445,6 +8445,15 @@ static void emulator_vm_bugged(struct x86_emulate_ctxt *ctxt)
84458445
kvm_vm_bugged(kvm);
84468446
}
84478447

8448+
static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt,
8449+
gva_t addr, unsigned int flags)
8450+
{
8451+
if (!kvm_x86_ops.get_untagged_addr)
8452+
return addr;
8453+
8454+
return static_call(kvm_x86_get_untagged_addr)(emul_to_vcpu(ctxt), addr, flags);
8455+
}
8456+
84488457
static const struct x86_emulate_ops emulate_ops = {
84498458
.vm_bugged = emulator_vm_bugged,
84508459
.read_gpr = emulator_read_gpr,
@@ -8489,6 +8498,7 @@ static const struct x86_emulate_ops emulate_ops = {
84898498
.leave_smm = emulator_leave_smm,
84908499
.triple_fault = emulator_triple_fault,
84918500
.set_xcr = emulator_set_xcr,
8501+
.get_untagged_addr = emulator_get_untagged_addr,
84928502
};
84938503

84948504
static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)

0 commit comments

Comments
 (0)