linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Gray <bgray@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: ajd@linux.ibm.com, linux-kernel@vger.kernel.org,
	linux-hardening@vger.kernel.org, cmr@bluescreens.de,
	Benjamin Gray <bgray@linux.ibm.com>
Subject: [RFC PATCH 12/13] selftests/powerpc: Add DEXCR status utility lsdexcr
Date: Mon, 28 Nov 2022 13:44:57 +1100	[thread overview]
Message-ID: <20221128024458.46121-13-bgray@linux.ibm.com> (raw)
In-Reply-To: <20221128024458.46121-1-bgray@linux.ibm.com>

Add a utility 'lsdexcr' to print the current DEXCR status. Useful for
quickly checking the status when debugging test failures, using the
sysctl interfaces manually, or just wanting to check it.

Example output:

          Requested: 84000000 (SBHE, NPHIE)
Hypervisor enforced: 00000000
          Effective: 84000000 (SBHE, NPHIE)

        SBHE * (0): set, prctl editable  	(Speculative branch hint enable)
      IBRTPD   (3): clear, prctl editable  	(Indirect branch recurrent target prediction disable)
       SRAPD   (4): clear, prctl editable  	(Subroutine return address prediction disable)
       NPHIE * (5): set  	(Non-privileged hash instruction enable)

Global SBHE override: 1 (set)

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
---
 .../selftests/powerpc/dexcr/.gitignore        |   1 +
 .../testing/selftests/powerpc/dexcr/Makefile  |   2 +
 .../testing/selftests/powerpc/dexcr/lsdexcr.c | 178 ++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/dexcr/lsdexcr.c

diff --git a/tools/testing/selftests/powerpc/dexcr/.gitignore b/tools/testing/selftests/powerpc/dexcr/.gitignore
index 035a1fcd8fb3..7dd2fad93732 100644
--- a/tools/testing/selftests/powerpc/dexcr/.gitignore
+++ b/tools/testing/selftests/powerpc/dexcr/.gitignore
@@ -1,2 +1,3 @@
 dexcr_test
 hashchk_user
+lsdexcr
diff --git a/tools/testing/selftests/powerpc/dexcr/Makefile b/tools/testing/selftests/powerpc/dexcr/Makefile
index 9814e72a4afa..8cb732cda7e7 100644
--- a/tools/testing/selftests/powerpc/dexcr/Makefile
+++ b/tools/testing/selftests/powerpc/dexcr/Makefile
@@ -1,4 +1,5 @@
 TEST_GEN_PROGS := dexcr_test hashchk_test
+TEST_GEN_FILES := lsdexcr
 
 TEST_FILES := settings
 top_srcdir = ../../../../..
@@ -7,3 +8,4 @@ include ../../lib.mk
 HASHCHK_TEST_CFLAGS = -no-pie $(call cc-option,-mno-rop-protect)
 
 $(TEST_GEN_PROGS): ../harness.c ../utils.c ./dexcr.c ./cap.c
