diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 19 |
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 | ||
1575 | static inline bool cpu_has_vmx_invvpid_individual_addr(void) | ||
1576 | { | ||
1577 | return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT; | ||
1578 | } | ||
1579 | |||
1575 | static inline bool cpu_has_vmx_invvpid_single(void) | 1580 | static 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); |