Skip to content

Commit b39bd52

Browse files
Binbin Wusean-jc
authored andcommitted
KVM: x86: Untag addresses for LAM emulation where applicable
Stub in vmx_get_untagged_addr() and wire up calls from the emulator (via get_untagged_addr()) and "direct" calls from various VM-Exit handlers in VMX where LAM untagging is supposed to be applied. Defer implementing the guts of vmx_get_untagged_addr() to future patches purely to make the changes easier to consume. LAM is active only for 64-bit linear addresses and several types of accesses are exempted. - Cases need to untag address (handled in get_vmx_mem_address()) Operand(s) of VMX instructions and INVPCID. Operand(s) of SGX ENCLS. - Cases LAM doesn't apply to (no change needed) Operand of INVLPG. Linear address in INVPCID descriptor. Linear address in INVVPID descriptor. BASEADDR specified in SECS of ECREATE. Note: - LAM doesn't apply to write to control registers or MSRs - LAM masking is applied before walking page tables, i.e. the faulting linear address in CR2 doesn't contain the metadata. - The guest linear address saved in VMCS doesn't contain metadata. 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-10-binbin.wu@linux.intel.com [sean: massage changelog] Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 37a4184 commit b39bd52

5 files changed

Lines changed: 19 additions & 0 deletions

File tree

arch/x86/kvm/vmx/nested.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4980,6 +4980,7 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,
49804980
else
49814981
*ret = off;
49824982

4983+
*ret = vmx_get_untagged_addr(vcpu, *ret, 0);
49834984
/* Long mode: #GP(0)/#SS(0) if the memory address is in a
49844985
* non-canonical form. This is the only check on the memory
49854986
* destination for long mode!
@@ -5797,6 +5798,10 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
57975798
vpid02 = nested_get_vpid02(vcpu);
57985799
switch (type) {
57995800
case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
5801+
/*
5802+
* LAM doesn't apply to addresses that are inputs to TLB
5803+
* invalidation.
5804+
*/
58005805
if (!operand.vpid ||
58015806
is_noncanonical_address(operand.gla, vcpu))
58025807
return nested_vmx_fail(vcpu,

arch/x86/kvm/vmx/sgx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static int sgx_get_encls_gva(struct kvm_vcpu *vcpu, unsigned long offset,
3737
if (!IS_ALIGNED(*gva, alignment)) {
3838
fault = true;
3939
} else if (likely(is_64_bit_mode(vcpu))) {
40+
*gva = vmx_get_untagged_addr(vcpu, *gva, 0);
4041
fault = is_noncanonical_address(*gva, vcpu);
4142
} else {
4243
*gva &= 0xffffffff;

arch/x86/kvm/vmx/vmx.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8205,6 +8205,11 @@ static void vmx_vm_destroy(struct kvm *kvm)
82058205
free_pages((unsigned long)kvm_vmx->pid_table, vmx_get_pid_table_order(kvm));
82068206
}
82078207

8208+
gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags)
8209+
{
8210+
return gva;
8211+
}
8212+
82088213
static struct kvm_x86_ops vmx_x86_ops __initdata = {
82098214
.name = KBUILD_MODNAME,
82108215

@@ -8345,6 +8350,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
83458350
.complete_emulated_msr = kvm_complete_insn_gp,
83468351

83478352
.vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
8353+
8354+
.get_untagged_addr = vmx_get_untagged_addr,
83488355
};
83498356

83508357
static unsigned int vmx_handle_intel_pt_intr(void)

arch/x86/kvm/vmx/vmx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type);
420420
u64 vmx_get_l2_tsc_offset(struct kvm_vcpu *vcpu);
421421
u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu);
422422

423+
gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
424+
423425
static inline void vmx_set_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr,
424426
int type, bool value)
425427
{

arch/x86/kvm/x86.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13563,6 +13563,10 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva)
1356313563

1356413564
switch (type) {
1356513565
case INVPCID_TYPE_INDIV_ADDR:
13566+
/*
13567+
* LAM doesn't apply to addresses that are inputs to TLB
13568+
* invalidation.
13569+
*/
1356613570
if ((!pcid_enabled && (operand.pcid != 0)) ||
1356713571
is_noncanonical_address(operand.gla, vcpu)) {
1356813572
kvm_inject_gp(vcpu, 0);

0 commit comments

Comments
 (0)