From a04aa3d5662149b70f31e0e6584bd8c6087b5f3b Mon Sep 17 00:00:00 2001 From: Pratik Prajapati Date: Mon, 12 Jun 2017 23:02:36 -0700 Subject: sgx: Move SGX code to intel/common/block CONFIG_SOC_INTEL_COMMON_BLOCK_SGX controls building. The SGX feature is still enabled from devicetree.cb. As of now this SGX init supports only KBL (SKL not tested). Support of SGX for new SOCs would be added incrementally in this common code base. Change-Id: I0fbba364b7342e686a2287ea1a910ef9a4eed595 Signed-off-by: Pratik Prajapati Reviewed-on: https://review.coreboot.org/20173 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- .../intel/common/block/include/intelblocks/msr.h | 8 + .../intel/common/block/include/intelblocks/sgx.h | 30 ++++ src/soc/intel/common/block/sgx/Kconfig | 7 + src/soc/intel/common/block/sgx/Makefile.inc | 1 + src/soc/intel/common/block/sgx/sgx.c | 158 ++++++++++++++++++++ src/soc/intel/skylake/Kconfig | 1 + src/soc/intel/skylake/Makefile.inc | 1 - src/soc/intel/skylake/cpu.c | 16 +- src/soc/intel/skylake/include/soc/cpu.h | 1 - src/soc/intel/skylake/include/soc/msr.h | 4 - src/soc/intel/skylake/sgx.c | 161 --------------------- 11 files changed, 219 insertions(+), 169 deletions(-) create mode 100644 src/soc/intel/common/block/include/intelblocks/sgx.h create mode 100644 src/soc/intel/common/block/sgx/Kconfig create mode 100644 src/soc/intel/common/block/sgx/Makefile.inc create mode 100644 src/soc/intel/common/block/sgx/sgx.c delete mode 100644 src/soc/intel/skylake/sgx.c (limited to 'src/soc') diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 6d78ed8c2f..1025c28e92 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -18,8 +18,10 @@ #define MSR_CORE_THREAD_COUNT 0x35 #define IA32_FEATURE_CONTROL 0x3a +#define FEATURE_CONTROL_LOCK (1) #define CPUID_VMX (1 << 5) #define CPUID_SMX (1 << 6) +#define SGX_GLOBAL_ENABLE (1 << 18) #define PLATFORM_INFO_SET_TDP (1 << 29) #define MSR_PLATFORM_INFO 0xce #define MSR_PMG_CST_CONFIG_CONTROL 0xe2 @@ -31,6 +33,8 @@ #define IO_MWAIT_REDIRECT_MASK 0x400 /* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */ #define CST_CFG_LOCK_MASK 0x8000 +#define MSR_BIOS_UPGD_TRIG 0x7a +#define SGX_ACTIVATE_BIT (1) #define MSR_PMG_IO_CAPTURE_BASE 0xe4 #define MSR_POWER_MISC 0x120 #define ENABLE_IA_UNTRUSTED (1 << 6) @@ -62,6 +66,7 @@ #define MISC_PWR_MGMT_ISST_EN_INT (1 << 7) #define MISC_PWR_MGMT_ISST_EN_EPP (1 << 12) #define MSR_TURBO_RATIO_LIMIT 0x1ad +#define PRMRR_PHYS_BASE_MSR 0x1f4 #define PRMRR_PHYS_MASK_MSR 0x1f5 #define PRMRR_PHYS_MASK_LOCK (1 << 10) #define PRMRR_PHYS_MASK_VALID (1 << 11) @@ -69,6 +74,8 @@ #define MSR_EVICT_CTL 0x2e0 #define UNCORE_PRMRR_PHYS_BASE_MSR 0x2f4 #define UNCORE_PRMRR_PHYS_MASK_MSR 0x2f5 +#define MSR_SGX_OWNEREPOCH0 0x300 +#define MSR_SGX_OWNEREPOCH1 0x301 #define IA32_MC0_CTL 0x400 #define IA32_MC0_STATUS 0x401 #define SMM_FEATURE_CONTROL_MSR 0x4e0 @@ -124,5 +131,6 @@ #define SMRR_SUPPORTED (1<<11) #define PRMRR_SUPPORTED (1<<12) +#define SGX_SUPPORTED (1<<2) #endif /* SOC_INTEL_COMMON_MSR_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/sgx.h b/src/soc/intel/common/block/include/intelblocks/sgx.h new file mode 100644 index 0000000000..03d4ab5123 --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/sgx.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_INTEL_COMMON_BLOCK_SGX_H +#define SOC_INTEL_COMMON_BLOCK_SGX_H + +/* + * Lock SGX memory. + * CPU specific code needs to provide the implementation. + */ +void cpu_lock_sgx_memory(void); + +/* + * Configure SGX. + */ +void sgx_configure(const void *microcode_patch); + +#endif /* SOC_INTEL_COMMON_BLOCK_SGX_H */ diff --git a/src/soc/intel/common/block/sgx/Kconfig b/src/soc/intel/common/block/sgx/Kconfig new file mode 100644 index 0000000000..7889582007 --- /dev/null +++ b/src/soc/intel/common/block/sgx/Kconfig @@ -0,0 +1,7 @@ +config SOC_INTEL_COMMON_BLOCK_SGX + bool + default n + help + Software Guard eXtension(SGX) Feature. Intel SGX is a set of new CPU + instructions that can be used by applications to set aside privat + regions of code and data. diff --git a/src/soc/intel/common/block/sgx/Makefile.inc b/src/soc/intel/common/block/sgx/Makefile.inc new file mode 100644 index 0000000000..3fa18d8873 --- /dev/null +++ b/src/soc/intel/common/block/sgx/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX) += sgx.c diff --git a/src/soc/intel/common/block/sgx/sgx.c b/src/soc/intel/common/block/sgx/sgx.c new file mode 100644 index 0000000000..5a0b61dda6 --- /dev/null +++ b/src/soc/intel/common/block/sgx/sgx.c @@ -0,0 +1,158 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int is_sgx_supported(void) +{ + struct cpuid_result cpuid_regs; + msr_t msr; + + cpuid_regs = cpuid_ext(0x7, 0x0); /* EBX[2] is feature capability */ + msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */ + return ((cpuid_regs.ebx & SGX_SUPPORTED) && (msr.lo & PRMRR_SUPPORTED)); +} + +static int configure_core_prmrr(void) +{ + msr_t prmrr_base; + msr_t prmrr_mask; + msr_t msr; + + /* + * PRMRR base and mask are read from the UNCORE PRMRR MSRs + * that are already set in FSP-M. + */ + prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR); + prmrr_mask = rdmsr(UNCORE_PRMRR_PHYS_MASK_MSR); + if (!prmrr_base.lo) { + printk(BIOS_ERR, "SGX Error: Uncore PRMRR is not set!\n"); + return -1; + } + + msr = rdmsr(PRMRR_PHYS_MASK_MSR); + /* If it is locked don't attempt to write PRMRR MSRs. */ + if (msr.lo & PRMRR_PHYS_MASK_LOCK) + return 0; + + /* Program core PRMRR MSRs */ + prmrr_base.lo |= MTRR_TYPE_WRBACK; /* cache writeback mem attrib */ + wrmsr(PRMRR_PHYS_BASE_MSR, prmrr_base); + prmrr_mask.lo &= ~PRMRR_PHYS_MASK_VALID; /* Do not set the valid bit */ + prmrr_mask.lo |= PRMRR_PHYS_MASK_LOCK; /* Lock it */ + wrmsr(PRMRR_PHYS_MASK_MSR, prmrr_mask); + return 0; +} + +static void enable_sgx(void) +{ + msr_t msr; + + msr = rdmsr(IA32_FEATURE_CONTROL); + /* Only enable it when it is not locked */ + if ((msr.lo & FEATURE_CONTROL_LOCK) == 0) { + msr.lo |= SGX_GLOBAL_ENABLE; /* Enable it */ + wrmsr(IA32_FEATURE_CONTROL, msr); + } +} + +static void lock_sgx(void) +{ + msr_t msr; + + msr = rdmsr(IA32_FEATURE_CONTROL); + /* If it is locked don't attempt to lock it again. */ + if ((msr.lo & 1) == 0) { + msr.lo |= 1; /* Lock it */ + wrmsr(IA32_FEATURE_CONTROL, msr); + } +} + +static int owner_epoch_update(void) +{ + /* + * TODO - the Owner Epoch update mechanism is not determined yet, + * for PoC just write '0's to the MSRs. + */ + msr_t msr = {0, 0}; + + wrmsr(MSR_SGX_OWNEREPOCH0, msr); + wrmsr(MSR_SGX_OWNEREPOCH1, msr); + return 0; +} + +static void activate_sgx(void) +{ + msr_t msr; + + /* + * Activate SGX feature by writing 1b to MSR 0x7A on all threads. + * BIOS must ensure bit 0 is set prior to writing to it, then read it + * back and verify the bit is cleared to confirm SGX activation. + */ + msr = rdmsr(MSR_BIOS_UPGD_TRIG); + if (msr.lo & SGX_ACTIVATE_BIT) { + wrmsr(MSR_BIOS_UPGD_TRIG, + (msr_t) {.lo = SGX_ACTIVATE_BIT, .hi = 0}); + /* Read back to verify it is activated */ + msr = rdmsr(MSR_BIOS_UPGD_TRIG); + if (msr.lo & SGX_ACTIVATE_BIT) + printk(BIOS_ERR, "SGX activation failed.\n"); + else + printk(BIOS_INFO, "SGX activation was successful.\n"); + } else { + printk(BIOS_ERR, "SGX feature is deactivated.\n"); + } +} + +void sgx_configure(const void *microcode_patch) +{ + device_t dev = SA_DEV_ROOT; + config_t *conf = dev->chip_info; + + if (!conf->sgx_enable || !is_sgx_supported()) + return; + + /* Initialize PRMRR core MSRs */ + if (configure_core_prmrr() < 0) + return; + + /* Enable the SGX feature */ + enable_sgx(); + + /* Update the owner epoch value */ + if (owner_epoch_update() < 0) + return; + + /* Ensure to lock memory before reload microcode patch */ + cpu_lock_sgx_memory(); + + /* Reload the microcode patch */ + intel_microcode_load_unlocked(microcode_patch); + + /* Lock the SGX feature */ + lock_sgx(); + + /* Activate the SGX feature */ + activate_sgx(); +} diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 1dc80552ce..c558886584 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -65,6 +65,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_INTEL_COMMON_BLOCK_SA select SOC_INTEL_COMMON_BLOCK_SATA select SOC_INTEL_COMMON_BLOCK_SCS + select SOC_INTEL_COMMON_BLOCK_SGX select SOC_INTEL_COMMON_BLOCK_SMBUS select SOC_INTEL_COMMON_BLOCK_TIMER select SOC_INTEL_COMMON_BLOCK_UART diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index 75d57a9c19..0a8d10577e 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -63,7 +63,6 @@ ramstage-y += pmc.c ramstage-y += pmutil.c ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c ramstage-y += sd.c -ramstage-y += sgx.c ramstage-y += smi.c ramstage-y += smmrelocate.c ramstage-y += spi.c diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index e3be73870f..7f455e0d59 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -422,7 +423,7 @@ void soc_core_init(device_t cpu, const void *microcode) enable_turbo(); /* Configure SGX */ - configure_sgx(microcode); + sgx_configure(microcode); } static int adjust_apic_id(int index, int apic_id) @@ -489,7 +490,7 @@ void soc_init_cpus(struct bus *cpu_bus, const void *microcode) * here to get SGX enabled on BSP. This behavior needs to root-caused * and we shall not have this redundant call. */ - configure_sgx(microcode); + sgx_configure(microcode); } int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) @@ -514,3 +515,14 @@ int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) return (msr1.lo & PRMRR_SUPPORTED) && (current_patch_id == new_patch_id - 1); } + +void cpu_lock_sgx_memory(void) +{ + msr_t msr; + + msr = rdmsr(MSR_LT_LOCK_MEMORY); + if ((msr.lo & 1) == 0) { + msr.lo |= 1; /* Lock it */ + wrmsr(MSR_LT_LOCK_MEMORY, msr); + } +} diff --git a/src/soc/intel/skylake/include/soc/cpu.h b/src/soc/intel/skylake/include/soc/cpu.h index 059367aaa9..8073fcdded 100644 --- a/src/soc/intel/skylake/include/soc/cpu.h +++ b/src/soc/intel/skylake/include/soc/cpu.h @@ -56,6 +56,5 @@ void set_power_limits(u8 power_limit_1_time); u32 cpu_family_model(void); u32 cpu_stepping(void); int cpu_is_ult(void); -void configure_sgx(const void *microcode_patch); #endif diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h index bb4b8e72ac..81b6cc9de1 100644 --- a/src/soc/intel/skylake/include/soc/msr.h +++ b/src/soc/intel/skylake/include/soc/msr.h @@ -20,7 +20,6 @@ #include #define MSR_PIC_MSG_CONTROL 0x2e -#define MSR_BIOS_UPGD_TRIG 0x7a #define MSR_EMULATE_PM_TIMER 0x121 #define EMULATE_PM_TMR_EN (1 << 16) #define EMULATE_DELAY_OFFSET_VALUE 20 @@ -31,11 +30,8 @@ #define ENERGY_POLICY_NORMAL 6 #define ENERGY_POLICY_POWERSAVE 15 #define IA32_PACKAGE_THERM_INTERRUPT 0x1b2 -#define PRMRR_PHYS_BASE_MSR 0x1f4 #define IA32_PLATFORM_DCA_CAP 0x1f8 #define MSR_LT_LOCK_MEMORY 0x2e7 -#define MSR_SGX_OWNEREPOCH0 0x300 -#define MSR_SGX_OWNEREPOCH1 0x301 #define MSR_VR_CURRENT_CONFIG 0x601 #define MSR_VR_MISC_CONFIG 0x603 #define MSR_VR_MISC_CONFIG2 0x636 diff --git a/src/soc/intel/skylake/sgx.c b/src/soc/intel/skylake/sgx.c deleted file mode 100644 index 0e887de2ed..0000000000 --- a/src/soc/intel/skylake/sgx.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2017 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int is_sgx_supported(void) -{ - struct cpuid_result cpuid_regs; - msr_t msr; - - cpuid_regs = cpuid_ext(0x7, 0x0); /* EBX[2] is feature capability */ - msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */ - return ((cpuid_regs.ebx & 0x4) && (msr.lo & PRMRR_SUPPORTED)); -} - -static int configure_core_prmrr(void) -{ - msr_t prmrr_base; - msr_t prmrr_mask; - msr_t msr; - - /* - * PRMRR base and mask are read from the UNCORE PRMRR MSRs - * that are already set in FSP-M. - */ - prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR); - prmrr_mask = rdmsr(UNCORE_PRMRR_PHYS_MASK_MSR); - if (!prmrr_base.lo) { - printk(BIOS_ERR, "SGX Error: Uncore PRMRR is not set!\n"); - return -1; - } - - msr = rdmsr(PRMRR_PHYS_MASK_MSR); - /* If it is locked don't attempt to write PRMRR MSRs. */ - if (msr.lo & PRMRR_PHYS_MASK_LOCK) - return 0; - - /* Program core PRMRR MSRs */ - prmrr_base.lo |= 0x6; /* Set memory attribute to cache writeback */ - wrmsr(PRMRR_PHYS_BASE_MSR, prmrr_base); - prmrr_mask.lo &= ~PRMRR_PHYS_MASK_VALID; /* Do not set the valid bit */ - prmrr_mask.lo |= PRMRR_PHYS_MASK_LOCK; /* Lock it */ - wrmsr(PRMRR_PHYS_MASK_MSR, prmrr_mask); - return 0; -} - -static void enable_sgx(void) -{ - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - /* Only enable it when it is not locked */ - if ((msr.lo & 1) == 0) { - msr.lo |= (1 << 18); /* Enable it */ - wrmsr(IA32_FEATURE_CONTROL, msr); - } -} - -static void lock_sgx(void) -{ - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - /* If it is locked don't attempt to lock it again. */ - if ((msr.lo & 1) == 0) { - msr.lo |= 1; /* Lock it */ - wrmsr(IA32_FEATURE_CONTROL, msr); - } -} - -static int owner_epoch_update(void) -{ - /* - * TODO - the Owner Epoch update mechanism is not determined yet, - * for PoC just write '0's to the MSRs. - */ - msr_t msr = {0, 0}; - - wrmsr(MSR_SGX_OWNEREPOCH0, msr); - wrmsr(MSR_SGX_OWNEREPOCH1, msr); - return 0; -} - -static void activate_sgx(void) -{ - msr_t msr; - - /* - * Activate SGX feature by writing 1b to MSR 0x7A on all threads. - * BIOS must ensure bit 0 is set prior to writing to it, then read it - * back and verify the bit is cleared to confirm SGX activation. - */ - msr = rdmsr(MSR_BIOS_UPGD_TRIG); - if (msr.lo & 0x1) { - wrmsr(MSR_BIOS_UPGD_TRIG, (msr_t) {.lo = 0x1, .hi = 0}); - /* Read back to verify it is activated */ - msr = rdmsr(MSR_BIOS_UPGD_TRIG); - if (msr.lo & 0x1) - printk(BIOS_ERR, "SGX activation failed.\n"); - else - printk(BIOS_INFO, "SGX activation was successful.\n"); - } else { - printk(BIOS_ERR, "SGX feature is deactivated.\n"); - } -} - -void configure_sgx(const void *microcode_patch) -{ - device_t dev = SA_DEV_ROOT; - config_t *conf = dev->chip_info; - msr_t msr; - - if (!conf->sgx_enable || !is_sgx_supported()) - return; - - /* Initialize PRMRR core MSRs */ - if (configure_core_prmrr() < 0) - return; - - /* Enable the SGX feature */ - enable_sgx(); - - /* Update the owner epoch value */ - if (owner_epoch_update() < 0) - return; - - /* Ensure to lock memory before reload microcode patch */ - msr = rdmsr(MSR_LT_LOCK_MEMORY); - if ((msr.lo & 1) == 0) { - msr.lo |= 1; /* Lock it */ - wrmsr(MSR_LT_LOCK_MEMORY, msr); - } - - /* Reload the microcode patch */ - intel_microcode_load_unlocked(microcode_patch); - - /* Lock the SGX feature */ - lock_sgx(); - - /* Activate the SGX feature */ - activate_sgx(); -} -- cgit v1.2.3