File Index
Files and directories
Sign in
FILE

lsdexcr.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/powerpc/dexcr/lsdexcr.c C
  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
 11static unsigned int dexcr;
 12static unsigned int hdexcr;
 13static unsigned int effective;
 14
 15static 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
 24static 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
 53static 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
 72static 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
129int 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}
~/ Read-only file preview.