[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/microcode: Prevent attempting updates known to fail
If IA32_MSR_MCU_CONTROL exists, then it's possible a CPU may be unable to perform microcode updates. This is controlled through the DIS_MCU_LOAD bit. This patch checks that the CPU that got the request is capable of doing an update. If it is, then we let the procedure go through. While not enough for the general case (different CPUs with different settings), this patch copes with the far more common scenario of all CPUs being locked. Note that for the uncommon general case, we already have some logic in place to emit a message on xl-dmseg in order to notify the admin that they should reboot the machine ASAP. Signed-off-by: Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx> --- xen/arch/x86/cpu/microcode/core.c | 27 +++++++++++++++++++++++++++ xen/arch/x86/include/asm/cpufeature.h | 1 + xen/arch/x86/include/asm/msr-index.h | 5 +++++ 3 files changed, 33 insertions(+) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index cd456c476f..e507945932 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -697,6 +697,17 @@ static long cf_check microcode_update_helper(void *data) return ret; } +static bool this_cpu_can_install_update(void) +{ + uint64_t mcu_ctrl; + + if ( !cpu_has_mcu_ctrl ) + return true; + + rdmsrl(MSR_MCU_CONTROL, mcu_ctrl); + return !(mcu_ctrl & MCU_CONTROL_DIS_MCU_LOAD); +} + int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len) { int ret; @@ -708,6 +719,22 @@ int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len) if ( !ucode_ops.apply_microcode ) return -EINVAL; + if ( !this_cpu_can_install_update() ) + { + /* + * This CPU can't install microcode, so it makes no sense to try to + * go on. We're implicitly trusting firmware sanity in that all + * CPUs are expected to have a homogeneous setting. If, for some + * reason, another CPU happens to be locked down when this one + * isn't then unpleasantness will follow. In particular, some CPUs + * will be updated while others will not. A very stern message will + * be displayed in xl-dmesg that case, strongly advising to reboot the + * machine. + */ + printk("WARNING: microcode not installed due to DIS_MCU_LOAD=1"); + return -EACCES; + } + buffer = xmalloc_flex_struct(struct ucode_buf, buffer, len); if ( !buffer ) return -ENOMEM; diff --git a/xen/arch/x86/include/asm/cpufeature.h b/xen/arch/x86/include/asm/cpufeature.h index ace31e3b1f..0118171d7e 100644 --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -192,6 +192,7 @@ static inline bool boot_cpu_has(unsigned int feat) #define cpu_has_if_pschange_mc_no boot_cpu_has(X86_FEATURE_IF_PSCHANGE_MC_NO) #define cpu_has_tsx_ctrl boot_cpu_has(X86_FEATURE_TSX_CTRL) #define cpu_has_taa_no boot_cpu_has(X86_FEATURE_TAA_NO) +#define cpu_has_mcu_ctrl boot_cpu_has(X86_FEATURE_MCU_CTRL) #define cpu_has_fb_clear boot_cpu_has(X86_FEATURE_FB_CLEAR) /* Synthesized. */ diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h index 2749e433d2..5c1350b5f9 100644 --- a/xen/arch/x86/include/asm/msr-index.h +++ b/xen/arch/x86/include/asm/msr-index.h @@ -165,6 +165,11 @@ #define PASID_PASID_MASK 0x000fffff #define PASID_VALID (_AC(1, ULL) << 31) +#define MSR_MCU_CONTROL 0x00001406 +#define MCU_CONTROL_LOCK (_AC(1, ULL) << 0) +#define MCU_CONTROL_DIS_MCU_LOAD (_AC(1, ULL) << 1) +#define MCU_CONTROL_EN_SMM_BYPASS (_AC(1, ULL) << 2) + #define MSR_UARCH_MISC_CTRL 0x00001b01 #define UARCH_CTRL_DOITM (_AC(1, ULL) << 0) -- 2.34.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |