Skip to content

Commit bcdde30

Browse files
Jan Dakinevichrkrcmar
authored andcommitted
KVM: nVMX: invvpid handling improvements
- Expose all invalidation types to the L1 - Reject invvpid instruction, if L1 passed zero vpid value to single context invalidations Signed-off-by: Jan Dakinevich <[email protected]> Tested-by: Ladi Prosek <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent 63f3ac4 commit bcdde30

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

arch/x86/kvm/vmx.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
132132

133133
#define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
134134

135+
#define VMX_VPID_EXTENT_SUPPORTED_MASK \
136+
(VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT | \
137+
VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | \
138+
VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT | \
139+
VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT)
140+
135141
/*
136142
* These 2 parameters are used to config the controls for Pause-Loop Exiting:
137143
* ple_gap: upper bound on the amount of time between two successive
@@ -2834,8 +2840,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
28342840
*/
28352841
if (enable_vpid)
28362842
vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
2837-
VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
2838-
VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
2843+
VMX_VPID_EXTENT_SUPPORTED_MASK;
28392844
else
28402845
vmx->nested.nested_vmx_vpid_caps = 0;
28412846

@@ -7597,7 +7602,8 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
75977602
vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
75987603
type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
75997604

7600-
types = (vmx->nested.nested_vmx_vpid_caps >> 8) & 0x7;
7605+
types = (vmx->nested.nested_vmx_vpid_caps &
7606+
VMX_VPID_EXTENT_SUPPORTED_MASK) >> 8;
76017607

76027608
if (type >= 32 || !(types & (1 << type))) {
76037609
nested_vmx_failValid(vcpu,
@@ -7619,21 +7625,27 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
76197625
}
76207626

76217627
switch (type) {
7628+
case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
76227629
case VMX_VPID_EXTENT_SINGLE_CONTEXT:
7623-
/*
7624-
* Old versions of KVM use the single-context version so we
7625-
* have to support it; just treat it the same as all-context.
7626-
*/
7630+
case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
7631+
if (!vpid) {
7632+
nested_vmx_failValid(vcpu,
7633+
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
7634+
skip_emulated_instruction(vcpu);
7635+
return 1;
7636+
}
7637+
break;
76277638
case VMX_VPID_EXTENT_ALL_CONTEXT:
7628-
__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
7629-
nested_vmx_succeed(vcpu);
76307639
break;
76317640
default:
7632-
/* Trap individual address invalidation invvpid calls */
7633-
BUG_ON(1);
7634-
break;
7641+
WARN_ON_ONCE(1);
7642+
skip_emulated_instruction(vcpu);
7643+
return 1;
76357644
}
76367645

7646+
__vmx_flush_tlb(vcpu, vmx->nested.vpid02);
7647+
nested_vmx_succeed(vcpu);
7648+
76377649
skip_emulated_instruction(vcpu);
76387650
return 1;
76397651
}

0 commit comments

Comments
 (0)