~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/dexcr/lsdexcr.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0+
  2 
  3 #include <stddef.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 #include <sys/prctl.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 static void print_list(const char *list[], size_t len)
 16 {
 17         for (size_t i = 0; i < len; i++) {
 18                 printf("%s", list[i]);
 19                 if (i + 1 < len)
 20                         printf(", ");
 21         }
 22 }
 23 
 24 static void print_dexcr(char *name, unsigned int bits)
 25 {
 26         const char *enabled_aspects[ARRAY_SIZE(aspects) + 1] = {NULL};
 27         size_t j = 0;
 28 
 29         printf("%s: 0x%08x", name, bits);
 30 
 31         if (bits == 0) {
 32                 printf("\n");
 33                 return;
 34         }
 35 
 36         for (size_t i = 0; i < ARRAY_SIZE(aspects); i++) {
 37                 unsigned int mask = DEXCR_PR_BIT(aspects[i].index);
 38 
 39                 if (bits & mask) {
 40                         enabled_aspects[j++] = aspects[i].name;
 41                         bits &= ~mask;
 42                 }
 43         }
 44 
 45         if (bits)
 46                 enabled_aspects[j++] = "unknown";
 47 
 48         printf(" (");
 49         print_list(enabled_aspects, j);
 50         printf(")\n");
 51 }
 52 
 53 static void print_aspect(const struct dexcr_aspect *aspect)
 54 {
 55         const char *attributes[8] = {NULL};
 56         size_t j = 0;
 57         unsigned long mask;
 58 
 59         mask = DEXCR_PR_BIT(aspect->index);
 60         if (dexcr & mask)
 61                 attributes[j++] = "set";
 62         if (hdexcr & mask)
 63                 attributes[j++] = "set (hypervisor)";
 64         if (!(effective & mask))
 65                 attributes[j++] = "clear";
 66 
 67         printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index);
 68         print_list(attributes, j);
 69         printf("  \t(%s)\n", aspect->desc);
 70 }
 71 
 72 static void print_aspect_config(const struct dexcr_aspect *aspect)
 73 {
 74         const char *reason = NULL;
 75         const char *reason_hyp = NULL;
 76         const char *reason_prctl = "no prctl";
 77         bool actual = effective & DEXCR_PR_BIT(aspect->index);
 78         bool expected = actual;  /* Assume it's fine if we don't expect a specific set/clear value */
 79 
 80         if (actual)
 81                 reason = "set by unknown";
 82         else
 83                 reason = "cleared by unknown";
 84 
 85         if (aspect->prctl != -1) {
 86                 int ctrl = pr_get_dexcr(aspect->prctl);
 87 
 88                 if (ctrl < 0) {
 89                         reason_prctl = "failed to read prctl";
 90                 } else {
 91                         if (ctrl & PR_PPC_DEXCR_CTRL_SET) {
 92                                 reason_prctl = "set by prctl";
 93                                 expected = true;
 94                         } else if (ctrl & PR_PPC_DEXCR_CTRL_CLEAR) {
 95                                 reason_prctl = "cleared by prctl";
 96                                 expected = false;
 97                         } else {
 98                                 reason_prctl = "unknown prctl";
 99                         }
100 
101                         reason = reason_prctl;
102                 }
103         }
104 
105         if (hdexcr & DEXCR_PR_BIT(aspect->index)) {
106                 reason_hyp = "set by hypervisor";
107                 reason = reason_hyp;
108                 expected = true;
109         } else {
110                 reason_hyp = "not modified by hypervisor";
111         }
112 
113         printf("%12s (%d): %-28s (%s, %s)\n",
114                aspect->name,
115                aspect->index,
116                reason,
117                reason_hyp,
118                reason_prctl);
119 
120         /*
121          * The checks are not atomic, so this can technically trigger if the
122          * hypervisor makes a change while we are checking each source. It's
123          * far more likely to be a bug if we see this though.
124          */
125         if (actual != expected)
126                 printf("                : ! actual %s does not match config\n", aspect->name);
127 }
128 
129 int main(int argc, char *argv[])
130 {
131         if (!dexcr_exists()) {
132                 printf("DEXCR not detected on this hardware\n");
133                 return 1;
134         }
135 
136         dexcr = get_dexcr(DEXCR);
137         hdexcr = get_dexcr(HDEXCR);
138         effective = dexcr | hdexcr;
139 
140         printf("current status:\n");
141 
142         print_dexcr("    DEXCR", dexcr);
143         print_dexcr("   HDEXCR", hdexcr);
144         print_dexcr("Effective", effective);
145         printf("\n");
146 
147         for (size_t i = 0; i < ARRAY_SIZE(aspects); i++)
148                 print_aspect(&aspects[i]);
149         printf("\n");
150 
151         if (effective & DEXCR_PR_NPHIE) {
152                 printf("DEXCR[NPHIE] enabled: hashst/hashchk ");
153                 if (hashchk_triggers())
154                         printf("working\n");
155                 else
156                         printf("failed to trigger\n");
157         } else {
158                 printf("DEXCR[NPHIE] disabled: hashst/hashchk ");
159                 if (hashchk_triggers())
160                         printf("unexpectedly triggered\n");
161                 else
162                         printf("ignored\n");
163         }
164         printf("\n");
165 
166         printf("configuration:\n");
167         for (size_t i = 0; i < ARRAY_SIZE(aspects); i++)
168                 print_aspect_config(&aspects[i]);
169         printf("\n");
170 
171         return 0;
172 }
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php