Skip to content

Commit b7c4145

Browse files
committed
KVM: Don't spin on virt instruction faults during reboot
Since vmx blocks INIT signals, we disable virtualization extensions during reboot. This leads to virtualization instructions faulting; we trap these faults and spin while the reboot continues. Unfortunately spinning on a non-preemptible kernel may block a task that reboot depends on; this causes the reboot to hang. Fix by skipping over the instruction and hoping for the best. Signed-off-by: Avi Kivity <[email protected]>
1 parent 4cc7031 commit b7c4145

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,14 +786,18 @@ enum {
786786
* reboot turns off virtualization while processes are running.
787787
* Trap the fault and ignore the instruction if that happens.
788788
*/
789-
asmlinkage void kvm_handle_fault_on_reboot(void);
789+
asmlinkage void kvm_spurious_fault(void);
790+
extern bool kvm_rebooting;
790791

791792
#define __kvm_handle_fault_on_reboot(insn) \
792793
"666: " insn "\n\t" \
794+
"668: \n\t" \
793795
".pushsection .fixup, \"ax\" \n" \
794796
"667: \n\t" \
797+
"cmpb $0, kvm_rebooting \n\t" \
798+
"jne 668b \n\t" \
795799
__ASM_SIZE(push) " $666b \n\t" \
796-
"jmp kvm_handle_fault_on_reboot \n\t" \
800+
"call kvm_spurious_fault \n\t" \
797801
".popsection \n\t" \
798802
".pushsection __ex_table, \"a\" \n\t" \
799803
_ASM_PTR " 666b, 667b \n\t" \

virt/kvm/kvm_main.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ static void hardware_disable_all(void);
9090

9191
static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
9292

93-
static bool kvm_rebooting;
93+
bool kvm_rebooting;
94+
EXPORT_SYMBOL_GPL(kvm_rebooting);
9495

9596
static bool largepages_enabled = true;
9697

@@ -2171,18 +2172,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
21712172
}
21722173

21732174

2174-
asmlinkage void kvm_handle_fault_on_reboot(void)
2175+
asmlinkage void kvm_spurious_fault(void)
21752176
{
2176-
if (kvm_rebooting) {
2177-
/* spin while reset goes on */
2178-
local_irq_enable();
2179-
while (true)
2180-
cpu_relax();
2181-
}
21822177
/* Fault while not rebooting. We want the trace. */
21832178
BUG();
21842179
}
2185-
EXPORT_SYMBOL_GPL(kvm_handle_fault_on_reboot);
2180+
EXPORT_SYMBOL_GPL(kvm_spurious_fault);
21862181

21872182
static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
21882183
void *v)

0 commit comments

Comments
 (0)