linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "David E. Box" <david.e.box@linux.intel.com>
To: lee.jones@linaro.org, hdegoede@redhat.com,
	david.e.box@linux.intel.com, bhelgaas@google.com,
	gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com,
	srinivas.pandruvada@intel.com, shuah@kernel.org,
	mgross@linux.intel.com
Cc: linux-kernel@vger.kernel.org,
	platform-driver-x86@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-pci@vger.kernel.org
Subject: [V2 5/6] sample/sdsi: Sample of SDSi provisiong using sysfs
Date: Tue,  7 Dec 2021 09:14:47 -0800	[thread overview]
Message-ID: <20211207171448.799376-6-david.e.box@linux.intel.com> (raw)
In-Reply-To: <20211207171448.799376-1-david.e.box@linux.intel.com>

Sample application showing usage of Intel Software Defined Silicon
sysfs ABI.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
V2
  - New patch

 MAINTAINERS                |   1 +
 samples/sdsi/Makefile      |   9 +
 samples/sdsi/sdsi-sample.c | 399 +++++++++++++++++++++++++++++++++++++
 3 files changed, 409 insertions(+)
 create mode 100644 samples/sdsi/Makefile
 create mode 100644 samples/sdsi/sdsi-sample.c

diff --git a/MAINTAINERS b/MAINTAINERS
index af7f17e7400f..ba9603fb7f62 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9787,6 +9787,7 @@ INTEL SDSI DRIVER
 M:	David E. Box <david.e.box@linux.intel.com>
 S:	Supported
 F:	drivers/platform/x86/intel/sdsi.c
+F:	samples/sdsi/
 
 INTEL SKYLAKE INT3472 ACPI DEVICE DRIVER
 M:	Daniel Scally <djrscally@gmail.com>
