All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.