1 /*
2 * Check decoding of s390_pci_mmio_read and s390_pci_mmio_write syscalls.
3 *
4 * Copyright (c) 2018-2021 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "scno.h"
12
13 #if defined __NR_s390_pci_mmio_read && defined __NR_s390_pci_mmio_write
14
15 # include <errno.h>
16 # include <stdint.h>
17 # include <stdio.h>
18 # include <unistd.h>
19
20 static void
21 do_call(bool wr, kernel_ulong_t mmio_addr, kernel_ulong_t buf,
22 kernel_ulong_t len, bool buf_valid, const char *buf_str)
23 {
24 long saved_errno = 0;
25 long rc = 0;
26
27 printf("s390_pci_mmio_%s(%#llx, ", wr ? "write" : "read",
28 (unsigned long long) mmio_addr);
29
30 if (!wr) {
31 rc = syscall(__NR_s390_pci_mmio_read, mmio_addr, buf, len);
32 saved_errno = errno;
33 }
34
35 if (buf_valid && !rc) {
36 char *buf_ptr = (char *) (uintptr_t) buf;
37
38 print_quoted_hex(buf_ptr,
39 len > DEFAULT_STRLEN ? DEFAULT_STRLEN : len);
40
41 if (len > DEFAULT_STRLEN)
42 printf("...");
43 } else {
44 if (buf_str)
45 printf("%s", buf_str);
46 else
47 printf("%#llx", (unsigned long long) buf);
48 }
49
50 printf(", %llu) = ", (unsigned long long) len);
51
52 if (wr)
53 rc = syscall(__NR_s390_pci_mmio_write, mmio_addr, buf, len);
54 else
55 errno = saved_errno;
56
57 puts(sprintrc(rc));
58 }
59
60 int
61 main(void)
62 {
63 static const size_t buf_size = DEFAULT_STRLEN + 10;
64
65 char *buf = tail_alloc(buf_size);
66
67 bool bools[] = { true, false };
68
69 kernel_ulong_t addrs[] = {
70 0,
71 (kernel_ulong_t) 0xdeafbeefdeadc0deULL,
72 };
73
74 struct {
75 kernel_ulong_t buf;
76 const char *str;
77 size_t size;
78 } bufs[] = {
79 { (kernel_ulong_t) ARG_STR(NULL), 0 },
80 { (kernel_ulong_t) (buf + buf_size), NULL, 0 },
81 { (kernel_ulong_t) (buf), NULL, buf_size },
82 { (kernel_ulong_t) (buf + 9), NULL, buf_size - 9 },
83 { (kernel_ulong_t) (buf + 10), NULL, buf_size - 10 },
84 { (kernel_ulong_t) (buf + 16), NULL, buf_size - 16 },
85 { (kernel_ulong_t) (buf + 26), NULL, buf_size - 26 },
86 { (kernel_ulong_t) (buf + 28), NULL, buf_size - 28 },
87 };
88
89 kernel_ulong_t sizes[] = {
90 0,
91 DEFAULT_STRLEN / 2,
92 DEFAULT_STRLEN - 10,
93 DEFAULT_STRLEN,
94 DEFAULT_STRLEN + 1,
95 buf_size,
96 buf_size + 10,
97 (kernel_ulong_t) 0xfacefeedac0ffeedULL,
98 };
99
100 unsigned int ctr = 0;
101
102 for (unsigned int i = 0;
103 i < ARRAY_SIZE(addrs); ++i) {
104 for (unsigned int j = 0;
105 j < ARRAY_SIZE(bufs); ++j) {
106 for (unsigned int k = 0;
107 k < ARRAY_SIZE(sizes); ++k) {
108 for (unsigned int l = 0;
109 l < ARRAY_SIZE(bools); ++l) {
110 bool valid = bufs[j].buf &&
111 bufs[j].size >=
112 MIN(sizes[k],
113 DEFAULT_STRLEN + 1);
114
115 if (bufs[j].size && bools[l])
116 fill_memory_ex((char *) buf,
117 bufs[j].size,
118 0xC0 + ctr, 255);
119
120 do_call(bools[l], addrs[i], bufs[j].buf,
121 sizes[k], valid, bufs[j].str);
122
123 ctr++;
124 }
125 }
126 }
127 }
128
129 puts("+++ exited with 0 +++");
130 return 0;
131 }
132
133 #else
134
135 SKIP_MAIN_UNDEFINED("__NR_s390_pci_mmio_read && __NR_s390_pci_mmio_write");
136
137 #endif