|
@@ -132,6 +132,12 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
|
|
|
|
|
|
#define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
|
|
|
|
|
|
+#define VMX_VPID_EXTENT_SUPPORTED_MASK \
|
|
|
+ (VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT | \
|
|
|
+ VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | \
|
|
|
+ VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT | \
|
|
|
+ VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT)
|
|
|
+
|
|
|
/*
|
|
|
* These 2 parameters are used to config the controls for Pause-Loop Exiting:
|
|
|
* 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)
|
|
|
*/
|
|
|
if (enable_vpid)
|
|
|
vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
|
|
|
- VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
|
|
|
- VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
|
|
|
+ VMX_VPID_EXTENT_SUPPORTED_MASK;
|
|
|
else
|
|
|
vmx->nested.nested_vmx_vpid_caps = 0;
|
|
|
|
|
@@ -7597,7 +7602,8 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
|
|
|
vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
|
|
type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
|
|
|
|
|
|
- types = (vmx->nested.nested_vmx_vpid_caps >> 8) & 0x7;
|
|
|
+ types = (vmx->nested.nested_vmx_vpid_caps &
|
|
|
+ VMX_VPID_EXTENT_SUPPORTED_MASK) >> 8;
|
|
|
|
|
|
if (type >= 32 || !(types & (1 << type))) {
|
|
|
nested_vmx_failValid(vcpu,
|
|
@@ -7619,21 +7625,27 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
|
|
|
}
|
|
|
|
|
|
switch (type) {
|
|
|
+ case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
|
|
|
case VMX_VPID_EXTENT_SINGLE_CONTEXT:
|
|
|
- /*
|
|
|
- * Old versions of KVM use the single-context version so we
|
|
|
- * have to support it; just treat it the same as all-context.
|
|
|
- */
|
|
|
+ case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
|
|
|
+ if (!vpid) {
|
|
|
+ nested_vmx_failValid(vcpu,
|
|
|
+ VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
|
|
|
+ skip_emulated_instruction(vcpu);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
case VMX_VPID_EXTENT_ALL_CONTEXT:
|
|
|
- __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
|
|
|
- nested_vmx_succeed(vcpu);
|
|
|
break;
|
|
|
default:
|
|
|
- /* Trap individual address invalidation invvpid calls */
|
|
|
- BUG_ON(1);
|
|
|
- break;
|
|
|
+ WARN_ON_ONCE(1);
|
|
|
+ skip_emulated_instruction(vcpu);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
+ __vmx_flush_tlb(vcpu, vmx->nested.vpid02);
|
|
|
+ nested_vmx_succeed(vcpu);
|
|
|
+
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
return 1;
|
|
|
}
|