Re: [linux-4.14.y] KVM: x86: determine if an exception has an error code only when injecting it.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 29/07/21 01:08, Zubin Mithra wrote:
From: Maxim Levitsky <mlevitsk@xxxxxxxxxx>

commit b97f074583736c42fb36f2da1164e28c73758912 upstream.

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: Maxim Levitsky <mlevitsk@xxxxxxxxxx>
Message-Id: <20210225154135.405125-2-mlevitsk@xxxxxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Signed-off-by: Zubin Mithra <zsm@xxxxxxxxxxxx>
---
Backport Note:
* Syzkaller triggered a WARNING with the following stacktrace:
  WARNING: CPU: 3 PID: 3436 at arch/x86/kvm/x86.c:7529 kvm_arch_vcpu_ioctl_run+0x247/0x2dd2
  Kernel panic - not syncing: panic_on_warn set ...

  CPU: 3 PID: 3436 Comm: poc Not tainted 4.14.241-00082-gce4d1565392b #7
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
  Call Trace:
   dump_stack+0xf8/0x163
   panic+0x15a/0x2c2
   ? unregister_sha256_avx+0x1b/0x1b
   ? kvm_arch_vcpu_ioctl_run+0x247/0x2dd2
   __warn+0xe4/0x117
   ? kvm_arch_vcpu_ioctl_run+0x247/0x2dd2
   report_bug+0x93/0xdd
   fixup_bug+0x28/0x4b
   do_error_trap+0xb6/0x1b2
   ? fixup_bug+0x4b/0x4b
   ? kasan_slab_free+0x141/0x154
   ? kasan_slab_free+0xad/0x154
   ? kmem_cache_free+0x14d/0x301
   ? put_pid+0x57/0x6f
   ? kvm_vcpu_ioctl+0x214/0x73d
   ? vfs_ioctl+0x46/0x5a
   ? trace_hardirqs_off_caller+0x10c/0x115
   ? trace_hardirqs_off_thunk+0x1a/0x1c
   invalid_op+0x1b/0x40
  RIP: 0010:kvm_arch_vcpu_ioctl_run+0x247/0x2dd2

* This commit is present in linux-5.13.y.

* Conflict arises as the following commit is is not present in
linux-5.10.y and older.
- b3646477d458 ("KVM: x86: use static calls to reduce kvm_x86_ops overhead")

* Tests run: syzkaller reproducer, Chrome OS tryjobs

  arch/x86/kvm/x86.c | 13 +++++++++----
  1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 37d826acd017..d77caab7ad5e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -400,8 +400,6 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) {
  	queue:
-		if (has_error && !is_protmode(vcpu))
-			has_error = false;
  		if (reinject) {
  			/*
  			 * On vmentry, vcpu->arch.exception.pending is only
@@ -6624,13 +6622,20 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
  	kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
  }
+static void kvm_inject_exception(struct kvm_vcpu *vcpu)
+{
+       if (vcpu->arch.exception.error_code && !is_protmode(vcpu))
+               vcpu->arch.exception.error_code = false;
+       kvm_x86_ops->queue_exception(vcpu);
+}
+
  static int inject_pending_event(struct kvm_vcpu *vcpu)
  {
  	int r;
/* try to reinject previous events if any */
  	if (vcpu->arch.exception.injected) {
-		kvm_x86_ops->queue_exception(vcpu);
+		kvm_inject_exception(vcpu);
  		return 0;
  	}
@@ -6675,7 +6680,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu)
  			kvm_update_dr7(vcpu);
  		}
- kvm_x86_ops->queue_exception(vcpu);
+		kvm_inject_exception(vcpu);
  	} else if (vcpu->arch.smi_pending && !is_smm(vcpu)) {
  		vcpu->arch.smi_pending = false;
  		enter_smm(vcpu);



Acked-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux