diff options
-rw-r--r-- | util/inteltool/cpu.c | 53 | ||||
-rw-r--r-- | util/inteltool/inteltool.c | 13 | ||||
-rw-r--r-- | util/inteltool/inteltool.h | 1 |
3 files changed, 65 insertions, 2 deletions
diff --git a/util/inteltool/cpu.c b/util/inteltool/cpu.c index 284e90b50e..db63d36729 100644 --- a/util/inteltool/cpu.c +++ b/util/inteltool/cpu.c @@ -22,6 +22,10 @@ #define MTRR_CAP_MSR 0xfe #define PRMRR_SUPPORTED (1 << 12) #define SGX_SUPPORTED (1 << 2) +#define IA32_TME_ACTIVATE 0x982 +#define TME_SUPPORTED (1 << 13) +#define TME_LOCKED (1) +#define TME_ENABLED (1 << 1) int fd_msr; @@ -212,6 +216,55 @@ int print_sgx(void) return error; } +static int is_tme_supported() +{ + cpuid_result_t cpuid_regs; + + /* + * CPUID leaf 0x7 subleaf 0x0 to detect TME support + * https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key + * -Total-Memory-Encryption-Spec.pdf + */ + + cpuid_regs = cpuid_ext(0x7, 0x0); + return (cpuid_regs.ecx & TME_SUPPORTED); +} + +static msr_t read_tme_activate_msr(){ + return rdmsr_from_cpu(0, IA32_TME_ACTIVATE); +} + +static int is_tme_locked() +{ + msr_t data = read_tme_activate_msr(); + return (data.lo & TME_LOCKED); +} + +static int is_tme_enabled() +{ + msr_t data = read_tme_activate_msr(); + return (data.lo & TME_ENABLED); +} + +void print_tme(void) +{ +#ifndef __DARWIN__ + int tme_supported = is_tme_supported(); + + printf("\n============= Dumping INTEL TME status =============\n"); + + printf("TME supported : %s\n", tme_supported ? "YES" : "NO"); + + if (tme_supported) { + printf("TME locked : %s\n", is_tme_locked() ? "YES" : "NO"); + printf("TME enabled : %s\n", is_tme_enabled() ? "YES" : "NO"); + } + printf("====================================================\n"); +#else + printf("Not Implemented\n"); +#endif +} + int print_intel_core_msrs(void) { unsigned int i, core, id, core_num = get_number_of_cores(); diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index 5ecd8cacb8..d7415b07d2 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -515,6 +515,7 @@ static void print_usage(const char *name) " -M | --msrs: dump CPU MSRs\n" " -A | --ambs: dump AMB registers\n" " -x | --sgx: dump SGX status\n" + " -t | --tme: dump TME status\n" " -a | --all: dump all known (safe) registers\n" " --pcr=PORT_ID: dump all registers of a PCR port\n" " (may be specified max %d times)\n" @@ -575,7 +576,7 @@ int main(int argc, char *argv[]) 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, dump_sgx = 0; + int dump_spi = 0, dump_gfx = 0, dump_ahci = 0, dump_sgx = 0, dump_tme = 0; int dump_lpc = 0; int show_gpio_diffs = 0; size_t pcr_count = 0; @@ -602,10 +603,11 @@ int main(int argc, char *argv[]) {"ahci", 0, 0, 'R'}, {"sgx", 0, 0, 'x'}, {"pcr", required_argument, 0, LONG_OPT_PCR}, + {"tme", 0, 0, 't'}, {0, 0, 0, 0} }; - while ((opt = getopt_long(argc, argv, "vh?gGrplmedPMaAsfRS:x", + while ((opt = getopt_long(argc, argv, "vh?gGrplmedPMaAsfRS:xt", long_options, &option_index)) != EOF) { switch (opt) { case 'v': @@ -667,6 +669,7 @@ int main(int argc, char *argv[]) dump_spi = 1; dump_ahci = 1; dump_sgx = 1; + dump_tme = 1; break; case 'A': dump_ambs = 1; @@ -677,6 +680,9 @@ int main(int argc, char *argv[]) case 'x': dump_sgx = 1; break; + case 't': + dump_tme = 1; + break; case LONG_OPT_PCR: if (pcr_count < MAX_PCR_PORTS) { errno = 0; @@ -869,6 +875,9 @@ int main(int argc, char *argv[]) if (dump_sgx) print_sgx(); + if (dump_tme) + print_tme(); + if (pcr_count) print_pcr_ports(sb, dump_pcr, pcr_count); diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index b3253e7d9c..a528485bf0 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -411,6 +411,7 @@ 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 print_tme(void); void ivybridge_dump_timings(const char *dump_spd_file); #endif |