mirror of
https://github.com/openbsd/src.git
synced 2026-04-27 15:46:02 +00:00
regress: Test vmmcall raises #UD
On AMD/SVM the hypervisor will inject #UD when userland tries to execute the vmmcall instruction. Same holds for vmgexit which is encode as "rep vmmcall". On Intel/VMX vmmcall and vmgexit are invalid instructions, so the CPU will raise #UD. ok mlarkin@
This commit is contained in:
@@ -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)
|
||||
|
||||
29
regress/sys/arch/amd64/vmmcall/Makefile
Normal file
29
regress/sys/arch/amd64/vmmcall/Makefile
Normal file
@@ -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 <bsd.own.mk>
|
||||
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 <bsd.regress.mk>
|
||||
80
regress/sys/arch/amd64/vmmcall/vmmcall.c
Normal file
80
regress/sys/arch/amd64/vmmcall/vmmcall.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/* $OpenBSD: vmmcall.c,v 1.1 2026/02/16 13:08:57 hshoexer Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2025 Hans-Joerg Hoexer <hshoexer@yerbouti.franken.de>
|
||||
*
|
||||
* 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 <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user