Received: by 10.213.65.68 with SMTP id h4csp1169283imn; Wed, 14 Mar 2018 11:38:49 -0700 (PDT) X-Google-Smtp-Source: AG47ELu6Vp38ck1xnBoAXjtYxA3QhxJbEmLhRT2OgBMLY7RnFTOPQV6hIRb02dP8jsSV6pjsp6Me X-Received: by 10.101.82.198 with SMTP id z6mr4484551pgp.41.1521052729522; Wed, 14 Mar 2018 11:38:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521052729; cv=none; d=google.com; s=arc-20160816; b=WV0FrQXNxGutTo6aw7207SPixORzPjEWuO0smD9GmAOmt/kmRmAQOBUs0tAN/QzHbw av4znVWCjk3nriJG+4EKzvAV7tNurhfsFrI17+Kn4KeT/rIkr9+LwN+FkkL1YMhty53z brQ91fq2xcoaZUnqjpSorIsZCFP1JyhBwbwe1e+3kigScAw+4AJyaV+EJQm3EOHh4zrB pHKc8TMXR9KoCO0utV9m4k2QrlGdSRA9G/mI+HOttxwCw48CrucgXgVezeqOKBZM62cG oDP1NY02nvLSmlb8952q53VrY/ZPlPQxXvzYJb9FG+pH9pmvh/i1QktgiLGTQHL7PvFH aQhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=wGl5sQSXWbPX6CaI6c4Vd3jUZFf046sal7TeDt8oV/4=; b=TzC4T35GmSTNVLWx/J5uqhWTnSsdQUJxB+gXQQumng9cOZmAs6bjMjZB8i49jxtkZQ KZnxs7PM1IXC3isqOgSuT2XgNysxC5UVLzdF1XVGr06C8EDK7DO3z3e0Co9uY1KRXFKL G+SI/ipLsYtTtfvv5tWPTkmdXyxegeHKF0JA3g0pf1IrTnovkY16TzA/8yGdLzqT+B5u Bo1gx09ccArOevXHdnYVxjPGo7lY34nOhljCkrYD9z5FMTfBpm61KtMDIZHdPS+geMjS WoraaV7ZAV43sX6t17+8qj0S+4MFWB7p0g4tvllIOMEuASGUM4X1jF+wRk/K85hyf2qF uocA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o81si2485687pfk.67.2018.03.14.11.38.35; Wed, 14 Mar 2018 11:38:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751727AbeCNShA (ORCPT + 99 others); Wed, 14 Mar 2018 14:37:00 -0400 Received: from mail.skyhub.de ([5.9.137.197]:39218 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750779AbeCNSg6 (ORCPT ); Wed, 14 Mar 2018 14:36:58 -0400 X-Virus-Scanned: Nedap ESD1 at mail.skyhub.de Received: from mail.skyhub.de ([127.0.0.1]) by localhost (blast.alien8.de [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id afZJrovjJldU; Wed, 14 Mar 2018 19:36:40 +0100 (CET) Received: from pd.tnic (p200300EC2BC98E000DB0D181F40EDD09.dip0.t-ipconnect.de [IPv6:2003:ec:2bc9:8e00:db0:d181:f40e:dd09]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.skyhub.de (SuperMail on ZX Spectrum 128k) with ESMTPSA id AC56D1EC05F5; Wed, 14 Mar 2018 19:36:40 +0100 (CET) From: Borislav Petkov To: X86 ML Cc: Emanuel Czirai , Ashok Raj , Tom Lendacky , LKML Subject: [PATCH 1/2] x86/microcode: Attempt late loading only when new microcode is present Date: Wed, 14 Mar 2018 19:36:14 +0100 Message-Id: <20180314183615.17629-1-bp@alien8.de> X-Mailer: git-send-email 2.13.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Borislav Petkov Return UCODE_NEW from the scanning functions to denote that new microcode was found and only then attempt the expensive synchronization dance. Reported-and-tested-by: Emanuel Czirai Tested-by: Ashok Raj Tested-by: Tom Lendacky Signed-off-by: Borislav Petkov Cc: Thomas Gleixner --- arch/x86/include/asm/microcode.h | 1 + arch/x86/kernel/cpu/microcode/amd.c | 34 +++++++++++++++++++++------------- arch/x86/kernel/cpu/microcode/core.c | 8 +++----- arch/x86/kernel/cpu/microcode/intel.c | 4 +++- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 871714e2e4c6..2b7cc5397f80 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -25,6 +25,7 @@ struct device; enum ucode_state { UCODE_OK = 0, + UCODE_NEW, UCODE_UPDATED, UCODE_NFOUND, UCODE_ERROR, diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index a998e1a7d46f..48179928ff38 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -339,7 +339,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) return -EINVAL; ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size); - if (ret != UCODE_OK) + if (ret > UCODE_UPDATED) return -EINVAL; return 0; @@ -683,27 +683,35 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, static enum ucode_state load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) { + struct ucode_patch *p; enum ucode_state ret; /* free old equiv table */ free_equiv_cpu_table(); ret = __load_microcode_amd(family, data, size); - - if (ret != UCODE_OK) + if (ret != UCODE_OK) { cleanup(); + return ret; + } -#ifdef CONFIG_X86_32 - /* save BSP's matching patch for early load */ - if (save) { - struct ucode_patch *p = find_patch(0); - if (p) { - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); - memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), - PATCH_MAX_SIZE)); - } + p = find_patch(0); + if (!p) { + return ret; + } else { + if (boot_cpu_data.microcode == p->patch_id) + return ret; + + ret = UCODE_NEW; } -#endif + + /* save BSP's matching patch for early load */ + if (!save) + return ret; + + memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); + memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE)); + return ret; } diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 70ecbc8099c9..9f0fe5bb450d 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -607,7 +607,7 @@ static ssize_t reload_store(struct device *dev, return size; tmp_ret = microcode_ops->request_microcode_fw(bsp, µcode_pdev->dev, true); - if (tmp_ret != UCODE_OK) + if (tmp_ret != UCODE_NEW) return size; get_online_cpus(); @@ -691,10 +691,8 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw) if (system_state != SYSTEM_RUNNING) return UCODE_NFOUND; - ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, - refresh_fw); - - if (ustate == UCODE_OK) { + ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, refresh_fw); + if (ustate == UCODE_NEW) { pr_debug("CPU%d updated upon init\n", cpu); apply_microcode_on_target(cpu); } diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 2aded9db1d42..32b8e5724f96 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -862,6 +862,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, unsigned int leftover = size; unsigned int curr_mc_size = 0, new_mc_size = 0; unsigned int csig, cpf; + enum ucode_state ret = UCODE_OK; while (leftover) { struct microcode_header_intel mc_header; @@ -903,6 +904,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, new_mc = mc; new_mc_size = mc_size; mc = NULL; /* trigger new vmalloc */ + ret = UCODE_NEW; } ucode_ptr += mc_size; @@ -932,7 +934,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", cpu, new_rev, uci->cpu_sig.rev); - return UCODE_OK; + return ret; } static int get_ucode_fw(void *to, const void *from, size_t n) -- 2.13.0