diff --git a/Makefile b/Makefile index ac9edba..a9d9e3e 100644 --- a/Makefile +++ b/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 # -----------------------------------------------------------------------