Download raw body.
vmm(4): return error for VMCALL instead of injecting #UD
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] <TASK>
[ 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] </TASK>
[ 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
vmm(4): return error for VMCALL instead of injecting #UD