Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/powerpc: Add {read,write}_{long,ulong}

Add helper functions to read and write (unsigned) long values directly
from/to files. One of the kernel interfaces uses hex strings, so we need
to allow passing a base too.

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20230203003947.38033-5-bgray@linux.ibm.com

authored by

Benjamin Gray and committed by
Michael Ellerman
5c20de57 d1bc05b7

+95 -22
+2 -7
tools/testing/selftests/powerpc/dscr/dscr.h
··· 65 65 unsigned long get_default_dscr(void) 66 66 { 67 67 int err; 68 - char buf[16] = {0}; 69 68 unsigned long val; 70 69 71 - err = read_file(DSCR_DEFAULT, buf, sizeof(buf) - 1, NULL); 70 + err = read_ulong(DSCR_DEFAULT, &val, 16); 72 71 if (err) { 73 72 perror("read() failed"); 74 73 exit(1); 75 74 } 76 - sscanf(buf, "%lx", &val); 77 75 return val; 78 76 } 79 77 80 78 void set_default_dscr(unsigned long val) 81 79 { 82 80 int err; 83 - char buf[16]; 84 81 85 - sprintf(buf, "%lx\n", val); 86 - 87 - err = write_file(DSCR_DEFAULT, buf, strlen(buf)); 82 + err = write_ulong(DSCR_DEFAULT, val, 16); 88 83 if (err) { 89 84 perror("write() failed"); 90 85 exit(1);
+7 -7
tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
··· 12 12 13 13 static int check_cpu_dscr_default(char *file, unsigned long val) 14 14 { 15 - char buf[10] = {0}; 16 - int rc; 15 + unsigned long cpu_dscr; 16 + int err; 17 17 18 - rc = read_file(file, buf, sizeof(buf) - 1, NULL); 19 - if (rc) 20 - return rc; 18 + err = read_ulong(file, &cpu_dscr, 16); 19 + if (err) 20 + return err; 21 21 22 - if (strtol(buf, NULL, 16) != val) { 22 + if (cpu_dscr != val) { 23 23 printf("DSCR match failed: %ld (system) %ld (cpu)\n", 24 - val, strtol(buf, NULL, 16)); 24 + val, cpu_dscr); 25 25 return 1; 26 26 } 27 27 return 0;
+4
tools/testing/selftests/powerpc/include/utils.h
··· 42 42 43 43 int read_file(const char *path, char *buf, size_t count, size_t *len); 44 44 int write_file(const char *path, const char *buf, size_t count); 45 + int read_long(const char *path, long *result, int base); 46 + int write_long(const char *path, long result, int base); 47 + int read_ulong(const char *path, unsigned long *result, int base); 48 + int write_ulong(const char *path, unsigned long result, int base); 45 49 int read_debugfs_file(const char *debugfs_file, char *buf, size_t count); 46 50 int write_debugfs_file(const char *debugfs_file, const char *buf, size_t count); 47 51 int read_debugfs_int(const char *debugfs_file, int *result);
+1 -8
tools/testing/selftests/powerpc/pmu/lib.c
··· 192 192 { 193 193 int err; 194 194 long current; 195 - char buf[16] = {0}; 196 195 197 - err = read_file(PARANOID_PATH, buf, sizeof(buf) - 1, NULL); 198 - if (err) { 199 - printf("Couldn't read " PARANOID_PATH "?\n"); 200 - return false; 201 - } 202 - 203 - err = parse_long(buf, sizeof(buf), &current, 10); 196 + err = read_long(PARANOID_PATH, &current, 10); 204 197 if (err) { 205 198 printf("Couldn't parse " PARANOID_PATH "?\n"); 206 199 return false;
+81
tools/testing/selftests/powerpc/utils.c
··· 245 245 return err; 246 246 } 247 247 248 + int read_long(const char *path, long *result, int base) 249 + { 250 + int err; 251 + char buffer[32] = {0}; 252 + 253 + err = read_file(path, buffer, sizeof(buffer) - 1, NULL); 254 + if (err) 255 + return err; 256 + 257 + return parse_long(buffer, sizeof(buffer), result, base); 258 + } 259 + 260 + int read_ulong(const char *path, unsigned long *result, int base) 261 + { 262 + int err; 263 + char buffer[32] = {0}; 264 + 265 + err = read_file(path, buffer, sizeof(buffer) - 1, NULL); 266 + if (err) 267 + return err; 268 + 269 + return parse_ulong(buffer, sizeof(buffer), result, base); 270 + } 271 + 272 + int write_long(const char *path, long result, int base) 273 + { 274 + int err; 275 + int len; 276 + char buffer[32]; 277 + 278 + /* Decimal only for now: no format specifier for signed hex values */ 279 + if (base != 10) { 280 + err = -EINVAL; 281 + goto out; 282 + } 283 + 284 + len = snprintf(buffer, sizeof(buffer), "%ld", result); 285 + if (len < 0 || len >= sizeof(buffer)) { 286 + err = -EOVERFLOW; 287 + goto out; 288 + } 289 + 290 + err = write_file(path, buffer, len); 291 + 292 + out: 293 + errno = -err; 294 + return err; 295 + } 296 + 297 + int write_ulong(const char *path, unsigned long result, int base) 298 + { 299 + int err; 300 + int len; 301 + char buffer[32]; 302 + char *fmt; 303 + 304 + switch (base) { 305 + case 10: 306 + fmt = "%lu"; 307 + break; 308 + case 16: 309 + fmt = "%lx"; 310 + break; 311 + default: 312 + err = -EINVAL; 313 + goto out; 314 + } 315 + 316 + len = snprintf(buffer, sizeof(buffer), fmt, result); 317 + if (len < 0 || len >= sizeof(buffer)) { 318 + err = -errno; 319 + goto out; 320 + } 321 + 322 + err = write_file(path, buffer, len); 323 + 324 + out: 325 + errno = -err; 326 + return err; 327 + } 328 + 248 329 void *find_auxv_entry(int type, char *auxv) 249 330 { 250 331 ElfW(auxv_t) *p;