bugzilla-daemon@bugzilla.kernel.org writes:
https://bugzilla.kernel.org/show_bug.cgi?id=205171
Bug ID: 205171 Summary: kernel panic during windows 10pro start Product: Virtualization Version: unspecified Kernel Version: 4.19.74 and higher Hardware: All OS: Linux Tree: Mainline Status: NEW Severity: normal Priority: P1 Component: kvm Assignee: virtualization_kvm@kernel-bugs.osdl.org Reporter: dront78@gmail.com Regression: No
works fine on 4.19.73
[ 5829.948945] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 [ 5829.948951] PGD 0 P4D 0 [ 5829.948954] Oops: 0002 [#1] SMP NOPTI [ 5829.948957] CPU: 3 PID: 1699 Comm: CPU 0/KVM Tainted: G OE 4.19.78-2-lts #1 [ 5829.948958] Hardware name: Micro-Star International Co., Ltd. GE62 6QF/MS-16J4, BIOS E16J4IMS.117 01/18/2018 [ 5829.948989] RIP: 0010:kvm_write_guest_virt_system+0x1e/0x40 [kvm]
It seems 4.19 stable backport is broken, upstream commit f7eea636c3d50 has:
@@ -4588,7 +4589,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu) vmx_instruction_info, true, len, &gva)) return 1; /* _system ok, nested_vmx_check_permission has verified cpl=0 */ - kvm_write_guest_virt_system(vcpu, gva, &field_value, len, NULL); + if (kvm_write_guest_virt_system(vcpu, gva, &field_value, len, &e)) + kvm_inject_page_fault(vcpu, &e); }
and it's 4.19 counterpart (73c31bd92039):
@@ -8798,8 +8799,10 @@ static int handle_vmread(struct kvm_vcpu *vcpu) vmx_instruction_info, true, &gva)) return 1; /* _system ok, nested_vmx_check_permission has verified cpl=0 */ - kvm_write_guest_virt_system(vcpu, gva, &field_value, - (is_long_mode(vcpu) ? 8 : 4), NULL); + if (kvm_write_guest_virt_system(vcpu, gva, &field_value, + (is_long_mode(vcpu) ? 8 : 4), + NULL)) + kvm_inject_page_fault(vcpu, &e); }
(note the last argument to kvm_write_guest_virt_system() - it's NULL instead of &e.
And v4.19.74 has 6e60900cfa3e (541ab2aeb282 upstream):
@@ -5016,6 +5016,13 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, /* kvm_write_guest_virt_system can pull in tons of pages. */ vcpu->arch.l1tf_flush_l1d = true;
+ /* + * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED + * is returned, but our callers are not ready for that and they blindly + * call kvm_inject_page_fault. Ensure that they at least do not leak + * uninitialized kernel stack memory into cr2 and error code. + */ + memset(exception, 0, sizeof(*exception)); return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, PFERR_WRITE_MASK, exception); }
This all results in memset(NULL). (also, 6e60900cfa3e should come *after* f7eea636c3d50 and not before but oh well..)
The following will likely fix the problem (untested):
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e83f4f6bfdac..d3a900a4fa0e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8801,7 +8801,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) /* _system ok, nested_vmx_check_permission has verified cpl=0 */ if (kvm_write_guest_virt_system(vcpu, gva, &field_value, (is_long_mode(vcpu) ? 8 : 4), - NULL)) + &e)) kvm_inject_page_fault(vcpu, &e); }
I can send a patch to stable@ if needed.