make: QEMU takes the host's KVM when there is one to take
Every qemu target spelled `-cpu qemu64,+rdtscp` and nothing asked for acceleration, so the default way to run this system was the slowest one available. That is not a small constant: without KVM, QEMU emulates each instruction in software, and on this tree `ls /bin` measured 120 ms emulated against 20 ms with KVM on identical code. Every guess about the kernel being slow has to be made against the KVM number or it is really a measurement of TCG. The flags are probed rather than assumed. /dev/kvm is absent on a host without the extension, inside another VM, and when the user is not in the kvm group -- and a hard -enable-kvm turns each of those into a QEMU that refuses to start, which is worse than a slow one. `-cpu host` only goes with KVM: it means the physical CPU, which an emulator cannot present, so the fallback keeps the old spelling exactly. qemu-kvm stays, and is now the only target that *insists*. That is what you want when the question is why the host has no /dev/kvm, rather than quietly getting a slow machine. Verified both branches on this host: `make -n qemu` expands to "-enable-kvm -cpu host" where /dev/kvm exists, and overriding QEMU_ACCEL reproduces the previous "-cpu qemu64,+rdtscp" verbatim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ad2b321d56
commit
f852ed3ed8
1 changed files with 27 additions and 4 deletions
31
Makefile
31
Makefile
|
|
@ -122,6 +122,25 @@ endif
|
|||
|
||||
QEMU = qemu-system-x86_64
|
||||
|
||||
# Hardware virtualisation, when the host has it.
|
||||
#
|
||||
# Not a micro-optimisation. Without KVM, QEMU emulates every instruction, and
|
||||
# measured on this tree that is where most of "the system feels slow" came from:
|
||||
# `ls /bin` took 120 ms emulated against 20 ms with KVM, on identical code. Every
|
||||
# guess about the kernel being at fault has to be made against the KVM number,
|
||||
# or it is really a measurement of TCG.
|
||||
#
|
||||
# Probed rather than assumed, because /dev/kvm is absent on a machine without
|
||||
# the extension, inside another VM, or when the user is not in the kvm group --
|
||||
# and a hard -enable-kvm turns each of those into a QEMU that refuses to start.
|
||||
# `-cpu host` only makes sense with KVM: it is the physical CPU, which an
|
||||
# emulator cannot present.
|
||||
ifneq ($(wildcard /dev/kvm),)
|
||||
QEMU_ACCEL = -enable-kvm -cpu host
|
||||
else
|
||||
QEMU_ACCEL = -cpu qemu64,+rdtscp
|
||||
endif
|
||||
|
||||
# Display for every QEMU target.
|
||||
#
|
||||
# virtio-gpu is what the display class binds, and what a compositor should be
|
||||
|
|
@ -463,7 +482,7 @@ ovmf: $(OVMF_CODE) $(OVMF_VARS)
|
|||
all: $(OVMF_CODE) $(OVMF_VARS)
|
||||
|
||||
qemu-uefi: esp $(BUILD)/schfs.img $(OVMF_CODE) $(OVMF_VARS)
|
||||
$(QEMU) -machine pc-i440fx-9.2 -drive if=pflash,format=raw,unit=0,readonly=on,file=$(OVMF_CODE) -drive if=pflash,format=raw,unit=1,file=$(OVMF_VARS) -drive file=fat:rw:$(BUILD)/esp,index=0,media=disk,format=raw -drive file=$(BUILD)/schfs.img,format=raw,index=1,media=disk -m 1G -smp 1 -cpu qemu64,+rdtscp -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT)
|
||||
$(QEMU) -machine pc-i440fx-9.2 -drive if=pflash,format=raw,unit=0,readonly=on,file=$(OVMF_CODE) -drive if=pflash,format=raw,unit=1,file=$(OVMF_VARS) -drive file=fat:rw:$(BUILD)/esp,index=0,media=disk,format=raw -drive file=$(BUILD)/schfs.img,format=raw,index=1,media=disk -m 1G -smp 1 $(QEMU_ACCEL) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT)
|
||||
|
||||
# Build the ramdisk-root variant. This is a target rather than just
|
||||
# "make RAMROOT=1" because toggling RAMROOT changes CFLAGS (-DRAMDISK_ROOT),
|
||||
|
|
@ -526,7 +545,7 @@ schos.iso: $(BUILD)/kernel/kernel $(BUILD)/uefi/BOOTX64.EFI sysroot-install
|
|||
# all, so a kernel that still secretly depends on one fails here rather than
|
||||
# in someone's optical drive.
|
||||
qemu-iso: schos.iso
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) -cpu qemu64,+rdtscp \
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_ACCEL) \
|
||||
-cdrom schos.iso -boot d \
|
||||
-m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
|
|
@ -901,12 +920,16 @@ OVMF_DRIVES = -drive if=pflash,format=raw,unit=0,readonly=on,file=$(OVMF_CODE) \
|
|||
-drive file=fat:rw:$(BUILD)/esp,index=0,media=disk,format=raw \
|
||||
-drive file=$(BUILD)/schfs.img,format=raw,index=1,media=disk
|
||||
|
||||
# Kept as an explicit spelling, but `make qemu` now picks KVM up on its own
|
||||
# whenever /dev/kvm exists -- see QEMU_ACCEL. This target differs only in
|
||||
# insisting on it, which is what you want when the point is to find out why the
|
||||
# host has no /dev/kvm rather than to quietly get a slow machine.
|
||||
qemu-kvm: esp $(BUILD)/schfs.img $(OVMF_CODE) $(OVMF_VARS)
|
||||
$(QEMU) -enable-kvm -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT) -cpu host \
|
||||
$(OVMF_DRIVES) -m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
qemu: esp $(BUILD)/schfs.img $(OVMF_CODE) $(OVMF_VARS)
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT) -cpu qemu64,+rdtscp \
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT) $(QEMU_ACCEL) \
|
||||
$(OVMF_DRIVES) -m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
# The root filesystem. Built from the staged sysroot; the kernel mounts it as
|
||||
|
|
@ -926,7 +949,7 @@ $(BUILD)/schfs.img: $(MKSCHFS) $(BUILD)/sysroot.stamp
|
|||
#
|
||||
# Once up: cat /proc/schfs
|
||||
qemu-schfs: esp $(BUILD)/schfs.img $(OVMF_CODE) $(OVMF_VARS)
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) -cpu qemu64,+rdtscp \
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_ACCEL) \
|
||||
$(OVMF_DRIVES) -m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue