assembly: 0.960 i386: 0.932 architecture: 0.890 kernel: 0.854 debug: 0.842 x86: 0.836 device: 0.808 ppc: 0.803 graphic: 0.744 socket: 0.738 arm: 0.729 files: 0.714 KVM: 0.663 vnc: 0.656 PID: 0.623 boot: 0.619 network: 0.609 permissions: 0.605 peripherals: 0.595 performance: 0.566 risc-v: 0.561 hypervisor: 0.551 semantic: 0.550 register: 0.538 virtual: 0.454 VMM: 0.370 user-level: 0.312 mistranslation: 0.301 TCG: 0.276 -------------------- i386: 0.991 assembly: 0.979 x86: 0.973 TCG: 0.610 debug: 0.429 virtual: 0.365 boot: 0.181 kernel: 0.090 performance: 0.087 KVM: 0.066 PID: 0.055 hypervisor: 0.048 files: 0.047 socket: 0.045 register: 0.039 device: 0.031 architecture: 0.030 semantic: 0.027 vnc: 0.022 user-level: 0.009 network: 0.006 VMM: 0.006 permissions: 0.003 risc-v: 0.003 graphic: 0.003 peripherals: 0.002 ppc: 0.001 mistranslation: 0.001 arm: 0.000 QEMU crashes when an interrupt is triggered whose descriptor is not in physical memory Description of problem: When an interrupt is triggered whose descriptor is mapped but not in physical memory, QEMU crashes with the following message: ``` ** ERROR:../system/cpus.c:524:bql_lock_impl: assertion failed: (!bql_locked()) Bail out! ERROR:../system/cpus.c:524:bql_lock_impl: assertion failed: (!bql_locked()) Aborted (core dumped) ``` The given code triggers the bug by moving the IDT's base address, but it can also be triggered by any other method of moving the IDT's physical memory location, f.ex paging. With KVM enabled, this specific example loops forever instead of crashing, but if the code is altered to use paging, an internal KVM error is reported and the VM is paused. Steps to reproduce: 1. Assemble the code listed below using NASM: `nasm test.asm -o test.bin` 2. Run the code using `qemu-system-i386 -drive format=raw,file=test.bin`. Note that the given code only triggers the bug if the guest has 2 gigabytes or less of physical memory. 3. QEMU crashes. Additional information: NASM assembly of the code used: ``` bits 16 org 0x7c00 _start: ; Disable interrupts and load new IDT cli o32 lidt [idtdesc] ; Descriptor for INT 0 is in nonexistent physical memory, which crashes QEMU. int 0x00 idtdesc: dw 0x3ff ; Limit: 1 KiB for IDT dd 0x80000000 ; Base: 2 GiB ; Like most BIOSes, SeaBIOS requires this magic number to boot times 510-($-$$) db 0 dw 0xaa55 ```