1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <errno.h>
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #include "dexcr.h"
9 #include "utils.h"
10
11 static unsigned int dexcr;
12 static unsigned int hdexcr;
13 static unsigned int effective;
14
15 struct dexcr_aspect {
16 const char *name;
17 const char *desc;
18 unsigned int index;
19 };
20
21 static const struct dexcr_aspect aspects[] = {
22 {
23 .name = "SBHE",
24 .desc = "Speculative branch hint enable",
25 .index = 0,
26 },
27 {
28 .name = "IBRTPD",
29 .desc = "Indirect branch recurrent target prediction disable",
30 .index = 3,
31 },
32 {
33 .name = "SRAPD",
34 .desc = "Subroutine return address prediction disable",
35 .index = 4,
36 },
37 {
38 .name = "NPHIE",
39 .desc = "Non-privileged hash instruction enable",
40 .index = 5,
41 },
42 {
43 .name = "PHIE",
44 .desc = "Privileged hash instruction enable",
45 .index = 6,
46 },
47 };
48
print_list(const char * list[],size_t len)49 static void print_list(const char *list[], size_t len)
50 {
51 for (size_t i = 0; i < len; i++) {
52 printf("%s", list[i]);
53 if (i + 1 < len)
54 printf(", ");
55 }
56 }
57
print_dexcr(char * name,unsigned int bits)58 static void print_dexcr(char *name, unsigned int bits)
59 {
60 const char *enabled_aspects[ARRAY_SIZE(aspects) + 1] = {NULL};
61 size_t j = 0;
62
63 printf("%s: %08x", name, bits);
64
65 if (bits == 0) {
66 printf("\n");
67 return;
68 }
69
70 for (size_t i = 0; i < ARRAY_SIZE(aspects); i++) {
71 unsigned int mask = DEXCR_PR_BIT(aspects[i].index);
72
73 if (bits & mask) {
74 enabled_aspects[j++] = aspects[i].name;
75 bits &= ~mask;
76 }
77 }
78
79 if (bits)
80 enabled_aspects[j++] = "unknown";
81
82 printf(" (");
83 print_list(enabled_aspects, j);
84 printf(")\n");
85 }
86
print_aspect(const struct dexcr_aspect * aspect)87 static void print_aspect(const struct dexcr_aspect *aspect)
88 {
89 const char *attributes[8] = {NULL};
90 size_t j = 0;
91 unsigned long mask;
92
93 mask = DEXCR_PR_BIT(aspect->index);
94 if (dexcr & mask)
95 attributes[j++] = "set";
96 if (hdexcr & mask)
97 attributes[j++] = "set (hypervisor)";
98 if (!(effective & mask))
99 attributes[j++] = "clear";
100
101 printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index);
102 print_list(attributes, j);
103 printf(" \t(%s)\n", aspect->desc);
104 }
105
main(int argc,char * argv[])106 int main(int argc, char *argv[])
107 {
108 if (!dexcr_exists()) {
109 printf("DEXCR not detected on this hardware\n");
110 return 1;
111 }
112
113 dexcr = get_dexcr(DEXCR);
114 hdexcr = get_dexcr(HDEXCR);
115 effective = dexcr | hdexcr;
116
117 print_dexcr(" DEXCR", dexcr);
118 print_dexcr(" HDEXCR", hdexcr);
119 print_dexcr("Effective", effective);
120 printf("\n");
121
122 for (size_t i = 0; i < ARRAY_SIZE(aspects); i++)
123 print_aspect(&aspects[i]);
124 printf("\n");
125
126 if (effective & DEXCR_PR_NPHIE) {
127 printf("DEXCR[NPHIE] enabled: hashst/hashchk ");
128 if (hashchk_triggers())
129 printf("working\n");
130 else
131 printf("failed to trigger\n");
132 } else {
133 printf("DEXCR[NPHIE] disabled: hashst/hashchk ");
134 if (hashchk_triggers())
135 printf("unexpectedly triggered\n");
136 else
137 printf("ignored\n");
138 }
139
140 return 0;
141 }
142