diff --git a/regress/sys/arch/amd64/Makefile b/regress/sys/arch/amd64/Makefile index f51d0726c98..1c3d493f958 100644 --- a/regress/sys/arch/amd64/Makefile +++ b/regress/sys/arch/amd64/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.5 2026/02/16 13:05:14 hshoexer Exp $ +# $OpenBSD: Makefile,v 1.6 2026/02/16 13:08:57 hshoexer Exp $ .if ${MACHINE_ARCH} == "amd64" SUBDIR += ddb @@ -6,6 +6,7 @@ SUBDIR += dump_tables SUBDIR += fpu SUBDIR += seves_mmio SUBDIR += vmcall +SUBDIR += vmmcall SUBDIR += vmm .elif make(regress) || make(all) diff --git a/regress/sys/arch/amd64/vmmcall/Makefile b/regress/sys/arch/amd64/vmmcall/Makefile new file mode 100644 index 00000000000..3ed21b5bf40 --- /dev/null +++ b/regress/sys/arch/amd64/vmmcall/Makefile @@ -0,0 +1,29 @@ +# $OpenBSD: Makefile,v 1.1 2026/02/16 13:08:57 hshoexer Exp $ + +.if "${MACHINE_ARCH}" != amd64 +regress: + # MACHINE_ARCH is not amd64 + @echo SKIPPED +.else + +PROGS = vmmcall +WARNINGS = yes + +REGRESS_TARGETS = run-regress-vmmcall +run-regress-vmmcall: vmmcall + ./vmmcall vmmcall + ./vmmcall vmgexit + +.if ! (make(clean) || make(cleandir) || make(obj)) +.include +VMMODE != /sbin/sysctl -n machdep.vmmode +HYPVERVISOR!= /sbin/sysctl -n hw.vendor + +# Only run test on vmm(4) guests +.if "${VMMODE}" == "host" || "${HYPVERVISOR}" != "OpenBSD" +REGRESS_SKIP_TARGETS = ${REGRESS_TARGETS} +.endif +.endif +.endif + +.include diff --git a/regress/sys/arch/amd64/vmmcall/vmmcall.c b/regress/sys/arch/amd64/vmmcall/vmmcall.c new file mode 100644 index 00000000000..34f99e3d294 --- /dev/null +++ b/regress/sys/arch/amd64/vmmcall/vmmcall.c @@ -0,0 +1,80 @@ +/* $OpenBSD: vmmcall.c,v 1.1 2026/02/16 13:08:57 hshoexer Exp $ */ +/* + * Copyright (c) 2025 Hans-Joerg Hoexer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +static void +handler(int sig, siginfo_t *sip, void *ctx) +{ + printf("signo %d, code %d, errno %d\n", sip->si_signo, sip->si_code, + sip->si_errno); + if (sig != SIGILL) + errx(1, "expected SIGILL: %d", sig); + if (sip->si_code != ILL_PRVOPC) + errx(1, "expected ILL_PRVOPC: %d", sip->si_code); + + exit(0); +} + +__dead static void +usage(void) +{ + fprintf(stderr, "usage: %s vmmcall | vmgexit\n", + getprogname()); + exit(2); +} + +int +main(int argc, char **argv) +{ + struct sigaction sa; + int n; + + if (argc != 2) + usage(); + + if (strcmp(argv[1], "vmmcall") == 0) + n = 0; + else if (strcmp(argv[1], "vmgexit") == 0) + n = 1; + else + usage(); + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGILL, &sa, NULL) == -1) + err(2, "sigaction"); + + switch (n) { + case 0: + asm volatile("vmmcall"); + break; + case 1: + /* vmgexit is encode as "rep; vmmcall" */ + asm volatile("rep; vmmcall"); + break; + } + + errx(1, "expected signal"); + + return (0); +}