Received: by 2002:a05:7412:f690:b0:e2:908c:2ebd with SMTP id ej16csp954568rdb; Fri, 20 Oct 2023 04:39:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE2jM3Py389GgBlQ3zwv/1TYVUDWnVkPugxXN8AzgwKkT+fhjAtKjBaEU+KX9EYXjIxGcGD X-Received: by 2002:a05:6a20:7d9f:b0:15c:b7ba:9137 with SMTP id v31-20020a056a207d9f00b0015cb7ba9137mr1646275pzj.2.1697801997691; Fri, 20 Oct 2023 04:39:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697801997; cv=none; d=google.com; s=arc-20160816; b=ItmHlzt0QfYNEsCJ4SmORdjnGTXjiRtFyNtmwfs2mR4JWc4DUXH1YjJNdJr7ZbG7MT Jge3EW9On09ug01QHsemYOVFkV6mm+Q0mKFZ1Qu+Rfs+lrSn30osU2u1rPeU+NjfPSrD mfkTz3TGwRLn708g1bijWW0dQj38/pwfFPvCOxl2HrvVNYDi5FoMIwErpXN1QYWq9TdD NbRjMmiP6kEU4eTyBPUH6d+Nt5Gr0jrRCjK3VxSDkXtVK8v0ECjaoaMRpIPEkVEzgKHN ICcf7r1HkUAjAQ3aoisFAiZFC8/KRZkVvdL+N6SE6NAhDD6Pihzw4yi3uPJWa6WUrUdu U14w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=L+3ONnxpGDfjwbMH7fTfSlt9oKGA28nEngcyCpedSpQ=; fh=SUh4kdNTADmkahV2MeFbd3vkpkMlP6po9p9PBlTzZvU=; b=loIpqGniz2dJhLvIR7KZztyWtjeAz3JCKjJTut3QmRRQ/bpzb6MqEsihw7oPPyWxjS 6ae00j1Fh1xQDCCFR+JZSCUlS/o6gbhnDwy5ftV8GCMZ3e/mrFhM4K89HUvOVLGq8Zlx b9ZX/FYvexN/gVHVOirAKJeSMdvawK2hA7EL8P/LadWsuEc0n0o5K8gLEpEPUAkCSQ/h jSYLpbniv9jeYqIbkvOZduqbAkfCSoFW0dFAolO/2MylhBO8JOC/XyoG6VufxvRktbGD TUJBGozWd2ZfBGhp9XK9J3ZvVZF3VZVFSRi9VG2KVwaMsfqH+FCG/3fY0jMJS8P9GP8W Byow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=HRJcw28J; dkim=neutral (no key) header.i=@linutronix.de header.b=6AGSZXmr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id gt4-20020a17090af2c400b0027901ee93fbsi4171598pjb.156.2023.10.20.04.39.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 04:39:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=HRJcw28J; dkim=neutral (no key) header.i=@linutronix.de header.b=6AGSZXmr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 8868C82F0990; Fri, 20 Oct 2023 04:39:48 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377380AbjJTLir (ORCPT + 99 others); Fri, 20 Oct 2023 07:38:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377316AbjJTLia (ORCPT ); Fri, 20 Oct 2023 07:38:30 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1891D6B; Fri, 20 Oct 2023 04:37:47 -0700 (PDT) Date: Fri, 20 Oct 2023 11:37:45 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1697801866; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L+3ONnxpGDfjwbMH7fTfSlt9oKGA28nEngcyCpedSpQ=; b=HRJcw28JI4eynfUaUTqNW4kbgO9tvFPn+bkfoRisa6RdAkJe3E/1Jc3yhpWi9hUcYDj33v dCiec/lEPiPI8TfYoeIHU4f0AeVbwwE9Ia/j5HrzkZndnNpT14S//pQAMlkDgU09HDF7cq EZ0lHP8SHFXL+pMgo3bvnZjiGOtB7J8G3L5Ol+2NsAt/a4h8gbJph7zcdvd5sHw/6g4ESG L1+eVwbNvwemgAyIObl4LXa26/Prq61dbe+d+x6vXMm3SERSSPe9jNVLrOrgtNlBxAJpNH Qkpc97A60kEi9HebWg4GzD9W/T3EWJfOlm3ngkQuCWRUGkOLrsNViDQDfRQszA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1697801866; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L+3ONnxpGDfjwbMH7fTfSlt9oKGA28nEngcyCpedSpQ=; b=6AGSZXmrEsw6QYMaoXfy62hDIxH40DCcIGPe+MjgQkEflRdL171kUmjUoRqm83Xz0ZjuIs /A+rzYq0qQtXuQDg== From: "tip-bot2 for Ashok Raj" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/microcode] x86/microcode/intel: Add a minimum required revision for late loading Cc: Thomas Gleixner , Ashok Raj , "Borislav Petkov (AMD)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20231002115903.776467264@linutronix.de> References: <20231002115903.776467264@linutronix.de> MIME-Version: 1.0 Message-ID: <169780186548.3135.2921750255137200563.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Fri, 20 Oct 2023 04:39:48 -0700 (PDT) The following commit has been merged into the x86/microcode branch of tip: Commit-ID: d975d2d3f52eb942df34f9fe3a782a02f0650db2 Gitweb: https://git.kernel.org/tip/d975d2d3f52eb942df34f9fe3a782a02f0650db2 Author: Ashok Raj AuthorDate: Mon, 02 Oct 2023 14:00:11 +02:00 Committer: Borislav Petkov (AMD) CommitterDate: Thu, 19 Oct 2023 16:02:50 +02:00 x86/microcode/intel: Add a minimum required revision for late loading In general users, don't have the necessary information to determine whether late loading of a new microcode version is safe and does not modify anything which the currently running kernel uses already, e.g. removal of CPUID bits or behavioural changes of MSRs. To address this issue, Intel has added a "minimum required version" field to a previously reserved field in the microcode header. Microcode updates should only be applied if the current microcode version is equal to, or greater than this minimum required version. Thomas made some suggestions on how meta-data in the microcode file could provide Linux with information to decide if the new microcode is suitable candidate for late loading. But even the "simpler" option requires a lot of metadata and corresponding kernel code to parse it, so the final suggestion was to add the 'minimum required version' field in the header. When microcode changes visible features, microcode will set the minimum required version to its own revision which prevents late loading. Old microcode blobs have the minimum revision field always set to 0, which indicates that there is no information and the kernel considers it unsafe. This is a pure OS software mechanism. The hardware/firmware ignores this header field. For early loading there is no restriction because OS visible features are enumerated after the early load and therefore a change has no effect. The check is always enabled, but by default not enforced. It can be enforced via Kconfig or kernel command line. If enforced, the kernel refuses to late load microcode with a minimum required version field which is zero or when the currently loaded microcode revision is smaller than the minimum required revision. If not enforced the load happens independent of the revision check to stay compatible with the existing behaviour, but it influences the decision whether the kernel is tainted or not. If the check signals that the late load is safe, then the kernel is not tainted. Early loading is not affected by this. [ tglx: Massaged changelog and fixed up the implementation ] Suggested-by: Thomas Gleixner Signed-off-by: Ashok Raj Signed-off-by: Thomas Gleixner Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20231002115903.776467264@linutronix.de --- arch/x86/include/asm/microcode.h | 3 +- arch/x86/kernel/cpu/microcode/intel.c | 37 +++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 0ee6ed0..695e569 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -38,7 +38,8 @@ struct microcode_header_intel { unsigned int datasize; unsigned int totalsize; unsigned int metasize; - unsigned int reserved[2]; + unsigned int min_req_ver; + unsigned int reserved; }; struct microcode_intel { diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index bd9e13b..e99f129 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -457,16 +457,40 @@ static enum ucode_state apply_microcode_late(int cpu) return ret; } +static bool ucode_validate_minrev(struct microcode_header_intel *mc_header) +{ + int cur_rev = boot_cpu_data.microcode; + + /* + * When late-loading, ensure the header declares a minimum revision + * required to perform a late-load. The previously reserved field + * is 0 in older microcode blobs. + */ + if (!mc_header->min_req_ver) { + pr_info("Unsafe microcode update: Microcode header does not specify a required min version\n"); + return false; + } + + /* + * Check whether the current revision is either greater or equal to + * to the minimum revision specified in the header. + */ + if (cur_rev < mc_header->min_req_ver) { + pr_info("Unsafe microcode update: Current revision 0x%x too old\n", cur_rev); + pr_info("Current should be at 0x%x or higher. Use early loading instead\n", mc_header->min_req_ver); + return false; + } + return true; +} + static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; + bool is_safe, new_is_safe = false; int cur_rev = uci->cpu_sig.rev; unsigned int curr_mc_size = 0; u8 *new_mc = NULL, *mc = NULL; - if (force_minrev) - return UCODE_NFOUND; - while (iov_iter_count(iter)) { struct microcode_header_intel mc_header; unsigned int mc_size, data_size; @@ -509,9 +533,14 @@ static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter) if (!intel_find_matching_signature(mc, &uci->cpu_sig)) continue; + is_safe = ucode_validate_minrev(&mc_header); + if (force_minrev && !is_safe) + continue; + kvfree(new_mc); cur_rev = mc_header.rev; new_mc = mc; + new_is_safe = is_safe; mc = NULL; } @@ -523,7 +552,7 @@ static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter) return UCODE_NFOUND; ucode_patch_late = (struct microcode_intel *)new_mc; - return UCODE_NEW; + return new_is_safe ? UCODE_NEW_SAFE : UCODE_NEW; fail: kvfree(mc);