tests/tcg/s390x: Test PRNO TRNG interruptibility
Add a small test that issues a large PRNO TRNG request while a timer is running, and checks that the timer interrupts it several times. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260714191948.342204-3-iii@linux.ibm.com Signed-off-by: Eric Farman <farman@linux.ibm.com>
Ilya Leoshkevich committed
Jul 14, 2026 at 21:17 UTC
abe1d893f41d5fcbdabc22f46ec148069a4ef319
2 files changed
+68
tests/tcg/s390x/Makefile.target
+1
@@ -75,6 +75,7 @@ Z13_TESTS+=vcksm
75
Z13_TESTS+=vstl
76
Z13_TESTS+=vrep
77
Z13_TESTS+=precise-smc-user
78
+Z13_TESTS+=prno-trng
79
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
80
TESTS+=$(Z13_TESTS)
81
tests/tcg/s390x/prno-trng.c
new
+67
@@ -0,0 +1,67 @@
1
+/*
2
+ * Test that PERFORM RANDOM NUMBER OPERATION TRNG is interruptible.
3
+ *
4
+ * SPDX-License-Identifier: GPL-2.0-or-later
5
+ */
6
+#include <assert.h>
7
+#include <signal.h>
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <string.h>
11
+#include <sys/time.h>
12
+#include <asm/ucontext.h>
13
+
14
+static unsigned char buf1[16 * 1024 * 1024];
15
+static unsigned char buf2[16 * 1024 * 1024];
16
+
17
+static volatile sig_atomic_t interrupted;
18
+
19
+static void sigprof_handler(int sig, siginfo_t *info, void *ucontext)
20
+{
21
+ struct ucontext *uc = ucontext;
22
+ unsigned long addr = uc->uc_mcontext.regs.psw.addr;
23
+
24
+ if (*(unsigned short *)(addr - 4) == 0xb93c) {
25
+ interrupted++;
26
+ }
27
+}
28
+
29
+static void prno_trng(void *b1, unsigned long l1, void *b2, unsigned long l2)
30
+{
31
+ register unsigned long r0 asm("r0") = 114; /* TRNG */
32
+ register unsigned long r2 asm("r2") = (unsigned long)b1;
33
+ register unsigned long r3 asm("r3") = l1;
34
+ register unsigned long r4 asm("r4") = (unsigned long)b2;
35
+ register unsigned long r5 asm("r5") = l2;
36
+
37
+ asm volatile("0: ppno %[r2],%[r4]\n" /* prno alias for old toolchains */
38
+ " jo 0b"
39
+ : [r2] "+r" (r2), [r3] "+r" (r3)
40
+ , [r4] "+r" (r4), [r5] "+r" (r5)
41
+ : "r" (r0)
42
+ : "cc", "memory");
43
+}
44
+
45
+int main(void)
46
+{
47
+ struct itimerval it = {
48
+ .it_interval = { .tv_usec = 10000 }, /* 0.01s */
49
+ .it_value = { .tv_usec = 10000 },
50
+ };
51
+ struct sigaction act = {
52
+ .sa_sigaction = sigprof_handler,
53
+ .sa_flags = SA_SIGINFO,
54
+ };
55
+ int err;
56
+
57
+ err = sigaction(SIGPROF, &act, NULL);
58
+ assert(err == 0);
59
+ err = setitimer(ITIMER_PROF, &it, NULL);
60
+ assert(err == 0);
61
+
62
+ prno_trng(buf1, sizeof(buf1), buf2, sizeof(buf2));
63
+ printf("interrupted %d times\n", interrupted);
64
+ assert(interrupted >= 3);
65
+
66
+ return EXIT_SUCCESS;
67
+}