diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 0acac81f198b..a8b76c4c95e2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2659,12 +2659,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
2659 | default: | 2659 | default: |
2660 | msr = find_msr_entry(vmx, msr_index); | 2660 | msr = find_msr_entry(vmx, msr_index); |
2661 | if (msr) { | 2661 | if (msr) { |
2662 | u64 old_msr_data = msr->data; | ||
2662 | msr->data = data; | 2663 | msr->data = data; |
2663 | if (msr - vmx->guest_msrs < vmx->save_nmsrs) { | 2664 | if (msr - vmx->guest_msrs < vmx->save_nmsrs) { |
2664 | preempt_disable(); | 2665 | preempt_disable(); |
2665 | kvm_set_shared_msr(msr->index, msr->data, | 2666 | ret = kvm_set_shared_msr(msr->index, msr->data, |
2666 | msr->mask); | 2667 | msr->mask); |
2667 | preempt_enable(); | 2668 | preempt_enable(); |
2669 | if (ret) | ||
2670 | msr->data = old_msr_data; | ||
2668 | } | 2671 | } |
2669 | break; | 2672 | break; |
2670 | } | 2673 | } |
@@ -5291,7 +5294,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu) | |||
5291 | msr.data = data; | 5294 | msr.data = data; |
5292 | msr.index = ecx; | 5295 | msr.index = ecx; |
5293 | msr.host_initiated = false; | 5296 | msr.host_initiated = false; |
5294 | if (vmx_set_msr(vcpu, &msr) != 0) { | 5297 | if (kvm_set_msr(vcpu, &msr) != 0) { |
5295 | trace_kvm_msr_write_ex(ecx, data); | 5298 | trace_kvm_msr_write_ex(ecx, data); |
5296 | kvm_inject_gp(vcpu, 0); | 5299 | kvm_inject_gp(vcpu, 0); |
5297 | return 1; | 5300 | return 1; |
@@ -6743,6 +6746,12 @@ static int handle_invept(struct kvm_vcpu *vcpu) | |||
6743 | return 1; | 6746 | return 1; |
6744 | } | 6747 | } |
6745 | 6748 | ||
6749 | static int handle_invvpid(struct kvm_vcpu *vcpu) | ||
6750 | { | ||
6751 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
6752 | return 1; | ||
6753 | } | ||
6754 | |||
6746 | /* | 6755 | /* |
6747 | * The exit handlers return 1 if the exit was handled fully and guest execution | 6756 | * The exit handlers return 1 if the exit was handled fully and guest execution |
6748 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs | 6757 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs |
@@ -6788,6 +6797,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
6788 | [EXIT_REASON_MWAIT_INSTRUCTION] = handle_mwait, | 6797 | [EXIT_REASON_MWAIT_INSTRUCTION] = handle_mwait, |
6789 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor, | 6798 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor, |
6790 | [EXIT_REASON_INVEPT] = handle_invept, | 6799 | [EXIT_REASON_INVEPT] = handle_invept, |
6800 | [EXIT_REASON_INVVPID] = handle_invvpid, | ||
6791 | }; | 6801 | }; |
6792 | 6802 | ||
6793 | static const int kvm_vmx_max_exit_handlers = | 6803 | static const int kvm_vmx_max_exit_handlers = |
@@ -7023,7 +7033,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7023 | case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD: | 7033 | case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD: |
7024 | case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE: | 7034 | case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE: |
7025 | case EXIT_REASON_VMOFF: case EXIT_REASON_VMON: | 7035 | case EXIT_REASON_VMOFF: case EXIT_REASON_VMON: |
7026 | case EXIT_REASON_INVEPT: | 7036 | case EXIT_REASON_INVEPT: case EXIT_REASON_INVVPID: |
7027 | /* | 7037 | /* |
7028 | * VMX instructions trap unconditionally. This allows L1 to | 7038 | * VMX instructions trap unconditionally. This allows L1 to |
7029 | * emulate them for its L2 guest, i.e., allows 3-level nesting! | 7039 | * emulate them for its L2 guest, i.e., allows 3-level nesting! |
@@ -7164,10 +7174,10 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) | |||
7164 | && kvm_vmx_exit_handlers[exit_reason]) | 7174 | && kvm_vmx_exit_handlers[exit_reason]) |
7165 | return kvm_vmx_exit_handlers[exit_reason](vcpu); | 7175 | return kvm_vmx_exit_handlers[exit_reason](vcpu); |
7166 | else { | 7176 | else { |
7167 | vcpu->run->exit_reason = KVM_EXIT_UNKNOWN; | 7177 | WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_reason); |
7168 | vcpu->run->hw.hardware_exit_reason = exit_reason; | 7178 | kvm_queue_exception(vcpu, UD_VECTOR); |
7179 | return 1; | ||
7169 | } | 7180 | } |
7170 | return 0; | ||
7171 | } | 7181 | } |
7172 | 7182 | ||
7173 | static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | 7183 | static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) |