<p>Pratikkumar V Prajapati has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/20758">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">util/inteltool: Add support of SGX status<br><br>Add support of dumping Intel Software Guard Extension (SGX)<br>status. --sgx or -x is the command line switch to get SGX status.<br>The code iterates through all cores and reads MSRs to check if SGX is<br>supported, enabled and the feature is locked.<br><br>Change-Id: I1f5046c1f6703f5429c8717053ffe9c981cedf6f<br>Signed-off-by: Pratik Prajapati <pratikkumar.v.prajapati@intel.com><br>---<br>M util/inteltool/cpu.c<br>M util/inteltool/inteltool.c<br>M util/inteltool/inteltool.h<br>3 files changed, 160 insertions(+), 3 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/20758/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/util/inteltool/cpu.c b/util/inteltool/cpu.c<br>index afafc63..4ccc46a 100644<br>--- a/util/inteltool/cpu.c<br>+++ b/util/inteltool/cpu.c<br>@@ -28,6 +28,13 @@<br> # define BREG     "%%ebx"<br> #endif<br> <br>+#define IA32_FEATURE_CONTROL    0x3a<br>+#define SGX_GLOBAL_ENABLED       (1 << 18)<br>+#define FEATURE_CONTROL_LOCKED        (1)<br>+#define MTRR_CAP_MSR              0xfe<br>+#define PRMRR_SUPPORTED  (1<<12)<br>+#define SGX_SUPPORTED           (1<<2)<br>+<br> int fd_msr;<br> <br> unsigned int cpuid(unsigned int op)<br>@@ -46,6 +53,26 @@<br> #endif<br> <br>        return ret;<br>+}<br>+<br>+inline cpuid_result_t cpuid_ext(int op, unsigned int ecx)<br>+{<br>+   cpuid_result_t result;<br>+<br>+#ifndef __DARWIN__<br>+       asm volatile(<br>+                        "mov %%ebx, %%edi;"<br>+                        "cpuid;"<br>+                   "mov %%ebx, %%esi;"<br>+                        "mov %%edi, %%ebx;"<br>+                        : "=a" (result.eax),<br>+                       "=S" (result.ebx),<br>+                 "=c" (result.ecx),<br>+                 "=d" (result.edx)<br>+                  : "0" (op), "2" (ecx)<br>+                    : "edi");<br>+#endif<br>+ return result;<br> }<br> <br> #ifndef __DARWIN__<br>@@ -80,8 +107,121 @@<br> <br>   return msr;<br> }<br>+<br>+static int open_and_seek(int cpu, unsigned long msr, int mode, int *fd)<br>+{<br>+     char dev[512];<br>+       char temp_string[50];<br>+<br>+     snprintf(dev, sizeof(dev), "/dev/cpu/%d/msr", cpu);<br>+        *fd = open(dev, mode);<br>+<br>+    if (*fd < 0) {<br>+            sprintf(temp_string,<br>+                 "open(\"%s\"): %s\n", dev, strerror(errno));<br>+             perror(temp_string);<br>+         return -1;<br>+   }<br>+<br>+ if (lseek(*fd, msr, SEEK_SET) == (off_t)-1) {<br>+                sprintf(temp_string, "lseek(%lu): %s\n", msr, strerror(errno));<br>+            perror(temp_string);<br>+         close(*fd);<br>+          return -1;<br>+   }<br>+<br>+ return 0;<br>+}<br>+<br>+msr_t rdmsr_from_cpu(int cpu, unsigned long addr)<br>+{<br>+     int fd;<br>+      msr_t msr = { 0xffffffff, 0xffffffff };<br>+      uint32_t buf[2];<br>+     char temp_string[50];<br>+<br>+     if (open_and_seek(cpu, addr, O_RDONLY, &fd) < 0) {<br>+            sprintf(temp_string, "Could not read MSR for CPU#%d", cpu);<br>+                perror(temp_string);<br>+ }<br>+<br>+ if (read(fd, buf, 8) == 8) {<br>+         msr.lo = buf[0];<br>+             msr.hi = buf[1];<br>+     }<br>+<br>+ close(fd);<br>+<br>+        return msr;<br>+}<br>+<br>+int get_number_of_cpus(void)<br>+{<br>+        return sysconf(_SC_NPROCESSORS_ONLN);<br>+}<br>+<br>+int is_sgx_supported(int cpunum)<br>+{<br>+  cpuid_result_t cpuid_regs;<br>+   msr_t msr;<br>+<br>+        /* CPUID leaf 0x7 subleaf 0x0 to detect SGX support<br>+   * details are mentioned in Intel SDM Chap.36- section 36.7<br>+   */<br>+  cpuid_regs = cpuid_ext(0x7, 0x0);<br>+    msr = rdmsr_from_cpu(cpunum, MTRR_CAP_MSR);<br>+  return ((cpuid_regs.ebx & SGX_SUPPORTED) && (msr.lo & PRMRR_SUPPORTED));<br>+}<br>+<br>+int is_sgx_enabled(int cpunum)<br>+{<br>+ msr_t data;<br>+  data = rdmsr_from_cpu(cpunum, IA32_FEATURE_CONTROL);<br>+ return (data.lo & SGX_GLOBAL_ENABLED);<br>+}<br>+<br>+int is_sgx_locked(int cpunum)<br>+{<br>+        msr_t data;<br>+  data = rdmsr_from_cpu(cpunum, IA32_FEATURE_CONTROL);<br>+ return (data.lo & FEATURE_CONTROL_LOCKED);<br>+}<br>+<br> #endif<br> <br>+int print_sgx(void)<br>+{<br>+  int error = -1;<br>+#ifndef __DARWIN__<br>+ int ncpus = get_number_of_cpus();<br>+    int i = 0;<br>+   char temp_string[50];<br>+<br>+     printf("\n============= Dumping INTEL SGX status =============");<br>+<br>+       if (ncpus < 1) {<br>+          sprintf(temp_string, "Failed to get number of CPUs\n");<br>+            perror(temp_string);<br>+         error = -1;<br>+  } else {<br>+             printf("\nNumber of CPUs = %d\n", ncpus);<br>+          for (i = 0; i < ncpus ; i++) {<br>+<br>+                 printf("------------- CPU %d ----------------\n", i);<br>+                      printf("SGX supported             : %s\n",<br>+                                 is_sgx_supported(i) ? "YES" : "NO");<br>+                     printf("SGX enabled               : %s\n",<br>+                                 is_sgx_enabled(i) ? "YES" : "NO");<br>+                       printf("Feature Control locked    : %s\n",<br>+                                 is_sgx_locked(i) ? "YES" : "NO");<br>+                }<br>+            error = 0;<br>+   }<br>+    printf("====================================================\n");<br>+#endif<br>+ return error;<br>+}<br>+<br> int print_intel_core_msrs(void)<br> {<br>    unsigned int i, core, id;<br>diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c<br>index ccb8fac..9e33e14 100644<br>--- a/util/inteltool/inteltool.c<br>+++ b/util/inteltool/inteltool.c<br>@@ -244,7 +244,7 @@<br> <br> void print_usage(const char *name)<br> {<br>-  printf("usage: %s [-vh?gGrpmedPMaAsfSR]\n", name);<br>+ printf("usage: %s [-vh?gGrpmedPMaAsfSRx]\n", name);<br>         printf("\n"<br>              "   -v | --version:                   print the version\n"<br>          "   -h | --help:                      print this help\n\n"<br>@@ -262,6 +262,7 @@<br>             "   -P | --pciexpress:                dump northbridge PCIEXBAR registers\n\n"<br>              "   -M | --msrs:                      dump CPU MSRs\n"<br>              "   -A | --ambs:                      dump AMB registers\n"<br>+        "   -x | --sgx:                       dump SGX status\n"<br>            "   -a | --all:                       dump all known (safe) registers\n"<br>            "\n");<br>         exit(1);<br>@@ -280,7 +281,7 @@<br>         int dump_gpios = 0, dump_mchbar = 0, dump_rcba = 0;<br>   int dump_pmbase = 0, dump_epbar = 0, dump_dmibar = 0;<br>         int dump_pciexbar = 0, dump_coremsrs = 0, dump_ambs = 0;<br>-     int dump_spi = 0, dump_gfx = 0, dump_ahci = 0;<br>+       int dump_spi = 0, dump_gfx = 0, dump_ahci = 0, dump_sgx = 0;<br>  int show_gpio_diffs = 0;<br> <br>   static struct option long_options[] = {<br>@@ -301,10 +302,11 @@<br>                {"all", 0, 0, 'a'},<br>                 {"gfx", 0, 0, 'f'},<br>                 {"ahci", 0, 0, 'R'},<br>+               {"sgx", 0, 0, 'x'},<br>                 {0, 0, 0, 0}<br>  };<br> <br>-        while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaAsfRS:",<br>+       while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaAsfRS:x",<br>                                   long_options, &option_index)) != EOF) {<br>               switch (opt) {<br>                case 'v':<br>@@ -361,12 +363,16 @@<br>                      dump_ambs = 1;<br>                        dump_spi = 1;<br>                         dump_ahci = 1;<br>+                       dump_sgx = 1;<br>                         break;<br>                case 'A':<br>                     dump_ambs = 1;<br>                        break;<br>                case 's':<br>                     dump_spi = 1;<br>+                        break;<br>+               case 'x':<br>+                    dump_sgx = 1;<br>                         break;<br>                case 'h':<br>             case '?':<br>@@ -575,6 +581,10 @@<br>               print_ahci(ahci);<br>     }<br> <br>+ if (dump_sgx) {<br>+              print_sgx();<br>+ }<br>+<br>  /* Clean up */<br>        if (ahci)<br>             pci_free_dev(ahci);<br>diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h<br>index e463260..d4aa96f 100644<br>--- a/util/inteltool/inteltool.h<br>+++ b/util/inteltool/inteltool.h<br>@@ -224,6 +224,12 @@<br> int freebsd_wrmsr(int addr, msr_t msr);<br> #endif<br> typedef struct { uint16_t addr; int size; char *name; } io_register_t;<br>+typedef struct {<br>+    uint32_t eax;<br>+        uint32_t ebx;<br>+        uint32_t ecx;<br>+        uint32_t edx;<br>+} cpuid_result_t;<br> <br> void *map_physical(uint64_t phys_addr, size_t len);<br> void unmap_physical(void *virt_addr, size_t len);<br>@@ -241,4 +247,5 @@<br> int print_spi(struct pci_dev *sb);<br> int print_gfx(struct pci_dev *gfx);<br> int print_ahci(struct pci_dev *ahci);<br>+int print_sgx(void);<br> void ivybridge_dump_timings(const char *dump_spd_file);<br></pre><p>To view, visit <a href="https://review.coreboot.org/20758">change 20758</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/20758"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I1f5046c1f6703f5429c8717053ffe9c981cedf6f </div>
<div style="display:none"> Gerrit-Change-Number: 20758 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Pratikkumar V Prajapati <pratikkumar.v.prajapati@intel.com> </div>