1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) UnionTech Software Technology Co.,Ltd., 2024
4 * Author: Lu Fei <[email protected]>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Simple test on arch_prctl to set and get cpuid instruction of test thread.
11 */
12
13 #include "tst_test.h"
14 #include "tst_safe_stdio.h"
15 #include "lapi/syscalls.h"
16 #include "lapi/arch_prctl.h"
17 #include <stdlib.h>
18 #include <string.h>
19
arch_prctl_get(int code)20 static int arch_prctl_get(int code)
21 {
22 return tst_syscall(__NR_arch_prctl, code, NULL);
23 }
24
arch_prctl_set(int code,unsigned long addr)25 static int arch_prctl_set(int code, unsigned long addr)
26 {
27 return tst_syscall(__NR_arch_prctl, code, addr);
28 }
29
30 static bool tag;
31
setup(void)32 static void setup(void)
33 {
34 FILE *f;
35 char flag_mid[] = " cpuid_fault ";
36 char flag_end[] = " cpuid_fault\n";
37 char *line = NULL;
38 size_t len = 0;
39
40 tag = false;
41
42 f = SAFE_FOPEN("/proc/cpuinfo", "r");
43
44 while (getline(&line, &len, f) != -1)
45 if (strncmp(line, "flags", strlen("flags")) == 0 &&
46 (strstr(line, flag_mid) != NULL ||
47 strstr(line, flag_end) != NULL)) {
48 tag = true;
49 break;
50 }
51 }
52
run(unsigned int index)53 static void run(unsigned int index)
54 {
55 if (tag)
56 TST_EXP_PASS(arch_prctl_set(ARCH_SET_CPUID, index));
57 else
58 TST_EXP_FAIL(arch_prctl_set(ARCH_SET_CPUID, index), ENODEV);
59
60 // if cpu has cpuid_fault flag, ARCH_GET_CPUID returns what has been
61 // set: index, otherwise, returns default status: 1
62 int exp = tag ? index : 1;
63
64 TEST(arch_prctl_get(ARCH_GET_CPUID));
65 if (TST_RET == exp)
66 tst_res(TPASS, "get cpuid succeed.");
67 else
68 tst_res(TFAIL, "get wrong cpuid status");
69 }
70
71 static struct tst_test test = {
72 .test = run,
73 .setup = setup,
74 .tcnt = 2,
75 .min_kver = "4.12",
76 .supported_archs = (const char *const []){"x86_64", "x86", NULL}
77 };
78