+$(TEST_GEN_FILES): ../utils.c ./dexcr.c
diff --git a/tools/testing/selftests/powerpc/dexcr/lsdexcr.c b/tools/testing/selftests/powerpc/dexcr/lsdexcr.c
new file mode 100644
index 000000000000..c9f0035f8e2e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dexcr/lsdexcr.c
@@ -0,0 +1,178 @@
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+
+#include "dexcr.h"
+#include "utils.h"
+
+static unsigned int requested;
+static unsigned int enforced;
+static unsigned int effective;
+
+struct dexcr_aspect {
+	const char *name;
+	const char *desc;
+	unsigned int index;
+	unsigned long pr_val;
+};
+
+static const struct dexcr_aspect aspects[] = {
+	{
+		.name = "SBHE",
+		.desc = "Speculative branch hint enable",
+		.index = 0,
+		.pr_val = PR_PPC_DEXCR_SBHE,
+	},
+	{
+		.name = "IBRTPD",
+		.desc = "Indirect branch recurrent target prediction disable",
+		.index = 3,
+		.pr_val = PR_PPC_DEXCR_IBRTPD,
+	},
+	{
+		.name = "SRAPD",
+		.desc = "Subroutine return address prediction disable",
+		.index = 4,
+		.pr_val = PR_PPC_DEXCR_SRAPD,
+	},
+	{
+		.name = "NPHIE",
+		.desc = "Non-privileged hash instruction enable",
+		.index = 5,
+		.pr_val = PR_PPC_DEXCR_NPHIE,
+	},
+};
+
+#define NUM_ASPECTS (sizeof(aspects) / sizeof(struct dexcr_aspect))
+
+static void print_list(const char *list[], size_t len)
+{
+	for (size_t i = 0; i < len; i++) {
+		printf("%s", list[i]);
+		if (i + 1 < len)
+			printf(", ");
+	}
+}
+
+static void print_dexcr(char *name, unsigned int bits)
+{
+	const char *enabled_aspects[32] = {NULL};
+	size_t j = 0;
+
+	printf("%s: %08x", name, bits);
+
+	if (bits == 0) {
+		printf("\n");
+		return;
+	}
+
+	for (size_t i = 0; i < NUM_ASPECTS; i++) {
+		unsigned int mask = pr_aspect_to_dexcr_mask(aspects[i].pr_val);
+		if (bits & mask) {
+			enabled_aspects[j++] = aspects[i].name;
+			bits &= ~mask;
+		}
+	}
+
+	if (bits)
+		enabled_aspects[j++] = "unknown";
+
+	printf(" (");
+	print_list(enabled_aspects, j);
+	printf(")\n");
+}
+
+static void print_aspect(const struct dexcr_aspect *aspect)
+{
+	const char *attributes[32] = {NULL};
+	size_t j = 0;
+	unsigned long mask;
+	int pr_status;
+
+	/* Kernel-independent info about aspect */
+	mask = pr_aspect_to_dexcr_mask(aspect->pr_val);
+	if (requested & mask)
+		attributes[j++] = "set";
+	if (enforced & mask)
+		attributes[j++] = "hypervisor enforced";
+	if (!(effective & mask))
+		attributes[j++] = "clear";
+
+	/* Kernel understanding of the aspect */
+	pr_status = prctl(PR_PPC_GET_DEXCR, aspect->pr_val, 0, 0, 0);
+	if (pr_status == -1) {
+		switch (errno) {
+		case ENODEV:
+			attributes[j++] = "aspect not present";
+			break;
+		case EINVAL:
+			attributes[j++] = "unrecognised aspect";
+			break;
+		default:
+			attributes[j++] = "unknown kernel error";
+			break;
+		}
+	} else {
+		if (pr_status & PR_PPC_DEXCR_SET_ASPECT)
+			attributes[j++] = "prctl set";
+		if (pr_status & PR_PPC_DEXCR_FORCE_SET_ASPECT)
+			attributes[j++] = "prctl force set";
+		if (pr_status & PR_PPC_DEXCR_CLEAR_ASPECT)
+			attributes[j++] = "prctl clear";
+		if (pr_status & PR_PPC_DEXCR_PRCTL)
+			attributes[j++] = "prctl editable";
+	}
+
+	printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index);
+	print_list(attributes, j);
+	printf("  \t(%s)\n", aspect->desc);
+}
+
+static void print_overrides(void) {
+	long sbhe;
+	int err;
+
+	printf("Global SBHE override: ");
+	if ((err = read_long(SYSCTL_DEXCR_SBHE, &sbhe, 10))) {
+		printf("error reading " SYSCTL_DEXCR_SBHE ": %d (%s)\n", err, strerror(err));
+	} else {
+		const char *meaning;
+		switch (sbhe) {
+		case -1:
+			meaning = "default";
+			break;
+		case 0:
+			meaning = "clear";
+			break;
+		case 1:
+			meaning = "set";
+			break;
+		default:
+			meaning = "unknown";
+		}
+
+		printf("%ld (%s)\n", sbhe, meaning);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	requested = get_dexcr(UDEXCR);
+	enforced = get_dexcr(ENFORCED);
+	effective = requested | enforced;
+
+	print_dexcr("          Requested", requested);
+	print_dexcr("Hypervisor enforced", enforced);
+	print_dexcr("          Effective", effective);
+	printf("\n");
+
+	for (size_t i = 0; i < NUM_ASPECTS; i++)
+		print_aspect(&aspects[i]);
+	printf("\n");
+
+	print_overrides();
+
+	return 0;
+}
-- 
2.38.1


  parent reply	other threads:[~2022-11-28  2:54 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-28  2:44 [RFC PATCH 00/13] Add DEXCR support Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 01/13] powerpc/book3s: Add missing <linux/sched.h> include Benjamin Gray
2023-03-07  4:28   ` Nicholas Piggin
2022-11-28  2:44 ` [RFC PATCH 02/13] powerpc: Add initial Dynamic Execution Control Register (DEXCR) support Benjamin Gray
2023-03-07  4:45   ` Nicholas Piggin
2023-03-09 23:46     ` Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 03/13] powerpc/dexcr: Handle hashchk exception Benjamin Gray
2022-11-29 10:39   ` Nicholas Piggin
2022-11-29 22:04     ` Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 04/13] powerpc/dexcr: Support userspace ROP protection Benjamin Gray
2023-03-07  5:05   ` Nicholas Piggin
2023-03-07  5:37     ` Benjamin Gray
2023-03-21  4:51       ` Nicholas Piggin
2022-11-28  2:44 ` [RFC PATCH 05/13] prctl: Define PowerPC DEXCR interface Benjamin Gray
2023-03-07  5:07   ` Nicholas Piggin
2022-11-28  2:44 ` [RFC PATCH 06/13] powerpc/dexcr: Add prctl implementation Benjamin Gray
2023-03-07  5:12   ` Nicholas Piggin
2022-11-28  2:44 ` [RFC PATCH 07/13] powerpc/dexcr: Add sysctl entry for SBHE system override Benjamin Gray
2023-03-07  5:30   ` Nicholas Piggin
2023-03-07  5:58     ` Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 08/13] powerpc/dexcr: Add enforced userspace ROP protection config Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 09/13] selftests/powerpc: Add more utility macros Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 10/13] selftests/powerpc: Add hashst/hashchk test Benjamin Gray
2022-11-28  2:44 ` [RFC PATCH 11/13] selftests/powerpc: Add DEXCR prctl, sysctl interface test Benjamin Gray
2022-11-28  2:44 ` Benjamin Gray [this message]
2022-11-28  2:44 ` [RFC PATCH 13/13] Documentation: Document PowerPC kernel DEXCR interface Benjamin Gray
2023-03-07  5:40   ` Nicholas Piggin
2023-03-07  5:52     ` Benjamin Gray
2022-11-28  4:05 ` [RFC PATCH 00/13] Add DEXCR support Russell Currey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221128024458.46121-13-bgray@linux.ibm.com \
    --to=bgray@linux.ibm.com \
    --cc=ajd@linux.ibm.com \
    --cc=cmr@bluescreens.de \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).