Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / powerpc / papr_sysparm / papr_sysparm.c
blobf56c15a11e2f46e9046f30f94cb47f208b8be10a
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <sys/ioctl.h>
6 #include <unistd.h>
7 #include <asm/papr-sysparm.h>
9 #include "utils.h"
11 #define DEVPATH "/dev/papr-sysparm"
13 static int open_close(void)
15 const int devfd = open(DEVPATH, O_RDONLY);
17 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
18 DEVPATH " not present");
20 FAIL_IF(devfd < 0);
21 FAIL_IF(close(devfd) != 0);
23 return 0;
26 static int get_splpar(void)
28 struct papr_sysparm_io_block sp = {
29 .parameter = 20, // SPLPAR characteristics
31 const int devfd = open(DEVPATH, O_RDONLY);
33 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
34 DEVPATH " not present");
36 FAIL_IF(devfd < 0);
37 FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != 0);
38 FAIL_IF(sp.length == 0);
39 FAIL_IF(sp.length > sizeof(sp.data));
40 FAIL_IF(close(devfd) != 0);
42 return 0;
45 static int get_bad_parameter(void)
47 struct papr_sysparm_io_block sp = {
48 .parameter = UINT32_MAX, // there are only ~60 specified parameters
50 const int devfd = open(DEVPATH, O_RDONLY);
52 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
53 DEVPATH " not present");
55 FAIL_IF(devfd < 0);
57 // Ensure expected error
58 FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != -1);
59 FAIL_IF(errno != EOPNOTSUPP);
61 // Ensure the buffer is unchanged
62 FAIL_IF(sp.length != 0);
63 for (size_t i = 0; i < ARRAY_SIZE(sp.data); ++i)
64 FAIL_IF(sp.data[i] != 0);
66 FAIL_IF(close(devfd) != 0);
68 return 0;
71 static int check_efault_common(unsigned long cmd)
73 const int devfd = open(DEVPATH, O_RDWR);
75 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
76 DEVPATH " not present");
78 FAIL_IF(devfd < 0);
80 // Ensure expected error
81 FAIL_IF(ioctl(devfd, cmd, NULL) != -1);
82 FAIL_IF(errno != EFAULT);
84 FAIL_IF(close(devfd) != 0);
86 return 0;
89 static int check_efault_get(void)
91 return check_efault_common(PAPR_SYSPARM_IOC_GET);
94 static int check_efault_set(void)
96 return check_efault_common(PAPR_SYSPARM_IOC_SET);
99 static int set_hmc0(void)
101 struct papr_sysparm_io_block sp = {
102 .parameter = 0, // HMC0, not a settable parameter
104 const int devfd = open(DEVPATH, O_RDWR);
106 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
107 DEVPATH " not present");
109 FAIL_IF(devfd < 0);
111 // Ensure expected error
112 FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_SET, &sp) != -1);
113 SKIP_IF_MSG(errno == EOPNOTSUPP, "operation not supported");
114 FAIL_IF(errno != EPERM);
116 FAIL_IF(close(devfd) != 0);
118 return 0;
121 static int set_with_ro_fd(void)
123 struct papr_sysparm_io_block sp = {
124 .parameter = 0, // HMC0, not a settable parameter.
126 const int devfd = open(DEVPATH, O_RDONLY);
128 SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
129 DEVPATH " not present");
131 FAIL_IF(devfd < 0);
133 // Ensure expected error
134 FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_SET, &sp) != -1);
135 SKIP_IF_MSG(errno == EOPNOTSUPP, "operation not supported");
137 // HMC0 isn't a settable parameter and we would normally
138 // expect to get EPERM on attempts to modify it. However, when
139 // the file is open read-only, we expect the driver to prevent
140 // the attempt with a distinct error.
141 FAIL_IF(errno != EBADF);
143 FAIL_IF(close(devfd) != 0);
145 return 0;
148 struct sysparm_test {
149 int (*function)(void);
150 const char *description;
153 static const struct sysparm_test sysparm_tests[] = {
155 .function = open_close,
156 .description = "open and close " DEVPATH " without issuing commands",
159 .function = get_splpar,
160 .description = "retrieve SPLPAR characteristics",
163 .function = get_bad_parameter,
164 .description = "verify EOPNOTSUPP for known-bad parameter",
167 .function = check_efault_get,
168 .description = "PAPR_SYSPARM_IOC_GET returns EFAULT on bad address",
171 .function = check_efault_set,
172 .description = "PAPR_SYSPARM_IOC_SET returns EFAULT on bad address",
175 .function = set_hmc0,
176 .description = "ensure EPERM on attempt to update HMC0",
179 .function = set_with_ro_fd,
180 .description = "PAPR_IOC_SYSPARM_SET returns EACCES on read-only fd",
184 int main(void)
186 size_t fails = 0;
188 for (size_t i = 0; i < ARRAY_SIZE(sysparm_tests); ++i) {
189 const struct sysparm_test *t = &sysparm_tests[i];
191 if (test_harness(t->function, t->description))
192 ++fails;
195 return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE;