[coreboot-gerrit] Change in coreboot[master]: util/inteltool: Add support of SGX status

Pratikkumar V Prajapati (Code Review) gerrit at coreboot.org
Mon Jul 24 23:00:21 CEST 2017


Pratikkumar V Prajapati has uploaded this change for review. ( https://review.coreboot.org/20758


Change subject: util/inteltool: Add support of SGX status
......................................................................

util/inteltool: Add support of SGX status

Add support of dumping Intel Software Guard Extension (SGX)
status. --sgx or -x is the command line switch to get SGX status.
The code iterates through all cores and reads MSRs to check if SGX is
supported, enabled and the feature is locked.

Change-Id: I1f5046c1f6703f5429c8717053ffe9c981cedf6f
Signed-off-by: Pratik Prajapati <pratikkumar.v.prajapati at intel.com>
---
M util/inteltool/cpu.c
M util/inteltool/inteltool.c
M util/inteltool/inteltool.h
3 files changed, 160 insertions(+), 3 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/20758/1

diff --git a/util/inteltool/cpu.c b/util/inteltool/cpu.c
index afafc63..4ccc46a 100644
--- a/util/inteltool/cpu.c
+++ b/util/inteltool/cpu.c
@@ -28,6 +28,13 @@
 # define BREG	"%%ebx"
 #endif
 
+#define IA32_FEATURE_CONTROL	0x3a
+#define SGX_GLOBAL_ENABLED	(1 << 18)
+#define FEATURE_CONTROL_LOCKED	(1)
+#define MTRR_CAP_MSR		0xfe
+#define PRMRR_SUPPORTED	(1<<12)
+#define SGX_SUPPORTED		(1<<2)
+
 int fd_msr;
 
 unsigned int cpuid(unsigned int op)
@@ -46,6 +53,26 @@
 #endif
 
 	return ret;
+}
+
+inline cpuid_result_t cpuid_ext(int op, unsigned int ecx)
+{
+	cpuid_result_t result;
+
+#ifndef __DARWIN__
+	asm volatile(
+			"mov %%ebx, %%edi;"
+			"cpuid;"
+			"mov %%ebx, %%esi;"
+			"mov %%edi, %%ebx;"
+			: "=a" (result.eax),
+			"=S" (result.ebx),
+			"=c" (result.ecx),
+			"=d" (result.edx)
+			: "0" (op), "2" (ecx)
+			: "edi");
+#endif
+	return result;
 }
 
 #ifndef __DARWIN__
@@ -80,8 +107,121 @@
 
 	return msr;
 }
+
+static int open_and_seek(int cpu, unsigned long msr, int mode, int *fd)
+{
+	char dev[512];
+	char temp_string[50];
+
+	snprintf(dev, sizeof(dev), "/dev/cpu/%d/msr", cpu);
+	*fd = open(dev, mode);
+
+	if (*fd < 0) {
+		sprintf(temp_string,
+			"open(\"%s\"): %s\n", dev, strerror(errno));
+		perror(temp_string);
+		return -1;
+	}
+
+	if (lseek(*fd, msr, SEEK_SET) == (off_t)-1) {
+		sprintf(temp_string, "lseek(%lu): %s\n", msr, strerror(errno));
+		perror(temp_string);
+		close(*fd);
+		return -1;
+	}
+
+	return 0;
+}
+
+msr_t rdmsr_from_cpu(int cpu, unsigned long addr)
+{
+	int fd;
+	msr_t msr = { 0xffffffff, 0xffffffff };
+	uint32_t buf[2];
+	char temp_string[50];
+
+	if (open_and_seek(cpu, addr, O_RDONLY, &fd) < 0) {
+		sprintf(temp_string, "Could not read MSR for CPU#%d", cpu);
+		perror(temp_string);
+	}
+
+	if (read(fd, buf, 8) == 8) {
+		msr.lo = buf[0];
+		msr.hi = buf[1];
+	}
+
+	close(fd);
+
+	return msr;
+}
+
+int get_number_of_cpus(void)
+{
+	return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+int is_sgx_supported(int cpunum)
+{
+	cpuid_result_t cpuid_regs;
+	msr_t msr;
+
+	/* CPUID leaf 0x7 subleaf 0x0 to detect SGX support
+	 * details are mentioned in Intel SDM Chap.36- section 36.7
+	 */
+	cpuid_regs = cpuid_ext(0x7, 0x0);
+	msr = rdmsr_from_cpu(cpunum, MTRR_CAP_MSR);
+	return ((cpuid_regs.ebx & SGX_SUPPORTED) && (msr.lo & PRMRR_SUPPORTED));
+}
+
+int is_sgx_enabled(int cpunum)
+{
+	msr_t data;
+	data = rdmsr_from_cpu(cpunum, IA32_FEATURE_CONTROL);
+	return (data.lo & SGX_GLOBAL_ENABLED);
+}
+
+int is_sgx_locked(int cpunum)
+{
+	msr_t data;
+	data = rdmsr_from_cpu(cpunum, IA32_FEATURE_CONTROL);
+	return (data.lo & FEATURE_CONTROL_LOCKED);
+}
+
 #endif
 
+int print_sgx(void)
+{
+	int error = -1;
+#ifndef __DARWIN__
+	int ncpus = get_number_of_cpus();
+	int i = 0;
+	char temp_string[50];
+
+	printf("\n============= Dumping INTEL SGX status =============");
+
+	if (ncpus < 1) {
+		sprintf(temp_string, "Failed to get number of CPUs\n");
+		perror(temp_string);
+		error = -1;
+	} else {
+		printf("\nNumber of CPUs = %d\n", ncpus);
+		for (i = 0; i < ncpus ; i++) {
+
+			printf("------------- CPU %d ----------------\n", i);
+			printf("SGX supported             : %s\n",
+					is_sgx_supported(i) ? "YES" : "NO");
+			printf("SGX enabled               : %s\n",
+					is_sgx_enabled(i) ? "YES" : "NO");
+			printf("Feature Control locked    : %s\n",
+					is_sgx_locked(i) ? "YES" : "NO");
+		}
+		error = 0;
+	}
+	printf("====================================================\n");
+#endif
+	return error;
+}
+
 int print_intel_core_msrs(void)
 {
 	unsigned int i, core, id;
diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c
index ccb8fac..9e33e14 100644
--- a/util/inteltool/inteltool.c
+++ b/util/inteltool/inteltool.c
@@ -244,7 +244,7 @@
 
 void print_usage(const char *name)
 {
-	printf("usage: %s [-vh?gGrpmedPMaAsfSR]\n", name);
+	printf("usage: %s [-vh?gGrpmedPMaAsfSRx]\n", name);
 	printf("\n"
 	     "   -v | --version:                   print the version\n"
 	     "   -h | --help:                      print this help\n\n"
@@ -262,6 +262,7 @@
 	     "   -P | --pciexpress:                dump northbridge PCIEXBAR registers\n\n"
 	     "   -M | --msrs:                      dump CPU MSRs\n"
 	     "   -A | --ambs:                      dump AMB registers\n"
+	     "   -x | --sgx:                       dump SGX status\n"
 	     "   -a | --all:                       dump all known (safe) registers\n"
 	     "\n");
 	exit(1);
@@ -280,7 +281,7 @@
 	int dump_gpios = 0, dump_mchbar = 0, dump_rcba = 0;
 	int dump_pmbase = 0, dump_epbar = 0, dump_dmibar = 0;
 	int dump_pciexbar = 0, dump_coremsrs = 0, dump_ambs = 0;
-	int dump_spi = 0, dump_gfx = 0, dump_ahci = 0;
+	int dump_spi = 0, dump_gfx = 0, dump_ahci = 0, dump_sgx = 0;
 	int show_gpio_diffs = 0;
 
 	static struct option long_options[] = {
@@ -301,10 +302,11 @@
 		{"all", 0, 0, 'a'},
 		{"gfx", 0, 0, 'f'},
 		{"ahci", 0, 0, 'R'},
+		{"sgx", 0, 0, 'x'},
 		{0, 0, 0, 0}
 	};
 
-	while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaAsfRS:",
+	while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaAsfRS:x",
                                   long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'v':
@@ -361,12 +363,16 @@
 			dump_ambs = 1;
 			dump_spi = 1;
 			dump_ahci = 1;
+			dump_sgx = 1;
 			break;
 		case 'A':
 			dump_ambs = 1;
 			break;
 		case 's':
 			dump_spi = 1;
+			break;
+		case 'x':
+			dump_sgx = 1;
 			break;
 		case 'h':
 		case '?':
@@ -575,6 +581,10 @@
 		print_ahci(ahci);
 	}
 
+	if (dump_sgx) {
+		print_sgx();
+	}
+
 	/* Clean up */
 	if (ahci)
 		pci_free_dev(ahci);
diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h
index e463260..d4aa96f 100644
--- a/util/inteltool/inteltool.h
+++ b/util/inteltool/inteltool.h
@@ -224,6 +224,12 @@
 int freebsd_wrmsr(int addr, msr_t msr);
 #endif
 typedef struct { uint16_t addr; int size; char *name; } io_register_t;
+typedef struct {
+	uint32_t eax;
+	uint32_t ebx;
+	uint32_t ecx;
+	uint32_t edx;
+} cpuid_result_t;
 
 void *map_physical(uint64_t phys_addr, size_t len);
 void unmap_physical(void *virt_addr, size_t len);
@@ -241,4 +247,5 @@
 int print_spi(struct pci_dev *sb);
 int print_gfx(struct pci_dev *gfx);
 int print_ahci(struct pci_dev *ahci);
+int print_sgx(void);
 void ivybridge_dump_timings(const char *dump_spd_file);

-- 
To view, visit https://review.coreboot.org/20758
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1f5046c1f6703f5429c8717053ffe9c981cedf6f
Gerrit-Change-Number: 20758
Gerrit-PatchSet: 1
Gerrit-Owner: Pratikkumar V Prajapati <pratikkumar.v.prajapati at intel.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170724/b26a7f2a/attachment-0001.html>


More information about the coreboot-gerrit mailing list