Commit 1d518c6
KVM: LAPIC: Fix reentrancy issues with preempt notifiers
Preempt can occur in the preemption timer expiration handler:
CPU0 CPU1
preemption timer vmexit
handle_preemption_timer(vCPU0)
kvm_lapic_expired_hv_timer
hv_timer_is_use == true
sched_out
sched_in
kvm_arch_vcpu_load
kvm_lapic_restart_hv_timer
restart_apic_timer
start_hv_timer
already-expired timer or sw timer triggerd in the window
start_sw_timer
cancel_hv_timer
/* back in kvm_lapic_expired_hv_timer */
cancel_hv_timer
WARN_ON(!apic->lapic_timer.hv_timer_in_use); ==> Oops
This can be reproduced if CONFIG_PREEMPT is enabled.
------------[ cut here ]------------
WARNING: CPU: 4 PID: 2972 at /home/kernel/linux/arch/x86/kvm//lapic.c:1563 kvm_lapic_expired_hv_timer+0x9e/0xb0 [kvm]
CPU: 4 PID: 2972 Comm: qemu-system-x86 Tainted: G OE 4.13.0-rc2+ #16
RIP: 0010:kvm_lapic_expired_hv_timer+0x9e/0xb0 [kvm]
Call Trace:
handle_preemption_timer+0xe/0x20 [kvm_intel]
vmx_handle_exit+0xb8/0xd70 [kvm_intel]
kvm_arch_vcpu_ioctl_run+0xdd1/0x1be0 [kvm]
? kvm_arch_vcpu_load+0x47/0x230 [kvm]
? kvm_arch_vcpu_load+0x62/0x230 [kvm]
kvm_vcpu_ioctl+0x340/0x700 [kvm]
? kvm_vcpu_ioctl+0x340/0x700 [kvm]
? __fget+0xfc/0x210
do_vfs_ioctl+0xa4/0x6a0
? __fget+0x11d/0x210
SyS_ioctl+0x79/0x90
do_syscall_64+0x81/0x220
entry_SYSCALL64_slow_path+0x25/0x25
------------[ cut here ]------------
WARNING: CPU: 4 PID: 2972 at /home/kernel/linux/arch/x86/kvm//lapic.c:1498 cancel_hv_timer.isra.40+0x4f/0x60 [kvm]
CPU: 4 PID: 2972 Comm: qemu-system-x86 Tainted: G W OE 4.13.0-rc2+ #16
RIP: 0010:cancel_hv_timer.isra.40+0x4f/0x60 [kvm]
Call Trace:
kvm_lapic_expired_hv_timer+0x3e/0xb0 [kvm]
handle_preemption_timer+0xe/0x20 [kvm_intel]
vmx_handle_exit+0xb8/0xd70 [kvm_intel]
kvm_arch_vcpu_ioctl_run+0xdd1/0x1be0 [kvm]
? kvm_arch_vcpu_load+0x47/0x230 [kvm]
? kvm_arch_vcpu_load+0x62/0x230 [kvm]
kvm_vcpu_ioctl+0x340/0x700 [kvm]
? kvm_vcpu_ioctl+0x340/0x700 [kvm]
? __fget+0xfc/0x210
do_vfs_ioctl+0xa4/0x6a0
? __fget+0x11d/0x210
SyS_ioctl+0x79/0x90
do_syscall_64+0x81/0x220
entry_SYSCALL64_slow_path+0x25/0x25
This patch fixes it by making the caller of cancel_hv_timer, start_hv_timer
and start_sw_timer be in preemption-disabled regions, which trivially
avoid any reentrancy issue with preempt notifier.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
[Add more WARNs. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>1 parent 67fbcd6 commit 1d518c6
1 file changed
+14
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1495 | 1495 | | |
1496 | 1496 | | |
1497 | 1497 | | |
| 1498 | + | |
1498 | 1499 | | |
1499 | | - | |
1500 | 1500 | | |
1501 | 1501 | | |
1502 | | - | |
1503 | 1502 | | |
1504 | 1503 | | |
1505 | 1504 | | |
1506 | 1505 | | |
1507 | 1506 | | |
1508 | 1507 | | |
1509 | 1508 | | |
| 1509 | + | |
1510 | 1510 | | |
1511 | 1511 | | |
1512 | 1512 | | |
| |||
1538 | 1538 | | |
1539 | 1539 | | |
1540 | 1540 | | |
| 1541 | + | |
| 1542 | + | |
1541 | 1543 | | |
1542 | 1544 | | |
1543 | 1545 | | |
| |||
1552 | 1554 | | |
1553 | 1555 | | |
1554 | 1556 | | |
| 1557 | + | |
1555 | 1558 | | |
1556 | 1559 | | |
| 1560 | + | |
1557 | 1561 | | |
1558 | 1562 | | |
1559 | 1563 | | |
1560 | 1564 | | |
1561 | 1565 | | |
1562 | 1566 | | |
1563 | | - | |
| 1567 | + | |
| 1568 | + | |
| 1569 | + | |
| 1570 | + | |
1564 | 1571 | | |
1565 | 1572 | | |
1566 | 1573 | | |
| |||
1569 | 1576 | | |
1570 | 1577 | | |
1571 | 1578 | | |
| 1579 | + | |
| 1580 | + | |
1572 | 1581 | | |
1573 | 1582 | | |
1574 | 1583 | | |
| |||
1582 | 1591 | | |
1583 | 1592 | | |
1584 | 1593 | | |
| 1594 | + | |
1585 | 1595 | | |
1586 | 1596 | | |
1587 | 1597 | | |
| 1598 | + | |
1588 | 1599 | | |
1589 | 1600 | | |
1590 | 1601 | | |
| |||
0 commit comments