aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/vmx.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 98f05e2b0ecc..e50beb76d846 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1572,6 +1572,11 @@ static inline bool cpu_has_vmx_invept_global(void)
1572 return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT; 1572 return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
1573} 1573}
1574 1574
1575static inline bool cpu_has_vmx_invvpid_individual_addr(void)
1576{
1577 return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT;
1578}
1579
1575static inline bool cpu_has_vmx_invvpid_single(void) 1580static inline bool cpu_has_vmx_invvpid_single(void)
1576{ 1581{
1577 return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT; 1582 return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
@@ -8513,12 +8518,19 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
8513 8518
8514 switch (type) { 8519 switch (type) {
8515 case VMX_VPID_EXTENT_INDIVIDUAL_ADDR: 8520 case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
8516 if (is_noncanonical_address(operand.gla, vcpu)) { 8521 if (!operand.vpid ||
8522 is_noncanonical_address(operand.gla, vcpu)) {
8517 nested_vmx_failValid(vcpu, 8523 nested_vmx_failValid(vcpu,
8518 VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); 8524 VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
8519 return kvm_skip_emulated_instruction(vcpu); 8525 return kvm_skip_emulated_instruction(vcpu);
8520 } 8526 }
8521 /* fall through */ 8527 if (cpu_has_vmx_invvpid_individual_addr() &&
8528 vmx->nested.vpid02) {
8529 __invvpid(VMX_VPID_EXTENT_INDIVIDUAL_ADDR,
8530 vmx->nested.vpid02, operand.gla);
8531 } else
8532 __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true);
8533 break;
8522 case VMX_VPID_EXTENT_SINGLE_CONTEXT: 8534 case VMX_VPID_EXTENT_SINGLE_CONTEXT:
8523 case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL: 8535 case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
8524 if (!operand.vpid) { 8536 if (!operand.vpid) {
@@ -8526,15 +8538,16 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
8526 VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); 8538 VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
8527 return kvm_skip_emulated_instruction(vcpu); 8539 return kvm_skip_emulated_instruction(vcpu);
8528 } 8540 }
8541 __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true);
8529 break; 8542 break;
8530 case VMX_VPID_EXTENT_ALL_CONTEXT: 8543 case VMX_VPID_EXTENT_ALL_CONTEXT:
8544 __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true);
8531 break; 8545 break;
8532 default: 8546 default:
8533 WARN_ON_ONCE(1); 8547 WARN_ON_ONCE(1);
8534 return kvm_skip_emulated_instruction(vcpu); 8548 return kvm_skip_emulated_instruction(vcpu);
8535 } 8549 }
8536 8550
8537 __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true);
8538 nested_vmx_succeed(vcpu); 8551 nested_vmx_succeed(vcpu);
8539 8552
8540 return kvm_skip_emulated_instruction(vcpu); 8553 return kvm_skip_emulated_instruction(vcpu);