From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A5D51A268 for ; Sat, 12 Sep 2026 00:34:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173300; cv=none; b=C5zfs9NvXMQdJgnaZH+gBFhjObMvjsUUT8YUrdg/3oFABxUf9IYWnkpPfk16QEyHI/W3rl7zkz4/yak0epQLNnWVQrVM5Z9JQBHytreIxDHlW+VYTtsyMmaPIjUX2Ql0tog7D5WYXMeuhvH8KJumDbxM0RsRXScceJ3c8eD0cyI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173300; c=relaxed/simple; bh=qe7XIhIewwHBV/9KsEFxItJNJXwxG5s13s91Wa/n9Zo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XhyxTm61ZBiZ/WR8SMHCsTu0HZgr7fwISrbez3Hsfm8ifcUwrsFneiyL9uDOjWwTwWcYPcdVxI3EqljjsoYz4je4TmX4nFqai/cKgOSl3XHQ1G4vf7ocrbQmq7xUXPmUC5wbseDVVsVtkvqePM8zP5aYoUC98xSG4C01trqUB1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=V4qsL3ok; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="V4qsL3ok" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173299; x=1820709299; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qe7XIhIewwHBV/9KsEFxItJNJXwxG5s13s91Wa/n9Zo=; b=V4qsL3ok28g9BqAdEnlxty8fijovmgDxXmVqIcUnoMFqEdfCEeJ7BzU7 jhCyuh5NbBz5lEKkWXwlnbv7zaM3XqDrJO4AcFUAfdfdcfVBr+H7bsU9Q qpVIVq7F/505lBV9N4X1gSpbgTN7RdiG3MAvWB8MtQDXzJEceRJf82rsF vCMGp3CcPJJcB0lMQSkny2GxCjDaOuaY2nQzfHESrAo8REwoUBzFDwiGE qYLU9Nmo+iQgtKJog9dlaDnEx92nA1oKJqAtj0oHUZCNShJFQfR6FWpC5 lWieKDZ4IgegrKKwzEe04Yxuvw7wKZM2YKDkavrCJlXkpic85yFLKv5pt Q==; X-CSE-ConnectionGUID: alvGDlsGQmOXqDI6teOI8w== X-CSE-MsgGUID: 67+7oD/CSFWdG15rfB2QhQ== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174947" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174947" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:34:59 -0700 X-CSE-ConnectionGUID: L2XRBnIeRhWnh7Yd+ZvHbA== X-CSE-MsgGUID: 3QoVzrcJSk644q0wHhcdKA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217561" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:34:58 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 1/8] cpu/hotplug: Allow architecture-specific primary CPU bringup Date: Sat, 12 Sep 2026 00:08:07 +0000 Message-ID: <20260912000815.997720-2-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Parallel CPU bringup currently proceeds in two phases: first for the SMT primary threads and then second for the remaining secondary threads. This ordering avoids race conditions, specifically for x86 microcode loading. Upcoming x86 changes expand the microcode loading scope beyond a single core to package scope or even system-wide updates. Introduce architecture hooks that allow customizing which CPUs participate in the first phase: * arch_cpuhp_primary_aware() - indicates whether the architecture provides a custom primary CPU selection scheme, or not. * arch_cpuhp_get_primary_cpus() - returns a CPU mask for the first bringup iteration. Signed-off-by: Chang S. Bae --- arch/Kconfig | 4 ++++ include/linux/cpu.h | 9 +++++++++ kernel/cpu.c | 8 ++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 45c657772362..f38d80d583bf 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -102,6 +102,10 @@ config HOTPLUG_PARALLEL bool select HOTPLUG_SPLIT_STARTUP =20 +config HOTPLUG_PARALLEL_ARCH_PRIMARY + bool + depends on HOTPLUG_PARALLEL + config GENERIC_IRQ_ENTRY bool =20 diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 9b6b0d87fdb0..11e375d00df7 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -19,6 +19,7 @@ #include #include #include +#include =20 struct device; struct device_node; @@ -233,4 +234,12 @@ int arch_prctl_get_branch_landing_pad_state(struct tas= k_struct *t, unsigned long int arch_prctl_set_branch_landing_pad_state(struct task_struct *t, unsigne= d long state); int arch_prctl_lock_branch_landing_pad_state(struct task_struct *t); =20 +#ifdef CONFIG_HOTPLUG_PARALLEL_ARCH_PRIMARY +bool __init arch_cpuhp_primary_aware(void); +const struct cpumask *__init arch_cpuhp_get_primary_cpus(void); +#else +static inline bool arch_cpuhp_primary_aware(void) { return false; } +static inline const struct cpumask *arch_cpuhp_get_primary_cpus(void) { re= turn cpu_none_mask; } +#endif + #endif /* _LINUX_CPU_H_ */ diff --git a/kernel/cpu.c b/kernel/cpu.c index b3c8553d7bd6..5225f91c4d8c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1837,15 +1837,19 @@ static bool __init cpuhp_bringup_cpus_parallel(unsi= gned int ncpus) if (!__cpuhp_parallel_bringup) return false; =20 - if (cpuhp_smt_aware()) { - const struct cpumask *pmask =3D cpuhp_get_primary_thread_mask(); + if (arch_cpuhp_primary_aware() || cpuhp_smt_aware()) { static struct cpumask tmp_mask __initdata; + const struct cpumask *pmask; =20 /* * X86 requires to prevent that SMT siblings stopped while * the primary thread does a microcode update for various * reasons. Bring the primary threads up first. */ + pmask =3D arch_cpuhp_primary_aware() ? + arch_cpuhp_get_primary_cpus() : + cpuhp_get_primary_thread_mask(); + cpumask_and(&tmp_mask, mask, pmask); cpuhp_bringup_mask(&tmp_mask, ncpus, CPUHP_BP_KICK_AP); cpuhp_bringup_mask(&tmp_mask, ncpus, CPUHP_ONLINE); --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 989CA2C1586 for ; Sat, 12 Sep 2026 00:35:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173304; cv=none; b=mB9T0GAkuUlZETup9YsrVEtb9AOlOzaLdFNj+WbhJYAvI2wZ2ojhn+mb/CXCtkxkaO4w56KjbhwO2tEWNTYkjVQkHcQYj88lF9Rd1RzhQ+I0in7eaDK1WMZq03TnquKbWma6EWLmW1k5rkSuNjoiszRSWvRNVSPV3bKMcGfTx00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173304; c=relaxed/simple; bh=YXa0l6c+grZX2/LjoqW0DnFyjiTq9oXDwuC3+9M8yDo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FE7qvr5vVzb8jOfVUWlt4N011OkxxM+MAls1BJPExwJPScUd+elEwXdKFpoOVnOkA/AJLTJoSSQvXpwyYMf2TySyGn3YymJu5xy7FI1HKxg0Dvb5t6HMIzvNuwBDoPk5vtK/q9iwilJa7JT1csFJ5VQpIR0zEZDRf5J23HNY+3o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=fF00PUDk; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="fF00PUDk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173302; x=1820709302; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YXa0l6c+grZX2/LjoqW0DnFyjiTq9oXDwuC3+9M8yDo=; b=fF00PUDk8QfU5RvQCXy3mkjEoU/YNEEy4p8ApbaJpG1V4IysDTHuBqks hm3X2VjC6H5CvGhT9FNjcFSk4Qg4k3YHjOZHQrRfGzYkCwV9IjC2XCJ13 K7b4z3cJJS29qGKxrWAMszxwKHeJlr3vtiYjfDNEgUxHXlDAdy3GMvGGu kItH22GXAerBKsCgFU9WHO8Vvq0hh+pdFjSLZLMsN/JiAfq4CR5JTFEhp a1ByRx3o5yWwxu71A0wLgLiYI0PXhGLp1lqoAdF/W1c1T5b1MyXsI7px9 clKnDO4PlsUuBjZqRorsOzNQm9vrOZ+v/wFI8Jn1BgCWac3bgULBGS+Te Q==; X-CSE-ConnectionGUID: LqObo6ctTfOgSz9BGBv5rw== X-CSE-MsgGUID: IUYdzcs5TPaMNgaqpCwpWg== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174959" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174959" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:01 -0700 X-CSE-ConnectionGUID: ZKPuPMpFQfWZWh1dcMKf8w== X-CSE-MsgGUID: HR/NXSeCS+C4Ql386ozhFA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217578" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:01 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 2/8] x86/hotplug: Implement SMT-primary selection for parallel bringup Date: Sat, 12 Sep 2026 00:08:08 +0000 Message-ID: <20260912000815.997720-3-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Parallel CPU bringup executes in two phases to avoid microcode loading races between SMT siblings. The core code now supports architecture- specific customization of the first bringup phase. Implement the x86 logic to preserve the existing behavior. Signed-off-by: Chang S. Bae --- Note: With this change, the generic SMT-aware two-phase parallel bringup logic appears redundant since it was originally introduced for the x86 microcode loader path. But, another architecture, MIPS, also adopted the primary-aware parallel bringup model in: 76c43eb507bc ("MIPS: SMP: Implement parallel CPU bring up for EyeQ") So the generic fallback path still appears to have valid users. --- arch/x86/Kconfig | 1 + arch/x86/kernel/cpu/microcode/core.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 15fd9ec5ecac..cd6d4dfe3349 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1319,6 +1319,7 @@ config MICROCODE def_bool y depends on CPU_SUP_AMD || CPU_SUP_INTEL select CRYPTO_LIB_SHA256 if CPU_SUP_AMD + select HOTPLUG_PARALLEL_ARCH_PRIMARY if HOTPLUG_PARALLEL =20 config MICROCODE_INITRD32 def_bool y diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 0dd0c7241c57..36f08e2c99fb 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -869,6 +869,24 @@ static int mc_cpu_down_prep(unsigned int cpu) return 0; } =20 +#ifdef CONFIG_HOTPLUG_PARALLEL_ARCH_PRIMARY + +/* + * Queried by the parallel bringup code to determine whether x86 provides a + * custom primary CPU mask for early loading. + */ +bool __init arch_cpuhp_primary_aware(void) +{ + return __max_threads_per_core > 1; +} + +const struct cpumask *__init arch_cpuhp_get_primary_cpus(void) +{ + return cpu_primary_thread_mask; +} + +#endif /* CONFIG_HOTPLUG_PARALLEL_ARCH_PRIMARY */ + static struct attribute *cpu_root_microcode_attrs[] =3D { #ifdef CONFIG_MICROCODE_LATE_LOADING &dev_attr_reload.attr, --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84E741A268 for ; Sat, 12 Sep 2026 00:35:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173305; cv=none; b=TsEV6g/NJQx2bNkXgyyYJqdlHCr4iHBZZzZIXjWkj6kunrP7OBpD4JFQWnYVIs28iDkjdc4nwVmkmWh9NRmhWJsqCDgwpc8fIV5++cGsxfHWJvT5hJktXVIrFpt/HrcgfSyG4jbpys4Jy8iegOSIClW7EgQl68TLxi14uXfNgOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173305; c=relaxed/simple; bh=QWq25Fc/Rpsi6bFXQe7Ikl93k118o8jBVKBHBNa0+HI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cgjb6qGA80rNAOaN2yhV7VEWILsPwvUETDE3/ySVHlV2m+NNBn375TzbMAACckKdDj+bjKp+b83a2tK68rTx7u3dYtn9VRtt8dm/EVaCJ4FluKP+Zvjw6elmB7Era1+NdO67NDhSvgGht6CHIyZK07ASnNlUwpKoF5PzEsbwdCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=jh6U8ymT; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="jh6U8ymT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173304; x=1820709304; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QWq25Fc/Rpsi6bFXQe7Ikl93k118o8jBVKBHBNa0+HI=; b=jh6U8ymTAzRuDaLcw6bQRWWTtz/ltI+awuURyLcp9YLqqEw2mtGnUfi6 okBEBmZTPuTffGyawBgppNMpxRXqV6CKyTsgRPYLlxzDoHjIMsbKN1Iv5 AnTGM+zVC1MXPty7EcvhnEvwwkH8MMXiNKuh8jmh7ORqOjx7JibfLZ9iQ 4QTuGysl4lgLbnKRqdvhrxlZcKb+kRqhMML64S+NAvQxJeno4UWzsfyks 9bxBFZDtzVEyeTgNHCJfHxEIsiwjDdVbomZqOXFbEeWsgUZHaMH6ob+kt H9755KOJONx9tQoslN5FxVNeRYzNuTnYeAbHszyRfuYS51e5kXr8IMqKZ A==; X-CSE-ConnectionGUID: RRQZ08awSUiE1l67K6dihw== X-CSE-MsgGUID: 5eLi2A0jRTGOR5QWmXBmWA== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174965" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174965" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:03 -0700 X-CSE-ConnectionGUID: V67h+lTxTkiSsUV2VQwuXQ== X-CSE-MsgGUID: 8PNgL13QS0qGwBbDdN/l9Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217599" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:03 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 3/8] x86/cpu/topology: Introduce primary core mask Date: Sat, 12 Sep 2026 00:08:09 +0000 Message-ID: <20260912000815.997720-4-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The microcode loading distinguishes primary SMT threads from sibling threads to avoid races during updates. Because early loading relies on this distinction, parallel CPU bringup splits APs into two groups and brings them up in phases. Upcoming Intel microcode loading feature expands the loading scope beyond per-core updates to package-wide or system-wide updates. While CPU0 is the obvious primary for the system-wide scope, there is currently no facility to identify per-package primary CPUs for the parallel bringup. This matters because the parallel bringup logic must determine primary CPUs before any AP is ever brought up. But topology_logical_package_id() is not usable at that stage, as logical package IDs are established during AP bringup itself, as described in: 7af541cee1e0e ("x86/topology: Don't evaluate logical IDs during early boo= t") Unlike cpu_primary_thread_mask, there is also no relevant mask that tracks one primary CPU per package. Thus, introduce cpu_primary_core_mask to fill this gap. The mask intentionally includes all threads of the selected core. This preserves core-domain granularity and avoids coupling with the lower- level topology details such as SMT primary selection. Use the mask for the microcode staging path to simplify staging CPU selection at the moment. Following changes will address the microcode loading use. Signed-off-by: Chang S. Bae --- Note: The staging path itself could have continued using topology_logical_package= _id() as the late loading is only relevant. IOW, the cpu_primary_core_mask introduction was not required for the staging enablement back then. --- arch/x86/include/asm/topology.h | 3 +++ arch/x86/kernel/cpu/microcode/intel.c | 14 ++++---------- arch/x86/kernel/cpu/topology.c | 23 ++++++++++++++++++++--- arch/x86/kernel/cpu/topology_common.c | 9 +++++++++ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topolog= y.h index 1825691af941..02ad56cfc6f4 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -234,6 +234,9 @@ static inline unsigned int topology_amd_nodes_per_pkg(v= oid) { return 1; } extern struct cpumask __cpu_primary_thread_mask; #define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_th= read_mask) =20 +extern struct cpumask __cpu_primary_core_mask; +#define cpu_primary_core_mask ((const struct cpumask *)&__cpu_primary_core= _mask) + /** * topology_is_primary_thread - Check whether CPU is the primary SMT thread * @cpu: CPU to check diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 1142183c950c..4b5feee14712 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -605,7 +605,6 @@ static int do_stage(u64 mmio_pa) =20 static void stage_microcode(void) { - unsigned int pkg_id =3D UINT_MAX; int cpu, err; u64 mmio_pa; =20 @@ -619,15 +618,10 @@ static void stage_microcode(void) =20 /* * The MMIO address is unique per package, and all the SMT - * primary threads are online here. Find each MMIO space by - * their package IDs to avoid duplicate staging. + * primary threads are online here. Find unique MMIO space to + * avoid duplicate staging. */ - for_each_cpu(cpu, cpu_primary_thread_mask) { - if (topology_logical_package_id(cpu) =3D=3D pkg_id) - continue; - - pkg_id =3D topology_logical_package_id(cpu); - + for_each_cpu_and(cpu, cpu_primary_core_mask, cpu_primary_thread_mask) { err =3D rdmsrq_on_cpu(cpu, MSR_IA32_MCU_STAGING_MBOX_ADDR, &mmio_pa); if (WARN_ON_ONCE(err)) return; @@ -635,7 +629,7 @@ static void stage_microcode(void) err =3D do_stage(mmio_pa); if (err) { pr_err("Error: staging failed (%d) for CPU%d at package %u.\n", - err, cpu, pkg_id); + err, cpu, topology_logical_package_id(cpu)); return; } } diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 4913b64ec592..be6f5a3bd54f 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -75,12 +75,25 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) return phys_id =3D=3D (u64)cpuid_to_apicid[cpu]; } =20 +static unsigned int __max_cores_per_package __ro_after_init =3D 1; + static void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) { if (!(apicid & (__max_threads_per_core - 1))) cpumask_set_cpu(cpu, &__cpu_primary_thread_mask); } =20 +/* + * Select core 0 of every package and all SMT threads of that core so that= the + * mask stays at core granularity. + */ +static void cpu_mark_primary_core(unsigned int cpu, unsigned int apicid) +{ + if (!((apicid >> get_count_order(__max_threads_per_core)) & + (__max_cores_per_package - 1))) + cpumask_set_cpu(cpu, &__cpu_primary_core_mask); +} + /* * Convert the APIC ID to a domain level ID by masking out the low bits * below the domain level @dom. @@ -505,13 +518,16 @@ void __init topology_init_possible_cpus(void) pr_info("Max. logical dies: %3u\n", cntb); pr_info("Max. dies per package: %3u\n", __max_dies_per_package); =20 - cnta =3D domain_weight(TOPO_CORE_DOMAIN); - cntb =3D domain_weight(TOPO_SMT_DOMAIN); + cntb =3D domain_weight(TOPO_CORE_DOMAIN); + __max_cores_per_package =3D 1U << (get_count_order(cntb) - get_count_orde= r(cnta)); + pr_info("Max. cores per package:%3u\n", __max_cores_per_package); + + cnta =3D domain_weight(TOPO_SMT_DOMAIN); /* * Can't use order delta here as order(cnta) can be equal * order(cntb) even if cnta !=3D cntb. */ - __max_threads_per_core =3D DIV_ROUND_UP(cntb, cnta); + __max_threads_per_core =3D DIV_ROUND_UP(cnta, cntb); pr_info("Max. threads per core: %3u\n", __max_threads_per_core); =20 firstid =3D find_first_bit(apic_maps[TOPO_SMT_DOMAIN].map, MAX_LOCAL_APIC= ); @@ -545,6 +561,7 @@ void __init topology_init_possible_cpus(void) continue; =20 cpu_mark_primary_thread(cpu, apicid); + cpu_mark_primary_core(cpu, apicid); set_cpu_present(cpu, test_bit(apicid, phys_cpu_present_map)); } } diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/to= pology_common.c index 6845e3c63fbb..dc1d96be8ba5 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -20,6 +20,15 @@ EXPORT_SYMBOL_GPL(__amd_nodes_per_pkg); /* CPUs which are the primary SMT threads */ struct cpumask __cpu_primary_thread_mask __read_mostly; =20 +/* + * CPUs belonging to the primary core of each package + * + * To preserve core-domain granularity and to avoid the next-level primary + * details that cpu_primary_thread_mask can present, the mask includes all + * threads of each primary core. + */ +struct cpumask __cpu_primary_core_mask __read_mostly; + void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains d= om, unsigned int shift, unsigned int ncpus) { --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D0C129D260 for ; Sat, 12 Sep 2026 00:35:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173307; cv=none; b=RE3QxItK5mR2P0zJ6iT8vMthltciZFFYvm/XTxA4WuCgFmbd6axMsWz0cthNqo5hKRAdVCT09/imIlB+uYaxDYiQXq2SBRLhrrhcTlEy61c1yGv//DHjcHMugRIVOB0uOBXJ2rmeGKN8Eee2+dDDO+G6+j0TdUXifsCaeAqDkms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173307; c=relaxed/simple; bh=n1YFCcL+pq+InjfsAVMb4kl/Tw2a5rz5iSJpBsPCjRE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fABfNIOAe776BUoSWbgfEtSuyCRFTDtlQ8QcjOxdY6cxsZES5ItK7L7+h7UJIYy5p6LVKC13catuoxReP0Ge9029ukxJwG8ZHhnjLFWsuJE1MvsY7EBiK3aCSDtEOkwXIuKQwYzbj/kLwpxf8Ulf038jkQbfPTKhznjRM8zAyqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=KTkzcZIZ; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="KTkzcZIZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173305; x=1820709305; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=n1YFCcL+pq+InjfsAVMb4kl/Tw2a5rz5iSJpBsPCjRE=; b=KTkzcZIZXujhttde3S6sX9KWrIcRsnrsZr+URNuVBW6jSli04o12OB/1 8kehB0jt9Ffoo1rFPsVcLdyAysJf+H5GdvGSFAckswTod8qNN7Qj6NMV/ JJeLZXCXhZQAWbJEk3LeIcu//4v7YkrDbPQMyFakkG+ehxzyvcRLNhWjl OQwzIFDmF40F693MiT4VBFrRdO9hT1b+W5A/g97sNDvB7JDyAj68BoHX2 ns1HwGnvHmqYzjJZiORPCe+ZLS6Jf9HjNxjTzcrcrc1Gqm1PrUcnsd35U sxPvtOp+QZwXlSID7gGYLbIq8tibKzN31MJl+HyyqIsBrbZ382rsSOAaw g==; X-CSE-ConnectionGUID: HNccN2dtT3uyYxeZuSR6AQ== X-CSE-MsgGUID: 0PBISRhlSSaebAex3yermA== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174969" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174969" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:05 -0700 X-CSE-ConnectionGUID: rwriP2gUQXSZ2xCBAToWNw== X-CSE-MsgGUID: B71n73AeTpuArd1zZ1yN3A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217623" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:05 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 4/8] x86/microcode: Extend struct microcode_ops for uniform loading Date: Sat, 12 Sep 2026 00:08:10 +0000 Message-ID: <20260912000815.997720-5-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Microcode loading is currently performed on a per-core basis. The loading process concludes only after every core has been updated. As core counts continue to grow, reducing the number of update invocations makes the process increasingly efficient. The uniform loading feature extends the update scope beyond a single core, for example to a package or even an entire system. This means a single update covers multiple cores, which in turn reduces the number of update triggers. The common late-loading logic determines the primary CPUs before invoking vendor-specific callbacks. Extend struct microcode_ops with fields for describing the feature support and the loading scope. The actual loading flow changes will follow later. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/internal.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu= /microcode/internal.h index a10b547eda1e..0a74794e0245 100644 --- a/arch/x86/kernel/cpu/microcode/internal.h +++ b/arch/x86/kernel/cpu/microcode/internal.h @@ -21,6 +21,13 @@ enum ucode_state { UCODE_OFFLINE, }; =20 +enum uniform_scope { + UNIFORM_DEFAULT =3D 0, + UNIFORM_CORE, + UNIFORM_PKG, + UNIFORM_SYS, +}; + struct microcode_ops { enum ucode_state (*request_microcode_fw)(int cpu, struct device *dev); void (*microcode_fini_cpu)(int cpu); @@ -36,7 +43,9 @@ struct microcode_ops { void (*finalize_late_load)(int result); unsigned int nmi_safe : 1, use_nmi : 1, - use_staging : 1; + use_staging : 1, + use_uniform : 1; + enum uniform_scope uniform_scope; }; =20 struct early_load_data { --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A1842C15A9 for ; Sat, 12 Sep 2026 00:35:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173308; cv=none; b=UIAVBBo8AsNlmhxH6UFNzPHncSZjW8rkdtGdA94YZJDYioH/oBsuE/PlYcUKJA3SeBaEsqdSLptf+vEF1Os1+bjG0sE0wY3W0RM+blUOJnkrtsMSYl2ICZKg6km9sHM9hXiWqyGudj3q5FPnsdkSH0kqj9RoRvTY3BhMAClZq0g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173308; c=relaxed/simple; bh=ehTJT34x1/pVjPr0qCrycXzF3V5ZsU1NGkIp4eVinhg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kCpTRTsCXvb7nQeF4rikNllHOw5Du6E2ApPY6JfN1RD8l3yrPheSsw1+t/QyK3iYtzi+qzccifEUf4pPul/WgVbK6cZwiifc8+iMgHuxrX28F3KGbmlIWlNCP5Mm3hEdXLl7yr99IBwC9tn2RnTiSG+UtYdefpxKgpW+4wER4BY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=oH150HE/; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="oH150HE/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173307; x=1820709307; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ehTJT34x1/pVjPr0qCrycXzF3V5ZsU1NGkIp4eVinhg=; b=oH150HE/dJ8N4coHLA+O5PZGFJ0+sW0dXoaZIwF+QQ/I8b8bYUV7sA39 UTtHioUwBO85nAgAk2xcbUoXMcS0/XkdipBIPW9Y0neM1/MB3VjXArZVs 0lC8OYU6BZhx5TS+aMw6PITBI+SgLKQFLc7xdHTrooIdwYNL59fPEITIR NNmSfmH9PBt8Yqj8zXao4iNjeOeZNuLQRuCWuuUsAbk/yTftmj2cxI3Jn X2AHUuBrtbqug57fZtV+v+pQ6nqKid2pQylDO9LPpUejV260/FtBdl8p/ X/ZM+wowFmdDYqzbNiMK2z2y8gGmEeA0qx9Gmxa18qxJxF/putsL3OVBJ Q==; X-CSE-ConnectionGUID: QykqZWs6RR2puOkBTEu7JA== X-CSE-MsgGUID: sPydq6WwSxaGMa1wZWUtrQ== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174974" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174974" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:07 -0700 X-CSE-ConnectionGUID: +Ggx/10iSB6o/rT/zENWQQ== X-CSE-MsgGUID: 7/P339MVTEeTdEp7TORK/Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217642" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:07 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 5/8] x86/microcode: Clarify online enforcement with uniform loading Date: Sat, 12 Sep 2026 00:08:11 +0000 Message-ID: <20260912000815.997720-6-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The microcode update process requires at least one primary thread to oversee the update for each defined scope. Currently, the kernel mandates that all SMT primary threads remain online, assuming a core scope. When the loading scope is extended to cover a package or the entire system, this enforcement may be seen as unnecessary because offlining more CPUs is affordable as long as at least one CPU remains to participate in the microcode loading. The nosmt option can be considered for practical reasons. But it is impractical to aggressively switch off cores during such system-critical updates. So, the current online enforcement isn't expected to be too excessive even with the uniform loading. Clarify this consideration in code comments. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 36f08e2c99fb..8f617745d4d0 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -719,6 +719,12 @@ static bool setup_cpus(void) * * Ensure that the primary thread is online so that it is * guaranteed that all cores are updated. + * + * When the loading scope is extended beyond each core, it is + * not strictly required to have primary threads online. + * However, during such system-critical updates, offlining CPUs + * besides the nosmt case isn't a sensible measure either. So, + * this mandate remains considerably benign. */ if (!cpu_online(cpu)) { if (topology_is_primary_thread(cpu) || !allow_smt_offline) { --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AD1D2D8364 for ; Sat, 12 Sep 2026 00:35:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173311; cv=none; b=OddJouruSyUUth9J8umbrc3gqZSyATnYQP7AamFJ4yv0bSWf7MHiqFX/zvdSBS3B6yfrcGTu8YhqUsFKzMSC3OwYNKhQz9wTz6Ge3EkgSspBOAPK5A82TBDVXg7sciYvjjeB4tpf/1fYuHRTD6CM3+avk37ozm/IBqec7b0G0V8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173311; c=relaxed/simple; bh=p0migYejU9N010P8ZHhopEIg+2ZfkCHshpwVI7sSvrU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rBcDE9chlgORFf4m/p5O073rh3m7C/ZtSzd0FqICpAXE6Nwa6U5S0dJdxKEZZl+VN6VPOQfjFom7iUmhDs8Lz+sdrx7aQU3Qq30+5UwS0LEKUTrNU5a9cXhHwBReTI4Vdq/FxTFe9GG8pmsscppCugm6TzykkRxxT2mmNj9F41Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=LYDSU7mI; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="LYDSU7mI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173309; x=1820709309; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=p0migYejU9N010P8ZHhopEIg+2ZfkCHshpwVI7sSvrU=; b=LYDSU7mI4z3S3FD5GIF375Im3cHOKqYi80GMOzaNMiDlJl4hrYtimqjd 9EnZ8t3AFqcuO8UFJtoiMxkoBSr4vyP1e4pd5qjDTYzFEBkeygyNnhnVV tYeUR+nhMIjD7GddO892E/TkuL7ILL7V6d8hWHKJjhfkiVK0JqQGoCU5I BWHnNE/rHM/MInp+TyCgHpnALiG7U4lNNDjHb8iPqDxrDUMGnZxNSw6St lHP3hL9FHwRz/0uFbXDLCFzI6j3DMCwpyw9/s2qcAf8tfRaUzXcsEAZEI PlVI7acRvkRQSNiX2ziFL2hkcROLmbGTxuvJG6mh3FFNFWMn3CehX15H4 Q==; X-CSE-ConnectionGUID: zXK94IsOQSynSOxv1X6elg== X-CSE-MsgGUID: JWIFYwrITWOa+9VhC+g1uQ== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174979" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174979" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:09 -0700 X-CSE-ConnectionGUID: 7esh7jKWRYyX9j2GdbHZpg== X-CSE-MsgGUID: XVzZhznYQH27jSZWTSHDww== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217668" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:09 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 6/8] x86/microcode: Support uniform scope for late loading Date: Sat, 12 Sep 2026 00:08:12 +0000 Message-ID: <20260912000815.997720-7-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the late-loading path, per-CPU storage records a primary CPU in the ctrl_cpu field of struct microcode_ctrl. The primary CPU is then responsible for coordinating updates for the CPUs within its loading scope via __load_primary(). To support uniform loading, provide helpers that allow a given CPU to identify either its corresponding primary CPU or the set of CPUs in its loading scope. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/core.c | 38 +++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 8f617745d4d0..dfa311a2edbd 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -296,6 +296,36 @@ static void reload_early_microcode(unsigned int cpu) static struct faux_device *microcode_fdev; =20 #ifdef CONFIG_MICROCODE_LATE_LOADING + +/* + * Return the CPU mask corresponding to the update scope that @cpu belongs= to. + * Unknown scopes fall back to the legacy per-core scope. + */ +static const struct cpumask *ucode_scope_cpumask(unsigned int cpu) +{ + if (!microcode_ops->use_uniform) + return topology_sibling_cpumask(cpu); + + switch (microcode_ops->uniform_scope) { + case UNIFORM_PKG: + return topology_core_cpumask(cpu); + case UNIFORM_SYS: + return cpu_online_mask; + case UNIFORM_DEFAULT: + case UNIFORM_CORE: + break; + default: + WARN_ON_ONCE(1); + } + + return topology_sibling_cpumask(cpu); +} + +static inline unsigned int ucode_primary_cpu(unsigned int cpu) +{ + return cpumask_first(ucode_scope_cpumask(cpu)); +} + /* * Late loading dance. Why the heavy-handed stomp_machine effort? * @@ -437,7 +467,7 @@ static noinstr void load_secondary(unsigned int cpu) =20 static void __load_primary(unsigned int cpu) { - struct cpumask *secondaries =3D topology_sibling_cpumask(cpu); + const struct cpumask *secondaries =3D ucode_scope_cpumask(cpu); enum sibling_ctrl ctrl; enum ucode_state ret; unsigned int sibling; @@ -736,11 +766,7 @@ static bool setup_cpus(void) continue; } =20 - /* - * Initialize the per CPU state. This is core scope for now, - * but prepared to take package or system scope into account. - */ - ctrl.ctrl_cpu =3D cpumask_first(topology_sibling_cpumask(cpu)); + ctrl.ctrl_cpu =3D ucode_primary_cpu(cpu); per_cpu(ucode_ctrl, cpu) =3D ctrl; } return true; --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74EB22F549F for ; Sat, 12 Sep 2026 00:35:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173312; cv=none; b=Svh6xxcPN69/YAGHlaDijK25AxW3DpC7JbQrA2zgIYaOyHih0TN1esdDDt96WHa0C7+ay8si5DBTwIVsIodAhAaIEPCive7XU66a5UeMeOLX9rBizHeGVlxzTO+NqMeWvWV7ZYzY6z+z8uBm+y8XiagVWTg9koXSmOrxYwICzvE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173312; c=relaxed/simple; bh=jSAeJNOqF8YEG9tUnSYtAHr8JZ8rjcLYO1EZl9WbSjU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n00INe/enC63FzUeGPBcC8g4YHzNawRz2Bf3TwwxsVMWx9rtc92AcYjhZbV45bF5D3x55CZ5Ot64hTkd6vIlGFJher4xXyv9hdIzUlErv6i4Lqp5xEABFKg0BmHuJfsN1akYCaI0Pu3IfQdcJ00r2HByxfrADf84XPu0zBqDocU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=XVIitJWR; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="XVIitJWR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173312; x=1820709312; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jSAeJNOqF8YEG9tUnSYtAHr8JZ8rjcLYO1EZl9WbSjU=; b=XVIitJWR0XG2iS92n9AWUxijf5+/jjeJ+G5mjLBQeZZBWx7kB2lDMP6S 4yi7Bq/sqd/7sECQgsRkasi2AQ75KqVavtksEGaeNPCEJCIuuQZr1rEId fXwBROqViFoi5ifPye/obUMB076cSmud/V08lL+AOjssXXJhoHbnbBX/F NeU5l5nTK3jsrIfl3IFd8eip3tvSp8wHOXu82CxsABz3KPOSBOTlMO6bD eXeI/P+JNh4VMNETf5gONdiy3AxPSq7mfcMEMJa49rxwAOGp/xjJpjoTk fOOocKbX7OM/KYFyMlgdKAO5N65rYVszedlxNvjnV8Mv7lm5d0LgFu6nC w==; X-CSE-ConnectionGUID: RHCbwAm1TaOMrGVOCLZKqQ== X-CSE-MsgGUID: 5H680vRmTuGu/nacRH3Mew== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174983" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174983" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:11 -0700 X-CSE-ConnectionGUID: KNRLmKe5Q6OF3VHYiDueAw== X-CSE-MsgGUID: rBfgnburTpOnyYO5OLdrlg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217693" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:11 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 7/8] x86/microcode/intel: Support uniform scope for early loading Date: Sat, 12 Sep 2026 00:08:13 +0000 Message-ID: <20260912000815.997720-8-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The parallel bringup facility queries whether the architecture provides a custom set of primary CPUs. Extend x86 hooks with the Intel-specific logic so that the primary CPU selection matches the uniform loading scope. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/core.c | 9 +++ arch/x86/kernel/cpu/microcode/intel.c | 70 ++++++++++++++++++++++++ arch/x86/kernel/cpu/microcode/internal.h | 4 ++ 3 files changed, 83 insertions(+) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index dfa311a2edbd..ed547f2b4601 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -906,14 +906,23 @@ static int mc_cpu_down_prep(unsigned int cpu) /* * Queried by the parallel bringup code to determine whether x86 provides a * custom primary CPU mask for early loading. + * + * Uniform loading scope is Intel-specific, so let the vendor code determi= ne the + * primary CPU selection. */ bool __init arch_cpuhp_primary_aware(void) { + if (x86_cpuid_vendor() =3D=3D X86_VENDOR_INTEL) + return intel_primary_aware(); + return __max_threads_per_core > 1; } =20 const struct cpumask *__init arch_cpuhp_get_primary_cpus(void) { + if (x86_cpuid_vendor() =3D=3D X86_VENDOR_INTEL) + return intel_get_primary_cpus(); + return cpu_primary_thread_mask; } =20 diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 4b5feee14712..6178bddb7f60 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -989,6 +989,76 @@ static __init bool staging_available(void) return !!(val & MCU_STAGING); } =20 +bool __init intel_primary_aware(void) +{ + if (!microcode_intel_ops.use_uniform) + return __max_threads_per_core > 1; + + switch (microcode_intel_ops.uniform_scope) { + case UNIFORM_SYS: + /* + * The boot CPU performs the update for the entire system. But, + * returning false would fall back to the SMT primary mask. + * Return true to indicate the primary CPU clearly. + */ + return true; + case UNIFORM_PKG: + /* One primary core per package participates. */ + return true; + case UNIFORM_DEFAULT: + case UNIFORM_CORE: + /* + * Fallback to the legacy per-core loading, where the primary + * CPU distinction matters only when SMT is on. + */ + break; + default: + /* Unknown scopes fall back to the legacy per-core scope. */ + WARN_ON_ONCE(1); + } + + return __max_threads_per_core > 1; +} + +static struct cpumask primary_cpus __initdata; + +static void __init set_primary_cpus(void) +{ + if (!microcode_intel_ops.use_uniform) { + cpumask_copy(&primary_cpus, cpu_primary_thread_mask); + return; + } + + switch (microcode_intel_ops.uniform_scope) { + case UNIFORM_SYS: + /* + * CPU0 is guaranteed to be online and acts as the system + * primary. + */ + cpumask_set_cpu(0, &primary_cpus); + break; + case UNIFORM_PKG: + /* One CPU per package is sufficient. */ + cpumask_and(&primary_cpus, cpu_primary_core_mask, cpu_primary_thread_mas= k); + break; + case UNIFORM_DEFAULT: + case UNIFORM_CORE: + default: + cpumask_copy(&primary_cpus, cpu_primary_thread_mask); + } +} + +/* + * The bringup code may query the mask more than once. Compute it on first= use. + */ +const struct cpumask *__init intel_get_primary_cpus(void) +{ + if (cpumask_empty(&primary_cpus)) + set_primary_cpus(); + + return &primary_cpus; +} + struct microcode_ops * __init init_intel_microcode(void) { struct cpuinfo_x86 *c =3D &boot_cpu_data; diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu= /microcode/internal.h index 0a74794e0245..0552d66f4012 100644 --- a/arch/x86/kernel/cpu/microcode/internal.h +++ b/arch/x86/kernel/cpu/microcode/internal.h @@ -128,11 +128,15 @@ static inline void exit_amd_microcode(void) { } void load_ucode_intel_bsp(struct early_load_data *ed); void load_ucode_intel_ap(void); void reload_ucode_intel(void); +bool intel_primary_aware(void); +const struct cpumask *intel_get_primary_cpus(void); struct microcode_ops *init_intel_microcode(void); #else /* CONFIG_CPU_SUP_INTEL */ static inline void load_ucode_intel_bsp(struct early_load_data *ed) { } static inline void load_ucode_intel_ap(void) { } static inline void reload_ucode_intel(void) { } +static inline bool intel_primary_aware(void) { return false; } +static inline const struct cpumask *intel_get_primary_cpus(void) { return = cpu_none_mask; } static inline struct microcode_ops *init_intel_microcode(void) { return NU= LL; } #endif /* !CONFIG_CPU_SUP_INTEL */ =20 --=20 2.53.0 From nobody Fri Sep 25 13:19:17 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6C4C2F7EF5 for ; Sat, 12 Sep 2026 00:35:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173314; cv=none; b=LfPMThhXZa1X98O1HCictbijFuYUBqf2J5x4/10m9mI9OfzaTlePl7S7GhbiwK7088RwySCXWun2T2KaeP4TTKfjSC6WmyZkYrudDumqaUwcAKIT41oI16lmFDsjuJlnv2mxGBN3XejOfpwkRZsTpyWMG4PIrNOmgTDfeLHhuk0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789173314; c=relaxed/simple; bh=VazsLcKJUucH3Vht+P6pWie1oVKC3Ras5avUVWPi1hI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Gg7GFOpKrdRE3GMDj5h3hr9GaXktnwq6E5KE/pzAnoPkdSjGlQXJvvkUQofhofEb4B8y9txgVnU+QyX2junXJHD9pbNSRDyDbE3GWe/Iim/7KE/iWs1/MMb65puweVImyUyQkt2dr+mjdcWQQ299P+Bar4uVPxgzoDwuIabNr44= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=A1SPSlTm; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="A1SPSlTm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789173313; x=1820709313; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VazsLcKJUucH3Vht+P6pWie1oVKC3Ras5avUVWPi1hI=; b=A1SPSlTm8dqL8aU0cExhw4lpFheqP5zbcWu3vCrazfwRyuPehfpbw1jJ TazZUZVLp9eoKP6a0/cNCy0V9fgkaWZjaLFz2JiJYhd3KZpGVrf8uSHHQ Pz9z/tz/kN3JuzPHhBmg3MJXTZu38wmC08r+04yUZevtM3pgQCWJKVPwg Yy3dQ3x2Np9xXj5Gg92Jgx8VLs/9sv2Dnr+mv/YO2dln1Zw2A8M5BCq0y mn5QxlAaj6wHf+s0hCjMl0W/wLAU3DqxVHuS/0AHd0gzRIO/XTsUU9L9+ DR+z6UwMQa/lQqTHxgd/5eb0Nl7PQ0GkIyL8dA5aGhZl1N15ld9sHGZjS Q==; X-CSE-ConnectionGUID: 6tNM7cfHRGmO073G9nK01Q== X-CSE-MsgGUID: 2gKy3MMtSBSyWzRLcOmVmQ== X-IronPort-AV: E=McAfee;i="6800,10657,11902"; a="115174988" X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="115174988" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 17:35:13 -0700 X-CSE-ConnectionGUID: o6Nk2K7nSqK89mjcozDc6Q== X-CSE-MsgGUID: h5E1atBAQzGpoo6CSQ1kAA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,98,1787036400"; d="scan'208";a="276217724" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa005.jf.intel.com with ESMTP; 11 Sep 2026 17:35:12 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, kevin.shu@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC v1 8/8] x86/microcode/intel: Enable uniform loading Date: Sat, 12 Sep 2026 00:08:14 +0000 Message-ID: <20260912000815.997720-9-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com> References: <20260912000815.997720-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Uniform scopes are now available for both early- and late-loading paths. This feature simplifies the loading process by reducing the number of update triggers. Ignoring the CPU's uniform scope results in more triggers than necessary. While this behavior is acceptable, it can increase update latency, particularly for the late-loading path. Enable the feature. Certain invalid states, such as incomplete firmware configuration or an unknown loading scope, can leave the update mechanism unreliable. Detect those conditions early and disable the loader before any update occurs. Module, tile, and die scopes are also possible, but currently reserved for future implementations. Treat them as equivalent to the default per-core scope. Signed-off-by: Chang S. Bae --- arch/x86/include/asm/microcode.h | 2 + arch/x86/include/asm/msr-index.h | 10 ++++ arch/x86/kernel/cpu/microcode/core.c | 5 ++ arch/x86/kernel/cpu/microcode/intel.c | 69 +++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microc= ode.h index 645e65ac1586..710b79aa03ec 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -21,11 +21,13 @@ void load_ucode_bsp(void); void load_ucode_ap(void); void microcode_bsp_resume(void); bool __init microcode_loader_disabled(void); +void __init microcode_disable_loader(void); #else static inline void load_ucode_bsp(void) { } static inline void load_ucode_ap(void) { } static inline void microcode_bsp_resume(void) { } static inline bool __init microcode_loader_disabled(void) { return false; } +static inline bool __init microcode_disable_loader(void) { } #endif =20 extern unsigned long initrd_start_early; diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index 3a8e51a0c9e8..6a412371e02f 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -975,7 +975,17 @@ #define MSR_IA32_UCODE_WRITE 0x00000079 =20 #define MSR_IA32_MCU_ENUMERATION 0x0000007b +#define MCU_UNIFORM_AVAIL BIT(0) +#define MCU_UNIFORM_CONFIG_REQD BIT(1) +#define MCU_UNIFORM_CONFIG_COMPLETE BIT(2) #define MCU_STAGING BIT(4) +#define MCU_UNIFORM_SCOPE GENMASK(15, 8) +#define MCU_UNIFORM_SCOPE_CORE 0x02 +#define MCU_UNIFORM_SCOPE_MODULE 0x03 +#define MCU_UNIFORM_SCOPE_TILE 0x04 +#define MCU_UNIFORM_SCOPE_DIE 0x05 +#define MCU_UNIFORM_SCOPE_PACKAGE 0x80 +#define MCU_UNIFORM_SCOPE_PLATFORM 0xc0 =20 #define MSR_IA32_UCODE_REV 0x0000008b =20 diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index ed547f2b4601..887ffdc814de 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -111,6 +111,11 @@ static bool amd_check_current_patch_level(void) return false; } =20 +void __init microcode_disable_loader(void) +{ + dis_ucode_ldr =3D true; +} + bool __init microcode_loader_disabled(void) { if (dis_ucode_ldr) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 6178bddb7f60..e6c2b693f30b 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -23,6 +23,7 @@ #include #include #include +#include =20 #include #include @@ -69,6 +70,8 @@ static const char ucode_path[] =3D "kernel/x86/microcode/= GenuineIntel.bin"; =20 #define MBOX_XACTION_TIMEOUT_MS (10 * MSEC_PER_SEC) =20 +#define CPUID_EDX_ARCH_CAP BIT(29) + /* Current microcode patch used in early patching on the APs. */ static struct microcode_intel *ucode_patch_va __read_mostly; static struct microcode_intel *ucode_patch_late __read_mostly; @@ -737,11 +740,21 @@ static int __init save_builtin_microcode(void) } early_initcall(save_builtin_microcode); =20 +static __init void setup_uniform(void); + /* Load microcode on BSP from initrd or builtin blobs */ void __init load_ucode_intel_bsp(struct early_load_data *ed) { struct ucode_cpu_info uci; =20 + /* + * The loader could be disabled during the uniform setup if any firmware + * misconfiguration is found. + */ + setup_uniform(); + if (microcode_loader_disabled()) + return; + uci.mc =3D get_microcode_blob(&uci, false); ed->old_rev =3D uci.cpu_sig.rev; =20 @@ -989,6 +1002,62 @@ static __init bool staging_available(void) return !!(val & MCU_STAGING); } =20 +static __init void setup_uniform(void) +{ + u64 val; + + if (native_cpuid_eax(0) < 7) + return; + + if (!(native_cpuid_edx(7) & CPUID_EDX_ARCH_CAP)) + return; + + if (!(native_rdmsrq(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_MCU_ENUM)) + return; + + val =3D native_rdmsrq(MSR_IA32_MCU_ENUMERATION); + if (!(val & MCU_UNIFORM_AVAIL)) + return; + + /* + * Ensure that the firmware did all the necessary steps. Any improper + * configuration makes the update mechanism unusable. + */ + if (val & MCU_UNIFORM_CONFIG_REQD && !(val & MCU_UNIFORM_CONFIG_COMPLETE)= ) { + microcode_disable_loader(); + pr_err("loading disabled: incomplete firmware configuration.\n"); + return; + } + + /* + * Configure the uniform scope accordingly. To make it simple, treat all + * scopes narrower than the package scope as per-core scope. + */ + switch (FIELD_GET(MCU_UNIFORM_SCOPE, val)) { + case MCU_UNIFORM_SCOPE_MODULE: + case MCU_UNIFORM_SCOPE_TILE: + case MCU_UNIFORM_SCOPE_DIE: + pr_info("Uniform scope is narrower than package, using core scope.\n"); + fallthrough; + case MCU_UNIFORM_SCOPE_CORE: + microcode_intel_ops.uniform_scope =3D UNIFORM_CORE; + break; + case MCU_UNIFORM_SCOPE_PACKAGE: + microcode_intel_ops.uniform_scope =3D UNIFORM_PKG; + break; + case MCU_UNIFORM_SCOPE_PLATFORM: + microcode_intel_ops.uniform_scope =3D UNIFORM_SYS; + break; + default: + microcode_disable_loader(); + pr_err("loading disabled: unknown uniform scope.\n"); + return; + } + + microcode_intel_ops.use_uniform =3D true; + pr_info("Enabled uniform feature.\n"); +} + bool __init intel_primary_aware(void) { if (!microcode_intel_ops.use_uniform) --=20 2.53.0