From: Miguel Landaeta Subject: vmm(4): return error for VMCALL instead of injecting #UD To: tech@openbsd.org Date: Mon, 16 Mar 2026 11:51:00 +0000 Hi, Linux guests panic during boot when executing VMCALL. vmm(4) currently injects #UD for this unsupported instruction. Linux identifies the hypervisor as KVM and issues VMCALL during ptp_kvm initialization, which results in the panic. Return an error for VMCALL instead of injecting #UD so the guest can continue booting. Linux then reports: [ 0.929350] fail to initialize ptp_kvm instead of crashing with a panic (see more details below). Index: sys/arch/amd64/amd64/vmm_machdep.c =================================================================== RCS file: /home/cvs/src/sys/arch/amd64/amd64/vmm_machdep.c,v diff -u -p -u -p -r1.72 vmm_machdep.c --- sys/arch/amd64/amd64/vmm_machdep.c 16 Feb 2026 15:08:41 -0000 1.72 +++ sys/arch/amd64/amd64/vmm_machdep.c 16 Mar 2026 10:40:24 -0000 @@ -4300,9 +4300,11 @@ svm_handle_exit(struct vcpu *vcpu) if (guest_cpl == 0 && vcpu->vc_gueststate.vg_rax == HVCALL_FORCED_ABORT) return (EINVAL); - DPRINTF("SVM_VMEXIT_VMMCALL at cpl=%d\n", guest_cpl); - ret = vmm_inject_ud(vcpu); - update_rip = 0; + DPRINTF("SVM_VMEXIT_VMMCALL: unsupported cpl=%d rax=0x%llx\n", + guest_cpl, vcpu->vc_gueststate.vg_rax); + vcpu->vc_gueststate.vg_rax = -1; + vcpu->vc_gueststate.vg_rip += 3; /* VMMCALL is 3 bytes long */ + update_rip = 1; break; default: DPRINTF("%s: unhandled exit 0x%llx (pa=0x%llx)\n", __func__, @@ -4740,9 +4742,11 @@ vmx_handle_exit(struct vcpu *vcpu) if (guest_cpl == 0 && vcpu->vc_gueststate.vg_rax == HVCALL_FORCED_ABORT) return (EINVAL); - DPRINTF("VMX_EXIT_VMCALL at cpl=%d\n", guest_cpl); - ret = vmm_inject_ud(vcpu); - update_rip = 0; + DPRINTF("VMX_EXIT_VMMCALL: unsupported cpl=%d rax=0x%llx\n", + guest_cpl, vcpu->vc_gueststate.vg_rax); + vcpu->vc_gueststate.vg_rax = -1; + vcpu->vc_gueststate.vg_rip += 3; /* VMCALL is 3 bytes long */ + update_rip = 1; break; default: #ifdef VMM_DEBUG Does this approach make sense, or is there a better way to handle this? As workaround, Linux can be booted with: clearcpuid=hypervisor kvm.ignore_msrs=1 which avoids the panic, but requiring guest kernel parameters is not ideal. For reference, Linux appears to handle KVM hypercall failures as shown in: 1. https://github.com/torvalds/linux/blob/v6.18/drivers/ptp/ptp_kvm_x86.c#L53 2. https://github.com/torvalds/linux/blob/v6.18/drivers/ptp/ptp_kvm_common.c#L143 Linux guest panic when booted without the patch above: [ 0.000000] Linux version 6.18.15-talos (root@buildkitsandbox) (gcc (GCC) 15.2.0, GNU ld (GNU Binutils) 2.45.1) #1 SMP Fri Mar 6 11:34:33 UTC 2026 [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz talos.platform=metal console=tty0 talos.halt_if_installed=1 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 console=ttyS0,115200 [...] [ 0.000000] SMBIOS 2.4 present. [ 0.000000] DMI: OpenBSD VMM, BIOS 1.16.3p1-OpenBSD-vmm 01/01/2011 [ 0.000000] DMI: Memory slots populated: 1/1 [ 0.000000] Hypervisor detected: KVM [...] [ 0.022656] Booting paravirtualized kernel on KVM [...] [ 0.037399] Kernel command line: BOOT_IMAGE=/boot/vmlinuz talos.platform=metal console=tty0 talos.halt_if_installed=1 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 console=ttyS0,115200 [ 0.037587] Unknown kernel command line parameters "selinux=1", will be passed to user space. [...] [ 0.233244] smp: Bringing up secondary CPUs ... [ 0.233244] smp: Brought up 1 node, 1 CPU [ 0.233244] smpboot: Total of 1 processors activated (3792.00 BogoMIPS) [ 0.233244] Memory: 1898132K/2096676K available (29489K kernel code, 6160K rwdata, 17284K rodata, 6196K init, 3956K bss, 188712K reserved, 0K cma-reserved) [ 0.363301] kvm_intel: VMX not supported by CPU 0 [...] [ 0.983920] Oops: invalid opcode: 0000 [#1] SMP PTI [ 0.983920] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.15-talos #1 NONE [ 0.983920] Hardware name: OpenBSD VMM, BIOS 1.16.3p1-OpenBSD-vmm 01/01/2011 [ 0.983920] RIP: 0010:kvm_arch_ptp_init+0x5f/0x120 [ 0.983920] Code: c7 c7 c0 ca 99 b1 e8 40 e4 ff fe 48 89 05 29 46 09 03 e8 c4 9c fe fe 48 85 c0 74 2b 48 8b 1d 18 46 09 03 b8 09 00 00 00 31 c9 <0f> 01 c1 48 3d 18 fc ff ff 74 12 48 83 c4 08 5b 31 d2 31 c9 31 f6 [ 0.983920] RSP: 0000:ffffcd1f0000bda8 EFLAGS: 00000246 [ 0.983920] RAX: 0000000000000009 RBX: 000000007c99cac0 RCX: 0000000000000000 [ 0.983920] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 0.983920] RBP: ffffcd1f0000bdd0 R08: 0000000000000000 R09: 0000000000000000 [ 0.983920] R10: 0000000000000000 R11: 0000000000000000 R12: ffffcd1f0000bde0 [ 0.983920] R13: ffffffffb12f4f80 R14: 00000000000000ee R15: ffffffffb15529a0 [ 0.983920] FS: 0000000000000000(0000) GS:ffff8c4f8c425000(0000) knlGS:0000000000000000 [ 0.983920] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050013 [ 0.983920] CR2: ffff8c4f3cc01000 CR3: 000000007b466000 CR4: 00000000003506b0 [ 0.983920] Call Trace: [ 0.983920] [ 0.983920] ptp_kvm_init+0x2c/0x160 [ 0.983920] do_one_initcall+0x5b/0x2f0 [ 0.983920] kernel_init_freeable+0x3dd/0x490 [ 0.983920] ? __pfx_kernel_init+0x10/0x10 [ 0.983920] kernel_init+0x1e/0x170 [ 0.983920] ? __pfx_kernel_init+0x10/0x10 [ 0.983920] ret_from_fork+0x126/0x170 [ 0.983920] ? __pfx_kernel_init+0x10/0x10 [ 0.983920] ret_from_fork_asm+0x1a/0x30 [ 0.983920] [ 0.983920] Modules linked in: [ 1.021270] ---[ end trace 0000000000000000 ]--- [ 1.022379] RIP: 0010:kvm_arch_ptp_init+0x5f/0x120 [ 1.023526] Code: c7 c7 c0 ca 99 b1 e8 40 e4 ff fe 48 89 05 29 46 09 03 e8 c4 9c fe fe 48 85 c0 74 2b 48 8b 1d 18 46 09 03 b8 09 00 00 00 31 c9 <0f> 01 c1 48 3d 18 fc ff ff 74 12 48 83 c4 08 5b 31 d2 31 c9 31 f6 [ 1.025240] RSP: 0000:ffffcd1f0000bda8 EFLAGS: 00000246 [ 1.025240] RAX: 0000000000000009 RBX: 000000007c99cac0 RCX: 0000000000000000 [ 1.025240] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 1.025240] RBP: ffffcd1f0000bdd0 R08: 0000000000000000 R09: 0000000000000000 [ 1.025240] R10: 0000000000000000 R11: 0000000000000000 R12: ffffcd1f0000bde0 [ 1.025240] R13: ffffffffb12f4f80 R14: 00000000000000ee R15: ffffffffb15529a0 [ 1.025240] FS: 0000000000000000(0000) GS:ffff8c4f8c425000(0000) knlGS:0000000000000000 [ 1.025240] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050013 [ 1.025240] CR2: ffff8c4f3cc01000 CR3: 000000007b466000 CR4: 00000000003506b0 [ 1.025240] Kernel panic - not syncing: Fatal exception [ 1.025240] Kernel Offset: 0x2c400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) To reproduce: vmctl start -c -m 2G -L -i 1 -r metal-amd64.iso -d disk.qcow2 talos ISO image: https://github.com/siderolabs/talos/releases/download/v1.12.5/metal-amd64.iso Thanks! Miguel