Commit b97f0745 authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Paolo Bonzini

KVM: x86: determine if an exception has an error code only when injecting it.

A page fault can be queued while vCPU is in real paged mode on AMD, and
AMD manual asks the user to always intercept it
(otherwise result is undefined).
The resulting VM exit, does have an error code.
Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Message-Id: <20210225154135.405125-2-mlevitsk@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 8173396e
...@@ -545,8 +545,6 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, ...@@ -545,8 +545,6 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) { if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) {
queue: queue:
if (has_error && !is_protmode(vcpu))
has_error = false;
if (reinject) { if (reinject) {
/* /*
* On vmentry, vcpu->arch.exception.pending is only * On vmentry, vcpu->arch.exception.pending is only
...@@ -8367,6 +8365,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) ...@@ -8367,6 +8365,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
static_call(kvm_x86_update_cr8_intercept)(vcpu, tpr, max_irr); static_call(kvm_x86_update_cr8_intercept)(vcpu, tpr, max_irr);
} }
int kvm_check_nested_events(struct kvm_vcpu *vcpu) int kvm_check_nested_events(struct kvm_vcpu *vcpu)
{ {
if (WARN_ON_ONCE(!is_guest_mode(vcpu))) if (WARN_ON_ONCE(!is_guest_mode(vcpu)))
...@@ -8380,6 +8379,13 @@ int kvm_check_nested_events(struct kvm_vcpu *vcpu) ...@@ -8380,6 +8379,13 @@ int kvm_check_nested_events(struct kvm_vcpu *vcpu)
return kvm_x86_ops.nested_ops->check_events(vcpu); return kvm_x86_ops.nested_ops->check_events(vcpu);
} }
static void kvm_inject_exception(struct kvm_vcpu *vcpu)
{
if (vcpu->arch.exception.error_code && !is_protmode(vcpu))
vcpu->arch.exception.error_code = false;
static_call(kvm_x86_queue_exception)(vcpu);
}
static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit) static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
{ {
int r; int r;
...@@ -8388,7 +8394,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit ...@@ -8388,7 +8394,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit
/* try to reinject previous events if any */ /* try to reinject previous events if any */
if (vcpu->arch.exception.injected) { if (vcpu->arch.exception.injected) {
static_call(kvm_x86_queue_exception)(vcpu); kvm_inject_exception(vcpu);
can_inject = false; can_inject = false;
} }
/* /*
...@@ -8451,7 +8457,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit ...@@ -8451,7 +8457,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit
} }
} }
static_call(kvm_x86_queue_exception)(vcpu); kvm_inject_exception(vcpu);
can_inject = false; can_inject = false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment