@samitouri / QOSamiQemu / commits / abe1d893f4

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 +}