diff --git a/samples/sdsi/Makefile b/samples/sdsi/Makefile
new file mode 100644
index 000000000000..17ac82a5623d
--- /dev/null
+++ b/samples/sdsi/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
+.PHONY: sdsi-sample
+
+sdsi-sample: sdsi-sample.o
+	$(CC) -Wall $^ -o $@
+
+clean:
+	rm *.o sdsi-sample
diff --git a/samples/sdsi/sdsi-sample.c b/samples/sdsi/sdsi-sample.c
new file mode 100644
index 000000000000..6b3b48359aa0
--- /dev/null
+++ b/samples/sdsi/sdsi-sample.c
@@ -0,0 +1,399 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * sdsi_test: Example program using the sysfs interface of the
+ * Intel Software Defined Silicon Linux driver.
+ *
+ * See https://github.com/intel/intel-sdsi/blob/master/os-interface.rst
+ * for register descriptions.
+ *
+ * Copyright (C) 2021 Intel Corporation. All rights reserved.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define SDSI_DIR		"/sys/bus/auxiliary/devices/intel_vsec.sdsi"
+#define GUID			"0x6dd191"
+#define REGISTERS_MIN_SIZE	72
+
+struct enabled_features {
+	uint64_t reserved:3;
+	uint64_t sdsi:1;
+	uint64_t reserved1:60;
+};
+
+struct auth_fail_count {
+	uint64_t key_failure_count:3;
+	uint64_t key_failure_threshold:3;
+	uint64_t auth_failure_count:3;
+	uint64_t auth_failure_threshold:3;
+	uint64_t reserved:52;
+};
+
+struct availability {
+	uint64_t reserved:58;
+	uint64_t updates_available:3;
+	uint64_t updates_threshold:3;
+};
+
+struct sdsi_reg_6dd191 {
+	uint64_t ppin;
+	uint64_t reserved;
+	struct enabled_features en_features;
+	uint64_t reserved1;
+	struct auth_fail_count auth_fail_count;
+	struct availability prov_avail;
+	uint64_t reserved2;
+	uint64_t reserved3;
+	uint64_t socket_id;
+};
+
+enum command {
+	CMD_NONE,
+	CMD_READ_LIC,
+	CMD_READ_REG,
+	CMD_PROV_AKC,
+	CMD_PROV_CAP,
+};
+
+static int get_file_size(FILE *stream, char *name)
+{
+	long size;
+	int ret;
+
+	ret = fseek(stream, 0L, SEEK_END);
+	if (ret == -1) {
+		fprintf(stderr, "...Could not seek to EOF %s: %s\n", name, strerror(errno));
+		return ret;
+	}
+
+	size = ftell(stream);
+	if (size == -1) {
+		fprintf(stderr, "...Could not get size of file %s: %s\n", name, strerror(errno));
+		return size;
+	}
+
+	rewind(stream);
+
+	return size;
+}
+
+static int sdsi_read_reg(char *socket)
+{
+	FILE *regs_ptr, *guid_ptr;
+	struct sdsi_reg_6dd191 registers;
+	char guid_val[20], *buf;
+	char regs_file[70];
+	char guid_file[70];
+	int ret, i;
+	long size;
+
+	snprintf(regs_file, sizeof(regs_file), "%s%s%s%s",
+		 SDSI_DIR, ".", socket, "/registers");
+
+	snprintf(guid_file, sizeof(guid_file), "%s%s%s%s",
+		 SDSI_DIR, ".", socket, "/guid");
+
+	memset(&registers, 0, sizeof(registers));
+
+	/* Open the guid file */
+	guid_ptr = fopen(guid_file, "r");
+	if (!guid_ptr) {
+		fprintf(stderr, "...Could not open file %s: %s\n", guid_file, strerror(errno));
+		return -1;
+	}
+
+	fscanf(guid_ptr, "%20s", guid_val);
+	fclose(guid_ptr);
+
+	/* Open the registers file */
+	regs_ptr = fopen(regs_file, "r");
+	if (!regs_ptr) {
+		fprintf(stderr, "...Could not open file %s: %s\n", regs_file, strerror(errno));
+		return -1;
+	}
+
+	/* Get size of the registers file */
+	size = get_file_size(regs_ptr, regs_file);
+	if (size < 0) {
+		ret = size;
+		goto close_regs_ptr;
+	}
+
+	/* Unknown guid. Just dump raw data */
+	if (strcmp(GUID, guid_val)) {
+		printf("Unrecognized guid, %s\n", guid_val);
+
+		buf = (char *)malloc(sizeof(char) * size);
+		if (!buf) {
+			perror("malloc");
+			goto close_regs_ptr;
+		}
+
+		ret = fread(buf, sizeof(uint8_t), size, regs_ptr);
+		if (!ret) {
+			fprintf(stderr, "...Could not read file %s: %s\n", regs_file,
+				strerror(errno));
+			free(buf);
+			goto close_regs_ptr;
+		}
+
+		for (i = 0; i < size; i += sizeof(uint64_t))
+			printf("%3d: 0x%lx\n", i, *(uint64_t *)&buf[i]);
+
+		free(buf);
+		goto close_regs_ptr;
+	}
+
+	/* Print register info for this guid */
+	ret = fread(&registers, sizeof(uint8_t), sizeof(registers), regs_ptr);
+	if (!ret) {
+		fprintf(stderr, "...Could not read file %s: %s\n", regs_file, strerror(errno));
+		goto close_regs_ptr;
+	}
+
+	printf("\n");
+	printf("Info for device %s.%s\n", "intel_vsec.sdsi", socket);
+	printf("\n");
+	printf("PPIN:                           0x%lx\n", registers.ppin);
+	printf("Enabled Features\n");
+	printf("    SDSi:                       %s\n", !!registers.en_features.sdsi ? "Enabled" : "Disabled");
+	printf("Authorization Failure Count\n");
+	printf("    Key Failure Count:          %d\n", registers.auth_fail_count.key_failure_count);
+	printf("    Key Failure Count:          %d\n", registers.auth_fail_count.key_failure_threshold);
+	printf("    Auth Failure Count:         %d\n", registers.auth_fail_count.auth_failure_count);
+	printf("    Auth Failure Count:         %d\n", registers.auth_fail_count.key_failure_threshold);
+	printf("Provisioning Availability\n");
+	printf("    Updates Available:          %d\n", registers.prov_avail.updates_available);
+	printf("    Updates Threshold:          %d\n", registers.prov_avail.updates_threshold);
+	printf("Socket ID:                      0x%lx\n", registers.socket_id);
+
+close_regs_ptr:
+	fclose(regs_ptr);
+
+	return 0;
+}
+
+static int sdsi_certificate_dump(char *socket)
+{
+	uint64_t state_certificate[512] = {0};
+	bool first_instance;
+	char cert_file[70];
+	uint64_t previous;
+	FILE *cert_ptr;
+	int i, ret;
+
+	snprintf(cert_file, sizeof(cert_file), "%s%s%s%s",
+		 SDSI_DIR, ".", socket, "/state_certificate");
+
+	/* Open the registers file */
+	cert_ptr = fopen(cert_file, "r");
+	if (!cert_ptr) {
+		fprintf(stderr, "...Could not open file %s: %s\n", cert_file, strerror(errno));
+		return -1;
+	}
+
+	/* Read registers */
+	ret = fread(state_certificate, sizeof(uint8_t), sizeof(state_certificate), cert_ptr);
+	if (!ret) {
+		fprintf(stderr, "...Could not read file %s: %s\n", cert_file, strerror(errno));
+		goto close_cert_ptr;
+	}
+
+	printf("%3d: 0x%lx\n", 0, state_certificate[0]);
+	previous = state_certificate[0];
+	first_instance = true;
+
+	for (i = 1; i < (sizeof(state_certificate)/sizeof(uint64_t)); i++) {
+		if (state_certificate[i] == previous) {
+			if (first_instance) {
+				puts("*");
+				first_instance = false;
+			}
+			continue;
+		}
+		printf("%3d: 0x%lx\n", i, state_certificate[i]);
+		previous = state_certificate[i];
+		first_instance = true;
+	}
+	printf("%3d\n", i);
+
+close_cert_ptr:
+	fclose(cert_ptr);
+
+	return 0;
+}
+
+static int sdsi_provision(char *prov_file, char *bin_file)
+{
+	char buf[4096] = { 0 };
+	int bin_fd, prov_fd, size, ret = 0;
+
+	if (!bin_file) {
+		fprintf(stderr, "...No binary file provided\n");
+		return -1;
+	}
+
+	/* Open the provision file */
+	prov_fd = open(prov_file, O_WRONLY);
+	if (prov_fd == -1) {
+		fprintf(stderr, "...Could not open file %s: %s\n", prov_file, strerror(errno));
+		return prov_fd;
+	}
+
+	/* Open the binary */
+	bin_fd = open(bin_file, O_RDONLY);
+	if (bin_fd == -1) {
+		fprintf(stderr, "...Could not open file %s: %s\n", bin_file, strerror(errno));
+		ret = bin_fd;
+		goto close_provision_fd;
+	}
+
+	/* Read the binary file into the buffer */
+	ret = read(bin_fd, buf, 4096);
+	if (ret == -1)
+		goto close_bin_fd;
+
+	size = ret;
+	ret = write(prov_fd, buf, size);
+	if (ret < size) {
+		fprintf(stderr, "...Could not write file %s: %s\n", prov_file, strerror(errno));
+		goto close_bin_fd;
+	}
+
+	printf("Provisioned %s file %s successfully\n", prov_file, bin_file);
+
+close_bin_fd:
+	close(bin_fd);
+close_provision_fd:
+	close(prov_fd);
+
+	return ret;
+}
+
+static int sdsi_provision_akc(char *socket, char *bin_file)
+{
+	char akc_file[70];
+
+	snprintf(akc_file, sizeof(akc_file), "%s%s%s%s",
+		 SDSI_DIR, ".", socket, "/provision_akc");
+
+	return sdsi_provision(akc_file, bin_file);
+}
+
+static int sdsi_provision_cap(char *socket, char *bin_file)
+{
+	char cap_file[70];
+
+	snprintf(cap_file, sizeof(cap_file), "%s%s%s%s",
+		 SDSI_DIR, ".", socket, "/provision_cap");
+
+	return sdsi_provision(cap_file, bin_file);
+}
+
+static void print_help(char *prog)
+{
+	printf("Usage:\n");
+
+	printf("\t%s -s socket [-r [lic] [reg]] [-a file] [-c file]\n", prog);
+
+	printf("Options:\n");
+	printf("%-13s\t%s\n", "-s <socket>", "socket number to open");
+	printf("%-13s\t%s\n", "-r lic", "read licence data");
+	printf("%-13s\t%s\n", "-r reg", "read SDSi register data");
+	printf("%-13s\t%s\n", "-a <file>", "provision socket with AKC file");
+	printf("%-13s\t%s\n", "-c <file>", "provision socket with CAP file");
+}
+
+int main(int argc, char *argv[])
+{
+	char *bin_file = NULL, *socket = NULL;
+	enum command command = CMD_NONE;
+	int ret, opt, cmd_count = 0;
+
+	while ((opt = getopt(argc, argv, "hs:ra:c:t:")) != -1) {
+		switch (opt) {
+		case 's':
+			socket = optarg;
+			break;
+		case 'r':
+			if (!argv[optind]) {
+				print_help(argv[0]);
+				return -1;
+			}
+
+			if (strlen(argv[optind]) != strlen("lic")) {
+				print_help(argv[0]);
+				return -1;
+			}
+
+			if (!strcmp(argv[optind], "lic")) {
+				command = CMD_READ_LIC;
+				++cmd_count;
+				break;
+			} else if (!strcmp(argv[optind], "reg")) {
+				command = CMD_READ_REG;
+				++cmd_count;
+				break;
+			}
+
+			print_help(argv[0]);
+			return -1;
+		case 'a':
+			command = CMD_PROV_AKC;
+			bin_file = optarg;
+			++cmd_count;
+			break;
+		case 'c':
+			command = CMD_PROV_CAP;
+			bin_file = optarg;
+			++cmd_count;
+			break;
+		case 'h':
+			print_help(argv[0]);
+			break;
+		default:
+			print_help(argv[0]);
+			return 0;
+		}
+	}
+
+	if (!socket) {
+		fprintf(stderr, "socket is required\n");
+		print_help(argv[0]);
+		return -1;
+	}
+
+	if (!cmd_count) {
+		fprintf(stderr, "need to specify a command\n");
+		print_help(argv[0]);
+		return -1;
+	}
+
+	/* If applicable, check file exists */
+	if (bin_file) {
+		if (!access(bin_file, F_OK) == 0) {
+			fprintf(stderr, "...Could not open file %s: %s\n", bin_file, strerror(errno));
+			return -1;
+		}
+	}
+
+	/* Run the command */
+	if (command == CMD_READ_LIC)
+		ret = sdsi_certificate_dump(socket);
+	else if (command == CMD_READ_REG)
+		ret = sdsi_read_reg(socket);
+	else if (command == CMD_PROV_AKC)
+		ret = sdsi_provision_akc(socket, bin_file);
+	else
+		ret = sdsi_provision_cap(socket, bin_file);
+
+	return ret;
+}
-- 
2.25.1


  parent reply	other threads:[~2021-12-07 17:16 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-07 17:14 [V2 0/6] Auxiliary bus driver support for Intel PCIe VSEC/DVSEC David E. Box
2021-12-07 17:14 ` [V2 1/6] PCI: Add #defines for accessing PCIe DVSEC fields David E. Box
2021-12-07 17:14 ` [V2 2/6] driver core: auxiliary bus: Add driver data helpers David E. Box
2021-12-07 17:35   ` Andy Shevchenko
2021-12-08  7:03   ` Leon Romanovsky
2021-12-08  7:07     ` Greg KH
2021-12-08  8:32       ` Leon Romanovsky
2021-12-08  8:43         ` Greg KH
2021-12-08  9:12           ` Leon Romanovsky
2021-12-08 10:14             ` Andy Shevchenko
2021-12-08 10:48               ` Leon Romanovsky
2021-12-08  8:43       ` Lee Jones
2021-12-08  8:47         ` Greg KH
2021-12-08  9:13           ` Lee Jones
2021-12-08 10:15           ` Andy Shevchenko
2021-12-09 16:32           ` Bjorn Helgaas
2021-12-09 16:54             ` Andy Shevchenko
2021-12-08  9:18         ` Leon Romanovsky
2021-12-07 17:14 ` [V2 3/6] platform/x86/intel: Move intel_pmt from MFD to Auxiliary Bus David E. Box
2021-12-07 17:14 ` [V2 4/6] platform/x86: Add Intel Software Defined Silicon driver David E. Box
2021-12-08  7:14   ` Leon Romanovsky
2021-12-08 10:42     ` David E. Box
2021-12-08 10:56       ` Leon Romanovsky
2021-12-07 17:14 ` David E. Box [this message]
2021-12-07 17:14 ` [V2 6/6] selftests: sdsi: test sysfs setup David E. Box

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=20211207171448.799376-6-david.e.box@linux.intel.com \
    --to=david.e.box@linux.intel.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bhelgaas@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hdegoede@redhat.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mgross@linux.intel.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=srinivas.pandruvada@intel.com \
    /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).