xref: /freebsd/tests/sys/arch/amd64/int0x80.c (revision d5728351a58b87764f3302eb8c4ca9f35e99e8b6)
1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright 2026 The FreeBSD Foundation
5  *
6  * This software were developed by
7  * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
8  * the FreeBSD Foundation.
9  */
10 
11 #include <sys/syscall.h>
12 #include <err.h>
13 #include <signal.h>
14 #include <stdatomic.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 
20 #ifndef __amd64__
21 #error "amd64 only"
22 #endif
23 
24 /*
25  * The check to see how "INT $0x80" behaves for amd64 native ABI
26  * processes.  Before bd8edba0792b71be3f8ed5dea9c22287e95c986a it
27  * executed syscalls with amd64 calling conventions.  After that
28  * revision, it should raise SIGBUS.
29  */
30 
31 static uintptr_t int0x80_loc;
32 static int signo;
33 extern char after_int0x80[];
34 
35 static void
sigill_action(int signo1,siginfo_t * si __unused,void * uctxv)36 sigill_action(int signo1, siginfo_t *si __unused, void *uctxv)
37 {
38 	ucontext_t *uctx = uctxv;
39 
40 	signo = signo1;
41 	int0x80_loc = uctx->uc_mcontext.mc_rip;
42 }
43 
44 static int
fire(void)45 fire(void)
46 {
47 	int res;
48 
49 	res = SYS_getpid;
50 	asm volatile(
51 	    ".globl\tafter_int0x80\n"
52 	    "\tint\t$0x80\n"
53 	    "after_int0x80:"
54 	    : "+a" (res)
55 	    :
56 	    : "rdx", "memory", "cc");
57 	return (res);
58 }
59 
60 int
main(void)61 main(void)
62 {
63 	struct sigaction sa;
64 	char signame[SIG2STR_MAX];
65 	int pid, res;
66 
67 	res = 0;
68 
69 	memset(&sa, 0, sizeof(sa));
70 	sa.sa_sigaction = sigill_action;
71 	sa.sa_flags = SA_SIGINFO;
72 	if (sigaction(SIGBUS, &sa, NULL) == -1)
73 		err(1, "catching SIGBUS");
74 
75 	pid = fire();
76 	atomic_signal_fence(memory_order_seq_cst);
77 	if (int0x80_loc == 0) {
78 		printf("int $0x80 does not raise SIGBUS\n");
79 		if (pid == getpid())
80 			printf("and syscall worked\n");
81 		else
82 			printf("but syscall did not worked\n");
83 		res = 1;
84 	} else {
85 		sig2str(signo, signame);
86 		printf("int $0x80 raises SIG%s\n", signame);
87 		if (int0x80_loc == (uintptr_t)after_int0x80) {
88 			printf("at expected location\n");
89 		} else {
90 			printf("not at expected location\n");
91 			res = 1;
92 		}
93 	}
94 	exit(res);
95 }
96