]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.170/kvm-x86-use-jmp-to-invoke-kvm_spurious_fault-from-.fixup.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.4.170 / kvm-x86-use-jmp-to-invoke-kvm_spurious_fault-from-.fixup.patch
CommitLineData
3eb3a557
GKH
1From e81434995081fd7efb755fd75576b35dbb0850b1 Mon Sep 17 00:00:00 2001
2From: Sean Christopherson <sean.j.christopherson@intel.com>
3Date: Thu, 20 Dec 2018 14:21:08 -0800
4Subject: KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup
5
6From: Sean Christopherson <sean.j.christopherson@intel.com>
7
8commit e81434995081fd7efb755fd75576b35dbb0850b1 upstream.
9
10____kvm_handle_fault_on_reboot() provides a generic exception fixup
11handler that is used to cleanly handle faults on VMX/SVM instructions
12during reboot (or at least try to). If there isn't a reboot in
13progress, ____kvm_handle_fault_on_reboot() treats any exception as
14fatal to KVM and invokes kvm_spurious_fault(), which in turn generates
15a BUG() to get a stack trace and die.
16
17When it was originally added by commit 4ecac3fd6dc2 ("KVM: Handle
18virtualization instruction #UD faults during reboot"), the "call" to
19kvm_spurious_fault() was handcoded as PUSH+JMP, where the PUSH'd value
20is the RIP of the faulting instructing.
21
22The PUSH+JMP trickery is necessary because the exception fixup handler
23code lies outside of its associated function, e.g. right after the
24function. An actual CALL from the .fixup code would show a slightly
25bogus stack trace, e.g. an extra "random" function would be inserted
26into the trace, as the return RIP on the stack would point to no known
27function (and the unwinder will likely try to guess who owns the RIP).
28
29Unfortunately, the JMP was replaced with a CALL when the macro was
30reworked to not spin indefinitely during reboot (commit b7c4145ba2eb
31"KVM: Don't spin on virt instruction faults during reboot"). This
32causes the aforementioned behavior where a bogus function is inserted
33into the stack trace, e.g. my builds like to blame free_kvm_area().
34
35Revert the CALL back to a JMP. The changelog for commit b7c4145ba2eb
36("KVM: Don't spin on virt instruction faults during reboot") contains
37nothing that indicates the switch to CALL was deliberate. This is
38backed up by the fact that the PUSH <insn RIP> was left intact.
39
40Note that an alternative to the PUSH+JMP magic would be to JMP back
41to the "real" code and CALL from there, but that would require adding
42a JMP in the non-faulting path to avoid calling kvm_spurious_fault()
43and would add no value, i.e. the stack trace would be the same.
44
45Using CALL:
46
47------------[ cut here ]------------
48kernel BUG at /home/sean/go/src/kernel.org/linux/arch/x86/kvm/x86.c:356!
49invalid opcode: 0000 [#1] SMP
50CPU: 4 PID: 1057 Comm: qemu-system-x86 Not tainted 4.20.0-rc6+ #75
51Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
52RIP: 0010:kvm_spurious_fault+0x5/0x10 [kvm]
53Code: <0f> 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 55 49 89 fd 41
54RSP: 0018:ffffc900004bbcc8 EFLAGS: 00010046
55RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffffffffff
56RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
57RBP: ffff888273fd8000 R08: 00000000000003e8 R09: 0000000000000000
58R10: 0000000000000000 R11: 0000000000000784 R12: ffffc90000371fb0
59R13: 0000000000000000 R14: 000000026d763cf4 R15: ffff888273fd8000
60FS: 00007f3d69691700(0000) GS:ffff888277800000(0000) knlGS:0000000000000000
61CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
62CR2: 000055f89bc56fe0 CR3: 0000000271a5a001 CR4: 0000000000362ee0
63Call Trace:
64 free_kvm_area+0x1044/0x43ea [kvm_intel]
65 ? vmx_vcpu_run+0x156/0x630 [kvm_intel]
66 ? kvm_arch_vcpu_ioctl_run+0x447/0x1a40 [kvm]
67 ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm]
68 ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm]
69 ? __set_task_blocked+0x38/0x90
70 ? __set_current_blocked+0x50/0x60
71 ? __fpu__restore_sig+0x97/0x490
72 ? do_vfs_ioctl+0xa1/0x620
73 ? __x64_sys_futex+0x89/0x180
74 ? ksys_ioctl+0x66/0x70
75 ? __x64_sys_ioctl+0x16/0x20
76 ? do_syscall_64+0x4f/0x100
77 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
78Modules linked in: vhost_net vhost tap kvm_intel kvm irqbypass bridge stp llc
79---[ end trace 9775b14b123b1713 ]---
80
81Using JMP:
82
83------------[ cut here ]------------
84kernel BUG at /home/sean/go/src/kernel.org/linux/arch/x86/kvm/x86.c:356!
85invalid opcode: 0000 [#1] SMP
86CPU: 6 PID: 1067 Comm: qemu-system-x86 Not tainted 4.20.0-rc6+ #75
87Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
88RIP: 0010:kvm_spurious_fault+0x5/0x10 [kvm]
89Code: <0f> 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 55 49 89 fd 41
90RSP: 0018:ffffc90000497cd0 EFLAGS: 00010046
91RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffffffffff
92RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
93RBP: ffff88827058bd40 R08: 00000000000003e8 R09: 0000000000000000
94R10: 0000000000000000 R11: 0000000000000784 R12: ffffc90000369fb0
95R13: 0000000000000000 R14: 00000003c8fc6642 R15: ffff88827058bd40
96FS: 00007f3d7219e700(0000) GS:ffff888277900000(0000) knlGS:0000000000000000
97CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
98CR2: 00007f3d64001000 CR3: 0000000271c6b004 CR4: 0000000000362ee0
99Call Trace:
100 vmx_vcpu_run+0x156/0x630 [kvm_intel]
101 ? kvm_arch_vcpu_ioctl_run+0x447/0x1a40 [kvm]
102 ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm]
103 ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm]
104 ? __set_task_blocked+0x38/0x90
105 ? __set_current_blocked+0x50/0x60
106 ? __fpu__restore_sig+0x97/0x490
107 ? do_vfs_ioctl+0xa1/0x620
108 ? __x64_sys_futex+0x89/0x180
109 ? ksys_ioctl+0x66/0x70
110 ? __x64_sys_ioctl+0x16/0x20
111 ? do_syscall_64+0x4f/0x100
112 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
113Modules linked in: vhost_net vhost tap kvm_intel kvm irqbypass bridge stp llc
114---[ end trace f9daedb85ab3ddba ]---
115
116Fixes: b7c4145ba2eb ("KVM: Don't spin on virt instruction faults during reboot")
117Cc: stable@vger.kernel.org
118Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
119Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
120Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
121
122---
123 arch/x86/include/asm/kvm_host.h | 2 +-
124 1 file changed, 1 insertion(+), 1 deletion(-)
125
126--- a/arch/x86/include/asm/kvm_host.h
127+++ b/arch/x86/include/asm/kvm_host.h
128@@ -1200,7 +1200,7 @@ asmlinkage void kvm_spurious_fault(void)
129 "cmpb $0, kvm_rebooting \n\t" \
130 "jne 668b \n\t" \
131 __ASM_SIZE(push) " $666b \n\t" \
132- "call kvm_spurious_fault \n\t" \
133+ "jmp kvm_spurious_fault \n\t" \
134 ".popsection \n\t" \
135 _ASM_EXTABLE(666b, 667b)
136