From a6fabfb78e70b8096a8bf336aa64a3358a2f5eca Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Mon, 22 Jul 2024 21:48:03 +0200
Subject: tests: check if SSE registers are preserved on context switches

---
 src/cmd/tests/kernel/misc.c | 10 ++++++++++
 src/cmd/tests/kernel/misc.s | 27 +++++++++++++++++++++++++++
 src/cmd/tests/tests.c       | 12 +++++++-----
 3 files changed, 44 insertions(+), 5 deletions(-)
 create mode 100644 src/cmd/tests/kernel/misc.s

(limited to 'src/cmd')

diff --git a/src/cmd/tests/kernel/misc.c b/src/cmd/tests/kernel/misc.c
index 7fc0866..d25e3dd 100644
--- a/src/cmd/tests/kernel/misc.c
+++ b/src/cmd/tests/kernel/misc.c
@@ -60,8 +60,18 @@ static void test_invalid_syscall(void) {
 	test(_syscall(~0, 0, 0, 0, 0, 0) < 0);
 }
 
+extern void _sse_test(void *a);
+static void test_sse_restore(void) {
+	char buf[128] = "Hello world";
+	char buf2[128];
+	memcpy(buf2, buf, 128);
+	_sse_test(&buf);
+	test(memcmp(buf, buf2, 128) == 0);
+}
+
 void r_k_misc(void) {
 	run_test(test_fault_kill);
 	run_test(test_efault);
 	run_test(test_invalid_syscall);
+	run_test(test_sse_restore);
 }
diff --git a/src/cmd/tests/kernel/misc.s b/src/cmd/tests/kernel/misc.s
new file mode 100644
index 0000000..ae1b567
--- /dev/null
+++ b/src/cmd/tests/kernel/misc.s
@@ -0,0 +1,27 @@
+.section .text
+.global _sse_test
+.type _sse_test, @function
+
+/* Written in assembly to ensure gcc won't mess with the XMM registers */
+_sse_test:
+	movdqu (%rdi), %xmm1
+	push %rdi /* preserve */
+
+	call fork
+	cmp $0, %rax
+	je child
+
+	/* in parent - wait for the child to die */
+	mov %rax, %rdi
+	mov $0, %rsi
+	mov $0, %rdx
+	call _sys_wait2
+
+	pop %rdi
+	movdqu %xmm1, (%rdi)
+	ret
+
+child:
+	pxor %xmm1, %xmm1
+	mov $0, %rdi
+	call _sys_exit
diff --git a/src/cmd/tests/tests.c b/src/cmd/tests/tests.c
index 2b66b43..debd095 100644
--- a/src/cmd/tests/tests.c
+++ b/src/cmd/tests/tests.c
@@ -21,7 +21,7 @@ void run_test_inner(void (*fn)(), const char *s) {
 		if (waitpid(pid, &status, 0) != pid) {
 			test_failf("%s", "waitpid returned something weird");
 		} else if (WEXITSTATUS(status) != 0) {
-			test_failf("%s exited with %d", s, WEXITSTATUS(status));
+			test_failf("%s exited with %d, pid %d", s, WEXITSTATUS(status), pid);
 		}
 	}
 }
@@ -62,13 +62,15 @@ int main(void) {
 		r_s_ringbuf();
 		exit(0);
 	} else {
-		for (;;) {
+		for (int i = 0; ; i++) {
 			char buf[128];
 			long ret = _sys_read(reader, buf, sizeof buf, 0);
 			if (ret < 0) break;
-			printf("\033[31mFAIL\033[0m ");
-			fwrite(buf, ret, 1, stdout);
-			printf("\n");
+			printf("\033[31mFAIL\033[0m %3d %.*s\n", i, (int)ret, buf);
+			if (i == 100) {
+				printf("quitting due to too many errors\n");
+				break;
+			}
 		}
 	}
 	return 0;
-- 
cgit v1.2.3