From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3049C433F5 for ; Tue, 4 Oct 2022 08:12:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230049AbiJDIML (ORCPT ); Tue, 4 Oct 2022 04:12:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229910AbiJDILn (ORCPT ); Tue, 4 Oct 2022 04:11:43 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E1594F670 for ; Tue, 4 Oct 2022 01:10:34 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id BEFBE1F8D7; Tue, 4 Oct 2022 08:10:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871032; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FRQlMbR3LekauN/VGAqwz3/4iPTsfJTb9AkfSRaurK0=; b=Bc321u1uSx/Woo0VO1AgbzJrbEz3j0u/T50iz/y3r4mphjnc9Un9ZWZ3fE3YmPrp8RZSW7 SAf2fH3CQUoQAvjV0Qf0AV6hOhKMWXDgXgj5s50xhgNhU6kMqOr7EzZksDvhXmA1tNyfa2 KRPh0WuuTofShaWUItutW5O38uE/xCI= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 82513139EF; Tue, 4 Oct 2022 08:10:32 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id uq1sHnjqO2MlSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:10:32 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 01/16] x86/mtrr: add comment for set_mtrr_state() serialization Date: Tue, 4 Oct 2022 10:10:08 +0200 Message-Id: <20221004081023.32402-2-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a comment how set_mtrr_state() is needing serialization. Suggested-by: Borislav Petkov Signed-off-by: Juergen Gross --- V3: - new patch instead of old patch 1 --- arch/x86/kernel/cpu/mtrr/generic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index 558108296f3c..cd64eab02393 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -684,7 +684,10 @@ static u32 deftype_lo, deftype_hi; /** * set_mtrr_state - Set the MTRR state for this CPU. * - * NOTE: The CPU must already be in a safe state for MTRR changes. + * NOTE: The CPU must already be in a safe state for MTRR changes, includi= ng + * measures that only a single CPU can be active in set_mtrr_state()= in + * order to not be subject to races for usage of deftype_lo (this is + * accomplished by taking set_atomicity_lock). * RETURNS: 0 if no changes made, else a mask indicating what was changed. */ static unsigned long set_mtrr_state(void) --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B060BC433FE for ; Tue, 4 Oct 2022 08:12:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230061AbiJDIMQ (ORCPT ); Tue, 4 Oct 2022 04:12:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229885AbiJDILp (ORCPT ); Tue, 4 Oct 2022 04:11:45 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20C104AD61 for ; Tue, 4 Oct 2022 01:10:39 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 66CFC1F8EF; Tue, 4 Oct 2022 08:10:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871038; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8LiedMldWeIT3ErqqDfk2VgDsQE5AXBsEeh4EFbNTzw=; b=Kudt6qAVVcFkJOkAuDtlSMrvM71HTbTbxuB+3B+NVuLxGW7fZ4xg0xXfu3twTI1wg0dl33 Jt0fmbE3NNPQrvxDVILMLe1kjP2gfYzxaAHRndHXD3za+lZgCH0GzjIDJZlXQ7yp+uMWi2 or7dVgON8pJtspwDrifqxuqYIHbVQC8= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 2C377139EF; Tue, 4 Oct 2022 08:10:38 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id vdOACX7qO2MzSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:10:38 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 02/16] x86/mtrr: remove unused cyrix_set_all() function Date: Tue, 4 Oct 2022 10:10:09 +0200 Message-Id: <20221004081023.32402-3-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The Cyrix CPU specific MTRR function cyrix_set_all() will never be called, as the struct mtrr_ops set_all() callback will only be called in the use_intel() case, which would require the use_intel_if member of struct mtrr_ops to be set, which isn't the case for Cyrix. Signed-off-by: Juergen Gross --- V2: - new patch --- arch/x86/kernel/cpu/mtrr/cyrix.c | 34 -------------------------------- 1 file changed, 34 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cy= rix.c index ca670919b561..c77d3b0a5bf2 100644 --- a/arch/x86/kernel/cpu/mtrr/cyrix.c +++ b/arch/x86/kernel/cpu/mtrr/cyrix.c @@ -234,42 +234,8 @@ static void cyrix_set_arr(unsigned int reg, unsigned l= ong base, post_set(); } =20 -typedef struct { - unsigned long base; - unsigned long size; - mtrr_type type; -} arr_state_t; - -static arr_state_t arr_state[8] =3D { - {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, - {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} -}; - -static unsigned char ccr_state[7] =3D { 0, 0, 0, 0, 0, 0, 0 }; - -static void cyrix_set_all(void) -{ - int i; - - prepare_set(); - - /* the CCRs are not contiguous */ - for (i =3D 0; i < 4; i++) - setCx86(CX86_CCR0 + i, ccr_state[i]); - for (; i < 7; i++) - setCx86(CX86_CCR4 + i, ccr_state[i]); - - for (i =3D 0; i < 8; i++) { - cyrix_set_arr(i, arr_state[i].base, - arr_state[i].size, arr_state[i].type); - } - - post_set(); -} - static const struct mtrr_ops cyrix_mtrr_ops =3D { .vendor =3D X86_VENDOR_CYRIX, - .set_all =3D cyrix_set_all, .set =3D cyrix_set_arr, .get =3D cyrix_get_arr, .get_free_region =3D cyrix_get_free_region, --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DAE3C433F5 for ; Tue, 4 Oct 2022 08:12:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229942AbiJDIMU (ORCPT ); Tue, 4 Oct 2022 04:12:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229916AbiJDILq (ORCPT ); Tue, 4 Oct 2022 04:11:46 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2CF2262F for ; Tue, 4 Oct 2022 01:10:45 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 161B01F8D7; Tue, 4 Oct 2022 08:10:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871044; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=++0RAUux3FkgV6DJ2weOlHzVbEcfciRdmSrPPEXW7n4=; b=m6EyKBFLf5OiJP+xGO8aCC9ENOhiU2B3eqqUuWndQ8KTSVzP19+VcPialqt37KMt9sSFCi CDUm81lzLkpwUJ4tCh/mdXDhB2p/VYIzGVNHqbt/0ncvgocEAYOZmP0TOP2hb1zM38Y+cf J8IuWYrpnlot/Hoso6pmQbRvQ/AjU3o= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id CE92E139EF; Tue, 4 Oct 2022 08:10:43 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id BO2oMIPqO2M/SAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:10:43 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 03/16] x86/mtrr: replace use_intel() with a local flag Date: Tue, 4 Oct 2022 10:10:10 +0200 Message-Id: <20221004081023.32402-4-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In MTRR code use_intel() is only used in one source file, and the relevant use_intel_if member of struct mtrr_ops is set only in generic_mtrr_ops. Replace use_intel() with a single flag in cacheinfo.c, which can be set when assigning generic_mtrr_ops to mtrr_if. This allows to drop use_intel_if from mtrr_ops, while preparing to support PAT without MTRR. As another preparation for the PAT/MTRR decoupling use a bit for MTRR control and one for PAT control. For now set both bits together, this can be changed later. As the new flag will be set only if mtrr_enabled is set, the test for mtrr_enabled can be dropped at some places. At the same time drop the local mtrr_enabled() function and rename the __mtrr_enabled flag to mtrr_enabled. Signed-off-by: Juergen Gross --- V2: - new patch V4: - rename cache_generic to memory_caching_control (Borislav Petkov) - rename CACHE_GENERIC_* to CACHE_* (Borislav Petkov) - get rid of use_generic in mtrr_bp_init() (Borislav Petkov) --- arch/x86/include/asm/cacheinfo.h | 5 +++ arch/x86/kernel/cpu/cacheinfo.c | 3 ++ arch/x86/kernel/cpu/mtrr/generic.c | 1 - arch/x86/kernel/cpu/mtrr/mtrr.c | 55 +++++++++++++----------------- arch/x86/kernel/cpu/mtrr/mtrr.h | 2 -- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index 86b2e0dcc4bf..c3873962a7cd 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -2,6 +2,11 @@ #ifndef _ASM_X86_CACHEINFO_H #define _ASM_X86_CACHEINFO_H =20 +/* Kernel controls MTRR and/or PAT MSRs. */ +extern unsigned int memory_caching_control; +#define CACHE_MTRR 0x01 +#define CACHE_PAT 0x02 + void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); =20 diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 66556833d7af..5228fb9a3798 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -35,6 +35,9 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_= map); /* Shared L2 cache maps */ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); =20 +/* Kernel controls MTRR and/or PAT MSRs. */ +unsigned int memory_caching_control __ro_after_init =3D 0; + struct _cache_table { unsigned char descriptor; char cache_type; diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index cd64eab02393..81742870ecc5 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -917,7 +917,6 @@ int positive_have_wrcomb(void) * Generic structure... */ const struct mtrr_ops generic_mtrr_ops =3D { - .use_intel_if =3D 1, .set_all =3D generic_set_all, .get =3D generic_get_mtrr, .get_free_region =3D generic_get_free_region, diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 2746cac9d8a9..dacb537da126 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -46,6 +46,7 @@ #include #include =20 +#include #include #include #include @@ -58,12 +59,7 @@ #define MTRR_TO_PHYS_WC_OFFSET 1000 =20 u32 num_var_ranges; -static bool __mtrr_enabled; - -static bool mtrr_enabled(void) -{ - return __mtrr_enabled; -} +static bool mtrr_enabled; =20 unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; static DEFINE_MUTEX(mtrr_mutex); @@ -119,11 +115,11 @@ static int have_wrcomb(void) } =20 /* This function returns the number of variable MTRRs */ -static void __init set_num_var_ranges(void) +static void __init set_num_var_ranges(bool use_generic) { unsigned long config =3D 0, dummy; =20 - if (use_intel()) + if (use_generic) rdmsr(MSR_MTRRcap, config, dummy); else if (is_cpu(AMD) || is_cpu(HYGON)) config =3D 2; @@ -303,7 +299,7 @@ int mtrr_add_page(unsigned long base, unsigned long siz= e, int i, replace, error; mtrr_type ltype; =20 - if (!mtrr_enabled()) + if (!mtrr_enabled) return -ENXIO; =20 error =3D mtrr_if->validate_add_page(base, size, type); @@ -451,7 +447,7 @@ static int mtrr_check(unsigned long base, unsigned long= size) int mtrr_add(unsigned long base, unsigned long size, unsigned int type, bool increment) { - if (!mtrr_enabled()) + if (!mtrr_enabled) return -ENODEV; if (mtrr_check(base, size)) return -EINVAL; @@ -480,7 +476,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned= long size) unsigned long lbase, lsize; int error =3D -EINVAL; =20 - if (!mtrr_enabled()) + if (!mtrr_enabled) return -ENODEV; =20 max =3D num_var_ranges; @@ -540,7 +536,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned= long size) */ int mtrr_del(int reg, unsigned long base, unsigned long size) { - if (!mtrr_enabled()) + if (!mtrr_enabled) return -ENODEV; if (mtrr_check(base, size)) return -EINVAL; @@ -566,7 +562,7 @@ int arch_phys_wc_add(unsigned long base, unsigned long = size) { int ret; =20 - if (pat_enabled() || !mtrr_enabled()) + if (pat_enabled() || !mtrr_enabled) return 0; /* Success! (We don't need to do anything.) */ =20 ret =3D mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); @@ -755,15 +751,17 @@ void __init mtrr_bp_init(void) } =20 if (mtrr_if) { - __mtrr_enabled =3D true; - set_num_var_ranges(); + mtrr_enabled =3D true; + set_num_var_ranges(mtrr_if =3D=3D &generic_mtrr_ops); init_table(); - if (use_intel()) { + if (mtrr_if =3D=3D &generic_mtrr_ops) { /* BIOS may override */ - __mtrr_enabled =3D get_mtrr_state(); + mtrr_enabled =3D get_mtrr_state(); =20 - if (mtrr_enabled()) + if (mtrr_enabled) { mtrr_bp_pat_init(); + memory_caching_control |=3D CACHE_MTRR | CACHE_PAT; + } =20 if (mtrr_cleanup(phys_addr)) { changed_by_mtrr_cleanup =3D 1; @@ -772,7 +770,7 @@ void __init mtrr_bp_init(void) } } =20 - if (!mtrr_enabled()) { + if (!mtrr_enabled) { pr_info("Disabled\n"); =20 /* @@ -786,10 +784,7 @@ void __init mtrr_bp_init(void) =20 void mtrr_ap_init(void) { - if (!mtrr_enabled()) - return; - - if (!use_intel() || mtrr_aps_delayed_init) + if (!memory_caching_control || mtrr_aps_delayed_init) return; =20 /* @@ -816,7 +811,7 @@ void mtrr_save_state(void) { int first_cpu; =20 - if (!mtrr_enabled()) + if (!mtrr_enabled) return; =20 first_cpu =3D cpumask_first(cpu_online_mask); @@ -825,9 +820,7 @@ void mtrr_save_state(void) =20 void set_mtrr_aps_delayed_init(void) { - if (!mtrr_enabled()) - return; - if (!use_intel()) + if (!memory_caching_control) return; =20 mtrr_aps_delayed_init =3D true; @@ -838,7 +831,7 @@ void set_mtrr_aps_delayed_init(void) */ void mtrr_aps_init(void) { - if (!use_intel() || !mtrr_enabled()) + if (!memory_caching_control) return; =20 /* @@ -855,7 +848,7 @@ void mtrr_aps_init(void) =20 void mtrr_bp_restore(void) { - if (!use_intel() || !mtrr_enabled()) + if (!memory_caching_control) return; =20 mtrr_if->set_all(); @@ -863,10 +856,10 @@ void mtrr_bp_restore(void) =20 static int __init mtrr_init_finialize(void) { - if (!mtrr_enabled()) + if (!mtrr_enabled) return 0; =20 - if (use_intel()) { + if (memory_caching_control & CACHE_MTRR) { if (!changed_by_mtrr_cleanup) mtrr_state_warn(); return 0; diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtr= r.h index 2ac99e561181..88b1c4b6174a 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -14,7 +14,6 @@ extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; =20 struct mtrr_ops { u32 vendor; - u32 use_intel_if; void (*set)(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type); void (*set_all)(void); @@ -61,7 +60,6 @@ extern u64 size_or_mask, size_and_mask; extern const struct mtrr_ops *mtrr_if; =20 #define is_cpu(vnd) (mtrr_if && mtrr_if->vendor =3D=3D X86_VENDOR_##vnd) -#define use_intel() (mtrr_if && mtrr_if->use_intel_if =3D=3D 1) =20 extern unsigned int num_var_ranges; extern u64 mtrr_tom2; --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF372C433FE for ; Tue, 4 Oct 2022 08:12:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230087AbiJDIMY (ORCPT ); Tue, 4 Oct 2022 04:12:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229957AbiJDILr (ORCPT ); Tue, 4 Oct 2022 04:11:47 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2101628C for ; Tue, 4 Oct 2022 01:10:51 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id ADF8D219B8; Tue, 4 Oct 2022 08:10:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871049; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gjmwwu1nE4qkYJE0/hC2MZUBh8G9fijNxWNwmPmBasU=; b=DVu6v5FoLKVOrgK5jO+421ff2z/pj87ACPEAecU0yyYwRK5dpy8XZ9V40p8jit2fNM6qmy 5NbVGJXoKH/PCs6Oh6R2Sm6+Yq9Rz7vvbIRUPPx6Oes7jaq1o1Ze+89CzlDArt8MP76x5u D9zcCUC0zplskBcsTvsa/dQL5X1G8jo= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 73C2A139EF; Tue, 4 Oct 2022 08:10:49 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id izYAG4nqO2NHSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:10:49 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 04/16] x86/mtrr: rename prepare_set() and post_set() Date: Tue, 4 Oct 2022 10:10:11 +0200 Message-Id: <20221004081023.32402-5-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rename the currently MTRR specific functions prepare_set() and post_set() for preparing to move them. Make them non-static and put their prototypes into cacheinfo.h, where they will end after moving them to their final position anyway. Expand the comment before the functions with an introductory line and rename two related static variables, too. Signed-off-by: Juergen Gross --- V4: - carved out from other patch (Borislav Petkov) --- arch/x86/include/asm/cacheinfo.h | 3 +++ arch/x86/kernel/cpu/mtrr/generic.c | 43 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index c3873962a7cd..6159874b4183 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -10,4 +10,7 @@ extern unsigned int memory_caching_control; void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); =20 +void cache_disable(void); +void cache_enable(void); + #endif /* _ASM_X86_CACHEINFO_H */ diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index 81742870ecc5..aebdc90a2489 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -10,6 +10,7 @@ #include =20 #include +#include #include #include #include @@ -396,9 +397,6 @@ print_fixed(unsigned base, unsigned step, const mtrr_ty= pe *types) } } =20 -static void prepare_set(void); -static void post_set(void); - static void __init print_mtrr_state(void) { unsigned int i; @@ -450,11 +448,11 @@ void __init mtrr_bp_pat_init(void) unsigned long flags; =20 local_irq_save(flags); - prepare_set(); + cache_disable(); =20 pat_init(); =20 - post_set(); + cache_enable(); local_irq_restore(flags); } =20 @@ -687,7 +685,7 @@ static u32 deftype_lo, deftype_hi; * NOTE: The CPU must already be in a safe state for MTRR changes, includi= ng * measures that only a single CPU can be active in set_mtrr_state()= in * order to not be subject to races for usage of deftype_lo (this is - * accomplished by taking set_atomicity_lock). + * accomplished by taking cache_disable_lock). * RETURNS: 0 if no changes made, else a mask indicating what was changed. */ static unsigned long set_mtrr_state(void) @@ -718,18 +716,19 @@ static unsigned long set_mtrr_state(void) return change_mask; } =20 - -static unsigned long cr4; -static DEFINE_RAW_SPINLOCK(set_atomicity_lock); - /* + * Disable and enable caches. Needed for changing MTRRs and the PAT MSR. + * * Since we are disabling the cache don't allow any interrupts, * they would run extremely slow and would only increase the pain. * * The caller must ensure that local interrupts are disabled and - * are reenabled after post_set() has been called. + * are reenabled after cache_enable() has been called. */ -static void prepare_set(void) __acquires(set_atomicity_lock) +static unsigned long saved_cr4; +static DEFINE_RAW_SPINLOCK(cache_disable_lock); + +void cache_disable(void) __acquires(cache_disable_lock) { unsigned long cr0; =20 @@ -740,7 +739,7 @@ static void prepare_set(void) __acquires(set_atomicity_= lock) * changes to the way the kernel boots */ =20 - raw_spin_lock(&set_atomicity_lock); + raw_spin_lock(&cache_disable_lock); =20 /* Enter the no-fill (CD=3D1, NW=3D0) cache mode and flush caches. */ cr0 =3D read_cr0() | X86_CR0_CD; @@ -757,8 +756,8 @@ static void prepare_set(void) __acquires(set_atomicity_= lock) =20 /* Save value of CR4 and clear Page Global Enable (bit 7) */ if (boot_cpu_has(X86_FEATURE_PGE)) { - cr4 =3D __read_cr4(); - __write_cr4(cr4 & ~X86_CR4_PGE); + saved_cr4 =3D __read_cr4(); + __write_cr4(saved_cr4 & ~X86_CR4_PGE); } =20 /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ @@ -776,7 +775,7 @@ static void prepare_set(void) __acquires(set_atomicity_= lock) wbinvd(); } =20 -static void post_set(void) __releases(set_atomicity_lock) +void cache_enable(void) __releases(cache_disable_lock) { /* Flush TLBs (no need to flush caches - they are disabled) */ count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); @@ -790,8 +789,8 @@ static void post_set(void) __releases(set_atomicity_loc= k) =20 /* Restore value of CR4 */ if (boot_cpu_has(X86_FEATURE_PGE)) - __write_cr4(cr4); - raw_spin_unlock(&set_atomicity_lock); + __write_cr4(saved_cr4); + raw_spin_unlock(&cache_disable_lock); } =20 static void generic_set_all(void) @@ -800,7 +799,7 @@ static void generic_set_all(void) unsigned long flags; =20 local_irq_save(flags); - prepare_set(); + cache_disable(); =20 /* Actually set the state */ mask =3D set_mtrr_state(); @@ -808,7 +807,7 @@ static void generic_set_all(void) /* also set PAT */ pat_init(); =20 - post_set(); + cache_enable(); local_irq_restore(flags); =20 /* Use the atomic bitops to update the global mask */ @@ -839,7 +838,7 @@ static void generic_set_mtrr(unsigned int reg, unsigned= long base, vr =3D &mtrr_state.var_ranges[reg]; =20 local_irq_save(flags); - prepare_set(); + cache_disable(); =20 if (size =3D=3D 0) { /* @@ -858,7 +857,7 @@ static void generic_set_mtrr(unsigned int reg, unsigned= long base, mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi); } =20 - post_set(); + cache_enable(); local_irq_restore(flags); } =20 --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E654C433F5 for ; Tue, 4 Oct 2022 08:12:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229963AbiJDIMc (ORCPT ); Tue, 4 Oct 2022 04:12:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229846AbiJDILt (ORCPT ); Tue, 4 Oct 2022 04:11:49 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8332838C for ; Tue, 4 Oct 2022 01:10:57 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 4C8E1219BD; Tue, 4 Oct 2022 08:10:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871055; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BdNeASTIsigsn6I6gmyehllEZ5HmkU4n1YF0DHyGpbk=; b=Ix0S2B9lhA4qEUjm+JLZOCjYCs/xP8J4zXUnkK6JaypVlLNIcDCZ5kJQYpvfJyqsoMYgUk 5k6xl8jVh0n4Pgq4XmMDSdAl0Ho3+5c16a33gQSr9hiiw7fnkmcD8glAFy7vK2K2eHIDpa crTzy2P1dMQQRDuD5Y+1T6F/RmP/4ms= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 14949139EF; Tue, 4 Oct 2022 08:10:55 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id MpbcA4/qO2NTSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:10:55 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 05/16] x86/mtrr: split MTRR specific handling from cache dis/enabling Date: Tue, 4 Oct 2022 10:10:12 +0200 Message-Id: <20221004081023.32402-6-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Split the MTRR specific actions from cache_disable() and cache_enable() into the new functions mtrr_disable() and mtrr_enable(). Signed-off-by: Juergen Gross --- V4: - carved out from other patch (Borislav Petkov) --- arch/x86/include/asm/mtrr.h | 4 ++++ arch/x86/kernel/cpu/mtrr/generic.c | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 76d726074c16..12a16caed395 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -48,6 +48,8 @@ extern void mtrr_aps_init(void); extern void mtrr_bp_restore(void); extern int mtrr_trim_uncached_memory(unsigned long end_pfn); extern int amd_special_default_mtrr(void); +void mtrr_disable(void); +void mtrr_enable(void); # else static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform) { @@ -87,6 +89,8 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 l= o, u32 hi) #define set_mtrr_aps_delayed_init() do {} while (0) #define mtrr_aps_init() do {} while (0) #define mtrr_bp_restore() do {} while (0) +#define mtrr_disable() do {} while (0) +#define mtrr_enable() do {} while (0) # endif =20 #ifdef CONFIG_COMPAT diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index aebdc90a2489..164d753e9867 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -716,6 +716,21 @@ static unsigned long set_mtrr_state(void) return change_mask; } =20 +void mtrr_disable(void) +{ + /* Save MTRR state */ + rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); + + /* Disable MTRRs, and set the default type to uncached */ + mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); +} + +void mtrr_enable(void) +{ + /* Intel (P6) standard MTRRs */ + mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); +} + /* * Disable and enable caches. Needed for changing MTRRs and the PAT MSR. * @@ -764,11 +779,8 @@ void cache_disable(void) __acquires(cache_disable_lock) count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); flush_tlb_local(); =20 - /* Save MTRR state */ - rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); - - /* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); + if (boot_cpu_has(X86_FEATURE_MTRR)) + mtrr_disable(); =20 /* Again, only flush caches if we have to. */ if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) @@ -781,8 +793,8 @@ void cache_enable(void) __releases(cache_disable_lock) count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); flush_tlb_local(); =20 - /* Intel (P6) standard MTRRs */ - mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); + if (boot_cpu_has(X86_FEATURE_MTRR)) + mtrr_enable(); =20 /* Enable caches */ write_cr0(read_cr0() & ~X86_CR0_CD); --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A45D7C433FE for ; Tue, 4 Oct 2022 08:12:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229889AbiJDIM2 (ORCPT ); Tue, 4 Oct 2022 04:12:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229722AbiJDILs (ORCPT ); Tue, 4 Oct 2022 04:11:48 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 147FB117E for ; Tue, 4 Oct 2022 01:11:03 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id EC80B1F8D7; Tue, 4 Oct 2022 08:11:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871060; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C0neM2l7Apug14QCmm2699jmJrzVf7rSxrhTZuFYG4w=; b=BOimeAUNjhFBaFgZWCBlvFGvcmw8gL+Khva8wqJYKEJK+tQHbfHRVZMu3WpTNN3bHTH1it iifZtFwDhvXftAwiGtwMQSV2ThOQMcU+r7JEms5pS+EBKVslSVVMJf3z+nq9A9KzixjSkV +dc6cwmYCL/g7N+la/vg+pH8MA5B7QA= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id AD3C6139EF; Tue, 4 Oct 2022 08:11:00 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id GxgRKZTqO2NWSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:00 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 06/16] x86: move some code out of arch/x86/kernel/cpu/mtrr Date: Tue, 4 Oct 2022 10:10:13 +0200 Message-Id: <20221004081023.32402-7-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Prepare making PAT and MTRR support independent from each other by moving some code needed by both out of the MTRR specific sources. Signed-off-by: Juergen Gross --- V2: - move code from cpu/common.c to cpu/cacheinfo.c (Borislav Petkov) V4: - carved out all non-movement modifications (Borislav Petkov) --- arch/x86/kernel/cpu/cacheinfo.c | 77 ++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/mtrr/generic.c | 74 ---------------------------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 5228fb9a3798..ff32b2b1ca23 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include =20 #include "cpu.h" =20 @@ -1043,3 +1045,78 @@ int populate_cache_leaves(unsigned int cpu) =20 return 0; } + +/* + * Disable and enable caches. Needed for changing MTRRs and the PAT MSR. + * + * Since we are disabling the cache don't allow any interrupts, + * they would run extremely slow and would only increase the pain. + * + * The caller must ensure that local interrupts are disabled and + * are reenabled after cache_enable() has been called. + */ +static unsigned long saved_cr4; +static DEFINE_RAW_SPINLOCK(cache_disable_lock); + +void cache_disable(void) __acquires(cache_disable_lock) +{ + unsigned long cr0; + + /* + * Note that this is not ideal + * since the cache is only flushed/disabled for this CPU while the + * MTRRs are changed, but changing this requires more invasive + * changes to the way the kernel boots + */ + + raw_spin_lock(&cache_disable_lock); + + /* Enter the no-fill (CD=3D1, NW=3D0) cache mode and flush caches. */ + cr0 =3D read_cr0() | X86_CR0_CD; + write_cr0(cr0); + + /* + * Cache flushing is the most time-consuming step when programming + * the MTRRs. Fortunately, as per the Intel Software Development + * Manual, we can skip it if the processor supports cache self- + * snooping. + */ + if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) + wbinvd(); + + /* Save value of CR4 and clear Page Global Enable (bit 7) */ + if (boot_cpu_has(X86_FEATURE_PGE)) { + saved_cr4 =3D __read_cr4(); + __write_cr4(saved_cr4 & ~X86_CR4_PGE); + } + + /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ + count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); + flush_tlb_local(); + + if (boot_cpu_has(X86_FEATURE_MTRR)) + mtrr_disable(); + + /* Again, only flush caches if we have to. */ + if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) + wbinvd(); +} + +void cache_enable(void) __releases(cache_disable_lock) +{ + /* Flush TLBs (no need to flush caches - they are disabled) */ + count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); + flush_tlb_local(); + + if (boot_cpu_has(X86_FEATURE_MTRR)) + mtrr_enable(); + + /* Enable caches */ + write_cr0(read_cr0() & ~X86_CR0_CD); + + /* Restore value of CR4 */ + if (boot_cpu_has(X86_FEATURE_PGE)) + __write_cr4(saved_cr4); + + raw_spin_unlock(&cache_disable_lock); +} diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index 164d753e9867..bfe13eedaca8 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -731,80 +731,6 @@ void mtrr_enable(void) mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); } =20 -/* - * Disable and enable caches. Needed for changing MTRRs and the PAT MSR. - * - * Since we are disabling the cache don't allow any interrupts, - * they would run extremely slow and would only increase the pain. - * - * The caller must ensure that local interrupts are disabled and - * are reenabled after cache_enable() has been called. - */ -static unsigned long saved_cr4; -static DEFINE_RAW_SPINLOCK(cache_disable_lock); - -void cache_disable(void) __acquires(cache_disable_lock) -{ - unsigned long cr0; - - /* - * Note that this is not ideal - * since the cache is only flushed/disabled for this CPU while the - * MTRRs are changed, but changing this requires more invasive - * changes to the way the kernel boots - */ - - raw_spin_lock(&cache_disable_lock); - - /* Enter the no-fill (CD=3D1, NW=3D0) cache mode and flush caches. */ - cr0 =3D read_cr0() | X86_CR0_CD; - write_cr0(cr0); - - /* - * Cache flushing is the most time-consuming step when programming - * the MTRRs. Fortunately, as per the Intel Software Development - * Manual, we can skip it if the processor supports cache self- - * snooping. - */ - if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) - wbinvd(); - - /* Save value of CR4 and clear Page Global Enable (bit 7) */ - if (boot_cpu_has(X86_FEATURE_PGE)) { - saved_cr4 =3D __read_cr4(); - __write_cr4(saved_cr4 & ~X86_CR4_PGE); - } - - /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ - count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); - flush_tlb_local(); - - if (boot_cpu_has(X86_FEATURE_MTRR)) - mtrr_disable(); - - /* Again, only flush caches if we have to. */ - if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) - wbinvd(); -} - -void cache_enable(void) __releases(cache_disable_lock) -{ - /* Flush TLBs (no need to flush caches - they are disabled) */ - count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); - flush_tlb_local(); - - if (boot_cpu_has(X86_FEATURE_MTRR)) - mtrr_enable(); - - /* Enable caches */ - write_cr0(read_cr0() & ~X86_CR0_CD); - - /* Restore value of CR4 */ - if (boot_cpu_has(X86_FEATURE_PGE)) - __write_cr4(saved_cr4); - raw_spin_unlock(&cache_disable_lock); -} - static void generic_set_all(void) { unsigned long mask, count; --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0BB2C433F5 for ; Tue, 4 Oct 2022 08:12:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230110AbiJDIMm (ORCPT ); Tue, 4 Oct 2022 04:12:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230047AbiJDILw (ORCPT ); Tue, 4 Oct 2022 04:11:52 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B680B7E for ; Tue, 4 Oct 2022 01:11:08 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 92034219B8; Tue, 4 Oct 2022 08:11:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871066; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BTFT5yEVOlKLOCaID7kgIamryAoTtu6/XvN1SSiAlzw=; b=kdiuydR83doqu1zgH2Q8g4k2CIkun36JJJGgvvNCCQMV2tEdZHUbekXwdIcZM7nMikm5Q4 H0Nlw6ZjnS8JsX5zY9S5O6cVo10sGeeqJ39GuhG3Qtm3GXGhDO2K5tsNRpWMVbY5NKvtzf RRSwXaEvmcXc8HBpb2Psl3bj31FSeEk= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 575A1139EF; Tue, 4 Oct 2022 08:11:06 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id M44mFJrqO2NeSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:06 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 07/16] x86/mtrr: split generic_set_all() Date: Tue, 4 Oct 2022 10:10:14 +0200 Message-Id: <20221004081023.32402-8-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Split generic_set_all() into multiple parts, while moving the main function body into cacheinfo.c. Prepare the support of PAT without needing MTRR support by moving the main function body of generic_set_all() into cacheinfo.c while renaming it to cache_cpu_init(). The MTRR specific parts are moved into a dedicated small function called by cache_cpu_init() in order to make cache_cpu_init() as MTRR agnostic as possible. The setting of smp_changes_mask is merged into the (new) function mtrr_generic_set_state() used to call set_mtrr_state(). It was probably split in ancient times, as atomic operations while running uncached might be quite expensive, but OTOH only systems with a broken BIOS should ever require to set any bit in smp_changes_mask, so just hurting those devices with a penalty of a few microseconds during boot shouldn't be a real issue. Signed-off-by: Juergen Gross --- V2: - new patch V4: - remove some comments (Borislav Petkov) --- arch/x86/include/asm/cacheinfo.h | 1 + arch/x86/include/asm/mtrr.h | 2 ++ arch/x86/kernel/cpu/cacheinfo.c | 17 +++++++++++++++++ arch/x86/kernel/cpu/mtrr/generic.c | 15 ++------------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index 6159874b4183..978bac70fd49 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -12,5 +12,6 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, i= nt cpu); =20 void cache_disable(void); void cache_enable(void); +void cache_cpu_init(void); =20 #endif /* _ASM_X86_CACHEINFO_H */ diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 12a16caed395..986249a2b9b6 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -50,6 +50,7 @@ extern int mtrr_trim_uncached_memory(unsigned long end_pf= n); extern int amd_special_default_mtrr(void); void mtrr_disable(void); void mtrr_enable(void); +void mtrr_generic_set_state(void); # else static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform) { @@ -91,6 +92,7 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 l= o, u32 hi) #define mtrr_bp_restore() do {} while (0) #define mtrr_disable() do {} while (0) #define mtrr_enable() do {} while (0) +#define mtrr_generic_set_state() do {} while (0) # endif =20 #ifdef CONFIG_COMPAT diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index ff32b2b1ca23..49b60a427fc9 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -1120,3 +1120,20 @@ void cache_enable(void) __releases(cache_disable_loc= k) =20 raw_spin_unlock(&cache_disable_lock); } + +void cache_cpu_init(void) +{ + unsigned long flags; + + local_irq_save(flags); + cache_disable(); + + if (memory_caching_control & CACHE_MTRR) + mtrr_generic_set_state(); + + if (memory_caching_control & CACHE_PAT) + pat_init(); + + cache_enable(); + local_irq_restore(flags); +} diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index bfe13eedaca8..32aebed25e3f 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -731,30 +731,19 @@ void mtrr_enable(void) mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); } =20 -static void generic_set_all(void) +void mtrr_generic_set_state(void) { unsigned long mask, count; - unsigned long flags; - - local_irq_save(flags); - cache_disable(); =20 /* Actually set the state */ mask =3D set_mtrr_state(); =20 - /* also set PAT */ - pat_init(); - - cache_enable(); - local_irq_restore(flags); - /* Use the atomic bitops to update the global mask */ for (count =3D 0; count < sizeof(mask) * 8; ++count) { if (mask & 0x01) set_bit(count, &smp_changes_mask); mask >>=3D 1; } - } =20 /** @@ -854,7 +843,7 @@ int positive_have_wrcomb(void) * Generic structure... */ const struct mtrr_ops generic_mtrr_ops =3D { - .set_all =3D generic_set_all, + .set_all =3D cache_cpu_init, .get =3D generic_get_mtrr, .get_free_region =3D generic_get_free_region, .set =3D generic_set_mtrr, --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8A0EC433F5 for ; Tue, 4 Oct 2022 08:12:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230104AbiJDIMh (ORCPT ); Tue, 4 Oct 2022 04:12:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229912AbiJDILv (ORCPT ); Tue, 4 Oct 2022 04:11:51 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E4AD64E0 for ; Tue, 4 Oct 2022 01:11:14 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 3E95A219BD; Tue, 4 Oct 2022 08:11:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871072; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sTywZDx5uRgwnEEo9krOm0MUfpgr1DThTwZJSMEuMvI=; b=XbrNHjsqorneAM5hvphiO008+u7tQbZAMy9OICerPrz1WyenkVVDzYl+5BlrdIM2PXG5nO xAzBNXobk9Ss6eyCMHqRNMgNWKGZsDNcpNX4z5WOJl8XEXML4ww7B60QDPghIH3iAJHQK0 3UAiLjyzWJbQ97zQws3Ndv1gHoKlorU= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id F3EC4139EF; Tue, 4 Oct 2022 08:11:11 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Mv5POp/qO2NoSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:11 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 08/16] x86/mtrr: remove set_all callback from struct mtrr_ops Date: Tue, 4 Oct 2022 10:10:15 +0200 Message-Id: <20221004081023.32402-9-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Instead of using an indirect call to mtrr_if->set_all just call the only possible target cache_cpu_init() directly. This enables to remove the set_all callback from struct mtrr_ops. Signed-off-by: Juergen Gross --- arch/x86/kernel/cpu/mtrr/generic.c | 1 - arch/x86/kernel/cpu/mtrr/mtrr.c | 10 +++++----- arch/x86/kernel/cpu/mtrr/mtrr.h | 2 -- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index 32aebed25e3f..af8422c96b92 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -843,7 +843,6 @@ int positive_have_wrcomb(void) * Generic structure... */ const struct mtrr_ops generic_mtrr_ops =3D { - .set_all =3D cache_cpu_init, .get =3D generic_get_mtrr, .get_free_region =3D generic_get_free_region, .set =3D generic_set_mtrr, diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index dacb537da126..501ca1747d55 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -165,15 +165,15 @@ static int mtrr_rendezvous_handler(void *info) * saved, and we want to replicate that across all the cpus that come * online (either at the end of boot or resume or during a runtime cpu * online). If we're doing that, @reg is set to something special and on - * all the cpu's we do mtrr_if->set_all() (On the logical cpu that + * all the cpu's we do cache_cpu_init() (On the logical cpu that * started the boot/resume sequence, this might be a duplicate - * set_all()). + * cache_cpu_init()). */ if (data->smp_reg !=3D ~0U) { mtrr_if->set(data->smp_reg, data->smp_base, data->smp_size, data->smp_type); } else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) { - mtrr_if->set_all(); + cache_cpu_init(); } return 0; } @@ -765,7 +765,7 @@ void __init mtrr_bp_init(void) =20 if (mtrr_cleanup(phys_addr)) { changed_by_mtrr_cleanup =3D 1; - mtrr_if->set_all(); + cache_cpu_init(); } } } @@ -851,7 +851,7 @@ void mtrr_bp_restore(void) if (!memory_caching_control) return; =20 - mtrr_if->set_all(); + cache_cpu_init(); } =20 static int __init mtrr_init_finialize(void) diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtr= r.h index 88b1c4b6174a..3b1883185185 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -16,8 +16,6 @@ struct mtrr_ops { u32 vendor; void (*set)(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type); - void (*set_all)(void); - void (*get)(unsigned int reg, unsigned long *base, unsigned long *size, mtrr_type *type); int (*get_free_region)(unsigned long base, unsigned long size, --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54E77C433FE for ; Tue, 4 Oct 2022 08:12:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230115AbiJDIMw (ORCPT ); Tue, 4 Oct 2022 04:12:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230048AbiJDILz (ORCPT ); Tue, 4 Oct 2022 04:11:55 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A6D065E5 for ; Tue, 4 Oct 2022 01:11:19 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D9155219B8; Tue, 4 Oct 2022 08:11:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871077; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tjhFAyaLqHCvH39OzmLQawxoUpOV57qVfOb8KdlLKqU=; b=Qu9GfqpWZThC6n5lS+NuScgyxncCUmPfeWruyEnqHwTG9ERA0mk8rsajox67GNb7YtVuXc 1G6o9U3YnjxUwvRFTcba0qKXfcyvaMaC7iA0KzALvb+9Pm0BWPUJdgv/Y9wrfY5cxb2YaY 8NDDpZyzE+9oRJk6wE5xC3GPLOmfZeo= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 9DCD9139EF; Tue, 4 Oct 2022 08:11:17 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YNlOJaXqO2NxSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:17 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 09/16] x86/mtrr: simplify mtrr_bp_init() Date: Tue, 4 Oct 2022 10:10:16 +0200 Message-Id: <20221004081023.32402-10-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In case of the generic cache interface being used (Intel CPUs or a 64-bit system), the initialization sequence of the boot CPU is more complicated as necessary: - check if MTRR enabled, if yes, call mtrr_bp_pat_init() which will disable caching, set the PAT MSR, and reenable caching - call mtrr_cleanup(), in case that changed anything, call cache_cpu_init() doing the same caching disable/enable dance as above, but this time with setting the (modified) MTRR state (even if MTRR was disabled) AND setting the PAT MSR (again even with disabled MTRR) The sequence can be simplified a lot while removing potential inconsistencies: - check if MTRR enabled, if yes, call mtrr_cleanup() and then cache_cpu_init() This ensures to: - no longer disable/enable caching more than once - avoid to set MTRRs and/or the PAT MSR on the boot processor in case of MTRR cleanups even if MTRRs meant to be disabled With that mtrr_bp_pat_init() can be removed. Signed-off-by: Juergen Gross --- V2: - new patch --- arch/x86/kernel/cpu/mtrr/generic.c | 14 -------------- arch/x86/kernel/cpu/mtrr/mtrr.c | 6 +----- arch/x86/kernel/cpu/mtrr/mtrr.h | 1 - 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index af8422c96b92..2f2485d6657f 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -442,20 +442,6 @@ static void __init print_mtrr_state(void) pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20); } =20 -/* PAT setup for BP. We need to go through sync steps here */ -void __init mtrr_bp_pat_init(void) -{ - unsigned long flags; - - local_irq_save(flags); - cache_disable(); - - pat_init(); - - cache_enable(); - local_irq_restore(flags); -} - /* Grab all of the MTRR state for this CPU into *state */ bool __init get_mtrr_state(void) { diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 501ca1747d55..9e1b478ac896 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -759,12 +759,8 @@ void __init mtrr_bp_init(void) mtrr_enabled =3D get_mtrr_state(); =20 if (mtrr_enabled) { - mtrr_bp_pat_init(); memory_caching_control |=3D CACHE_MTRR | CACHE_PAT; - } - - if (mtrr_cleanup(phys_addr)) { - changed_by_mtrr_cleanup =3D 1; + changed_by_mtrr_cleanup =3D mtrr_cleanup(phys_addr); cache_cpu_init(); } } diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtr= r.h index 3b1883185185..c98928ceee6a 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -50,7 +50,6 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt); void fill_mtrr_var_range(unsigned int index, u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); bool get_mtrr_state(void); -void mtrr_bp_pat_init(void); =20 extern void __init set_mtrr_ops(const struct mtrr_ops *ops); =20 --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A16F4C433FE for ; Tue, 4 Oct 2022 08:12:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230125AbiJDIM5 (ORCPT ); Tue, 4 Oct 2022 04:12:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229938AbiJDIL4 (ORCPT ); Tue, 4 Oct 2022 04:11:56 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39F9010FE5 for ; Tue, 4 Oct 2022 01:11:25 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 85098219B0; Tue, 4 Oct 2022 08:11:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871083; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Tj4aELXaya1CaSjViiaKMXOfNXjJijcbMqgP3t4oiQA=; b=HVmgXUg+EIcCSmyVSFKEIollTXBD3At3iVM/zHCr25HtbpymoSptLLUWjnA0/Be+iOT1Tc ++I16uI7wsxXrt8/PKZvURJRNN98Kx0z3rLS6O6a9gZ7n4miZlcshAOLB/JODEsblBGbFz vxy5n8J7L55Bo34U6G74wbfBJEkjW0I= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 4BE01139EF; Tue, 4 Oct 2022 08:11:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 16syEavqO2OGSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:23 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 10/16] x86/mtrr: get rid of mtrr_enabled bool Date: Tue, 4 Oct 2022 10:10:17 +0200 Message-Id: <20221004081023.32402-11-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" There is no need for keeping mtrr_enabled, as it can easily be replaced by testing mtrr_if to be not NULL. Signed-off-by: Juergen Gross --- V4: - new patch --- arch/x86/kernel/cpu/mtrr/mtrr.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 9e1b478ac896..7eed5387e828 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -59,7 +59,6 @@ #define MTRR_TO_PHYS_WC_OFFSET 1000 =20 u32 num_var_ranges; -static bool mtrr_enabled; =20 unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; static DEFINE_MUTEX(mtrr_mutex); @@ -299,7 +298,7 @@ int mtrr_add_page(unsigned long base, unsigned long siz= e, int i, replace, error; mtrr_type ltype; =20 - if (!mtrr_enabled) + if (!mtrr_if) return -ENXIO; =20 error =3D mtrr_if->validate_add_page(base, size, type); @@ -447,7 +446,7 @@ static int mtrr_check(unsigned long base, unsigned long= size) int mtrr_add(unsigned long base, unsigned long size, unsigned int type, bool increment) { - if (!mtrr_enabled) + if (!mtrr_if) return -ENODEV; if (mtrr_check(base, size)) return -EINVAL; @@ -476,7 +475,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned= long size) unsigned long lbase, lsize; int error =3D -EINVAL; =20 - if (!mtrr_enabled) + if (!mtrr_if) return -ENODEV; =20 max =3D num_var_ranges; @@ -536,7 +535,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned= long size) */ int mtrr_del(int reg, unsigned long base, unsigned long size) { - if (!mtrr_enabled) + if (!mtrr_if) return -ENODEV; if (mtrr_check(base, size)) return -EINVAL; @@ -562,7 +561,7 @@ int arch_phys_wc_add(unsigned long base, unsigned long = size) { int ret; =20 - if (pat_enabled() || !mtrr_enabled) + if (pat_enabled() || !mtrr_if) return 0; /* Success! (We don't need to do anything.) */ =20 ret =3D mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); @@ -751,22 +750,21 @@ void __init mtrr_bp_init(void) } =20 if (mtrr_if) { - mtrr_enabled =3D true; set_num_var_ranges(mtrr_if =3D=3D &generic_mtrr_ops); init_table(); if (mtrr_if =3D=3D &generic_mtrr_ops) { /* BIOS may override */ - mtrr_enabled =3D get_mtrr_state(); - - if (mtrr_enabled) { + if (get_mtrr_state()) { memory_caching_control |=3D CACHE_MTRR | CACHE_PAT; changed_by_mtrr_cleanup =3D mtrr_cleanup(phys_addr); cache_cpu_init(); + } else { + mtrr_if =3D NULL; } } } =20 - if (!mtrr_enabled) { + if (!mtrr_if) { pr_info("Disabled\n"); =20 /* @@ -807,7 +805,7 @@ void mtrr_save_state(void) { int first_cpu; =20 - if (!mtrr_enabled) + if (!mtrr_if) return; =20 first_cpu =3D cpumask_first(cpu_online_mask); @@ -852,7 +850,7 @@ void mtrr_bp_restore(void) =20 static int __init mtrr_init_finialize(void) { - if (!mtrr_enabled) + if (!mtrr_if) return 0; =20 if (memory_caching_control & CACHE_MTRR) { --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 703A6C433FE for ; Tue, 4 Oct 2022 08:13:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230131AbiJDINC (ORCPT ); Tue, 4 Oct 2022 04:13:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229728AbiJDIL6 (ORCPT ); Tue, 4 Oct 2022 04:11:58 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3567A26FA for ; Tue, 4 Oct 2022 01:11:30 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 3326E1F8DD; Tue, 4 Oct 2022 08:11:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871089; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZzONkjUJmPZz/3+LUsNTypMHrROWbwKy8vJfF8tbKIc=; b=eTmHI6DYRJS0gdQ2DNRdK3aGFm2xivDyF+fejg1I61bBX15V/iv5oQKcrkQQORZyXsplTH fVlRcwMb1zKNnBh90OwXKf6uutRbX9TVA0D6vHITRW3XRgeNIx7wslGzDu0Mtidf1ZaCf+ tgcb4DmCcWuxI/Y87ycvXko/wdQ9fnI= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id EC61F139EF; Tue, 4 Oct 2022 08:11:28 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id r+VoOLDqO2OSSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:28 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 11/16] x86/mtrr: let cache_aps_delayed_init replace mtrr_aps_delayed_init Date: Tue, 4 Oct 2022 10:10:18 +0200 Message-Id: <20221004081023.32402-12-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In order to prepare decoupling MTRR and PAT replace the MTRR specific mtrr_aps_delayed_init flag with a more generic cache_aps_delayed_init one. Signed-off-by: Juergen Gross --- V2: - new patch V4: - reestablish function to set cache_aps_delayed_init (Borislav Petkov) --- arch/x86/include/asm/cacheinfo.h | 3 +++ arch/x86/include/asm/mtrr.h | 2 -- arch/x86/kernel/cpu/cacheinfo.c | 7 +++++++ arch/x86/kernel/cpu/mtrr/mtrr.c | 17 ++++------------- arch/x86/kernel/smpboot.c | 5 +++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index 978bac70fd49..1339bf0908dc 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -7,11 +7,14 @@ extern unsigned int memory_caching_control; #define CACHE_MTRR 0x01 #define CACHE_PAT 0x02 =20 +extern bool cache_aps_delayed_init; + void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); =20 void cache_disable(void); void cache_enable(void); void cache_cpu_init(void); +void set_cache_aps_delayed_init(void); =20 #endif /* _ASM_X86_CACHEINFO_H */ diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 986249a2b9b6..5d31219c8529 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -43,7 +43,6 @@ extern int mtrr_del(int reg, unsigned long base, unsigned= long size); extern int mtrr_del_page(int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); extern void mtrr_ap_init(void); -extern void set_mtrr_aps_delayed_init(void); extern void mtrr_aps_init(void); extern void mtrr_bp_restore(void); extern int mtrr_trim_uncached_memory(unsigned long end_pfn); @@ -87,7 +86,6 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 l= o, u32 hi) { } #define mtrr_ap_init() do {} while (0) -#define set_mtrr_aps_delayed_init() do {} while (0) #define mtrr_aps_init() do {} while (0) #define mtrr_bp_restore() do {} while (0) #define mtrr_disable() do {} while (0) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 49b60a427fc9..330aa412be63 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -1137,3 +1137,10 @@ void cache_cpu_init(void) cache_enable(); local_irq_restore(flags); } + +bool cache_aps_delayed_init; + +void set_cache_aps_delayed_init(void) +{ + cache_aps_delayed_init =3D true; +} diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 7eed5387e828..68376c924b75 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -64,7 +64,6 @@ unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; static DEFINE_MUTEX(mtrr_mutex); =20 u64 size_or_mask, size_and_mask; -static bool mtrr_aps_delayed_init; =20 static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __ro_after_init; =20 @@ -171,7 +170,7 @@ static int mtrr_rendezvous_handler(void *info) if (data->smp_reg !=3D ~0U) { mtrr_if->set(data->smp_reg, data->smp_base, data->smp_size, data->smp_type); - } else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) { + } else if (cache_aps_delayed_init || !cpu_online(smp_processor_id())) { cache_cpu_init(); } return 0; @@ -778,7 +777,7 @@ void __init mtrr_bp_init(void) =20 void mtrr_ap_init(void) { - if (!memory_caching_control || mtrr_aps_delayed_init) + if (!memory_caching_control || cache_aps_delayed_init) return; =20 /* @@ -812,14 +811,6 @@ void mtrr_save_state(void) smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); } =20 -void set_mtrr_aps_delayed_init(void) -{ - if (!memory_caching_control) - return; - - mtrr_aps_delayed_init =3D true; -} - /* * Delayed MTRR initialization for all AP's */ @@ -833,11 +824,11 @@ void mtrr_aps_init(void) * by doing set_mtrr_aps_delayed_init(), prior to this point. If not, * then we are done. */ - if (!mtrr_aps_delayed_init) + if (!cache_aps_delayed_init) return; =20 set_mtrr(~0U, 0, 0, 0); - mtrr_aps_delayed_init =3D false; + cache_aps_delayed_init =3D false; } =20 void mtrr_bp_restore(void) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f24227bc3220..de2082c21e8b 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -58,6 +58,7 @@ #include =20 #include +#include #include #include #include @@ -1428,7 +1429,7 @@ void __init native_smp_prepare_cpus(unsigned int max_= cpus) =20 uv_system_init(); =20 - set_mtrr_aps_delayed_init(); + set_cache_aps_delayed_init(); =20 smp_quirk_init_udelay(); =20 @@ -1439,7 +1440,7 @@ void __init native_smp_prepare_cpus(unsigned int max_= cpus) =20 void arch_thaw_secondary_cpus_begin(void) { - set_mtrr_aps_delayed_init(); + set_cache_aps_delayed_init(); } =20 void arch_thaw_secondary_cpus_end(void) --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71355C433F5 for ; Tue, 4 Oct 2022 08:13:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230001AbiJDINF (ORCPT ); Tue, 4 Oct 2022 04:13:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229754AbiJDIL7 (ORCPT ); Tue, 4 Oct 2022 04:11:59 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDFA81117D; Tue, 4 Oct 2022 01:11:36 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E66CD1F8E6; Tue, 4 Oct 2022 08:11:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871094; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sXtW6VbAsfhLQrd3GTyybS8RtSCDFCFG8eE8+2mhkJQ=; b=tK5+5qWU6QqlanarLETnd9adLzur/RpmLl3bInowlpNXMZUxf9FtBqJ6g7EP/7GOC4L6mw wo3PqkZVCUsruha/5K6wp1US4AjMgakGA94ZpXdGTIQESNnOqJsazw6V/Y9WDAarZss0sY d/6Nqu9Xl4eKs5YBlR89KD7ZM9znPTY= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 9601D139EF; Tue, 4 Oct 2022 08:11:34 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id uzBYI7bqO2OiSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:34 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-pm@vger.kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Rafael J. Wysocki" , Pavel Machek Subject: [PATCH v4 12/16] x86/mtrr: add a stop_machine() handler calling only cache_cpu_init() Date: Tue, 4 Oct 2022 10:10:19 +0200 Message-Id: <20221004081023.32402-13-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Instead of having a stop_machine() handler for either a specific MTRR register or all state at once, add a handler just for calling cache_cpu_init() if appropriate. Add functions for calling stop_machine() with this handler as well. Add a generic replacements for mtrr_bp_restore() and a wrapper for mtrr_bp_init(). Signed-off-by: Juergen Gross --- V2: - completely new replacement of former patch 2 --- arch/x86/include/asm/cacheinfo.h | 7 +-- arch/x86/include/asm/mtrr.h | 4 -- arch/x86/kernel/cpu/cacheinfo.c | 61 +++++++++++++++++++++- arch/x86/kernel/cpu/common.c | 3 +- arch/x86/kernel/cpu/mtrr/mtrr.c | 87 +------------------------------- arch/x86/kernel/setup.c | 3 +- arch/x86/kernel/smpboot.c | 4 +- arch/x86/power/cpu.c | 3 +- 8 files changed, 73 insertions(+), 99 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index 1339bf0908dc..77fe39a11679 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -7,14 +7,15 @@ extern unsigned int memory_caching_control; #define CACHE_MTRR 0x01 #define CACHE_PAT 0x02 =20 -extern bool cache_aps_delayed_init; - void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); =20 void cache_disable(void); void cache_enable(void); -void cache_cpu_init(void); void set_cache_aps_delayed_init(void); +void cache_bp_init(void); +void cache_bp_restore(void); +void cache_ap_init(void); +void cache_aps_init(void); =20 #endif /* _ASM_X86_CACHEINFO_H */ diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 5d31219c8529..ec73d1e5bafb 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -42,8 +42,6 @@ extern int mtrr_add_page(unsigned long base, unsigned lon= g size, extern int mtrr_del(int reg, unsigned long base, unsigned long size); extern int mtrr_del_page(int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); -extern void mtrr_ap_init(void); -extern void mtrr_aps_init(void); extern void mtrr_bp_restore(void); extern int mtrr_trim_uncached_memory(unsigned long end_pfn); extern int amd_special_default_mtrr(void); @@ -85,8 +83,6 @@ static inline int mtrr_trim_uncached_memory(unsigned long= end_pfn) static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) { } -#define mtrr_ap_init() do {} while (0) -#define mtrr_aps_init() do {} while (0) #define mtrr_bp_restore() do {} while (0) #define mtrr_disable() do {} while (0) #define mtrr_enable() do {} while (0) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 330aa412be63..5867325809a6 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include #include @@ -1121,7 +1122,7 @@ void cache_enable(void) __releases(cache_disable_lock) raw_spin_unlock(&cache_disable_lock); } =20 -void cache_cpu_init(void) +static void cache_cpu_init(void) { unsigned long flags; =20 @@ -1138,9 +1139,65 @@ void cache_cpu_init(void) local_irq_restore(flags); } =20 -bool cache_aps_delayed_init; +static bool cache_aps_delayed_init; =20 void set_cache_aps_delayed_init(void) { cache_aps_delayed_init =3D true; } + +static int cache_rendezvous_handler(void *unused) +{ + if (cache_aps_delayed_init || !cpu_online(smp_processor_id())) + cache_cpu_init(); + + return 0; +} + +void __init cache_bp_init(void) +{ + mtrr_bp_init(); + + if (memory_caching_control) + cache_cpu_init(); +} + +void cache_bp_restore(void) +{ + if (memory_caching_control) + cache_cpu_init(); +} + +void cache_ap_init(void) +{ + if (!memory_caching_control || cache_aps_delayed_init) + return; + + /* + * Ideally we should hold mtrr_mutex here to avoid mtrr entries + * changed, but this routine will be called in cpu boot time, + * holding the lock breaks it. + * + * This routine is called in two cases: + * + * 1. very early time of software resume, when there absolutely + * isn't mtrr entry changes; + * + * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug + * lock to prevent mtrr entry changes + */ + stop_machine_from_inactive_cpu(cache_rendezvous_handler, NULL, + cpu_callout_mask); +} + +/* + * Delayed cache initialization for all AP's + */ +void cache_aps_init(void) +{ + if (!memory_caching_control || !cache_aps_delayed_init) + return; + + stop_machine(cache_rendezvous_handler, NULL, cpu_online_mask); + cache_aps_delayed_init =3D false; +} diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3e508f239098..fd058b547f8d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -1948,7 +1949,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_32 enable_sep_cpu(); #endif - mtrr_ap_init(); + cache_ap_init(); validate_apic_and_package_id(c); x86_spec_ctrl_setup_ap(); update_srbds_msr(); diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 68376c924b75..61666931abc4 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -69,9 +69,6 @@ static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __= ro_after_init; =20 const struct mtrr_ops *mtrr_if; =20 -static void set_mtrr(unsigned int reg, unsigned long base, - unsigned long size, mtrr_type type); - void __init set_mtrr_ops(const struct mtrr_ops *ops) { if (ops->vendor && ops->vendor < X86_VENDOR_NUM) @@ -154,25 +151,8 @@ static int mtrr_rendezvous_handler(void *info) { struct set_mtrr_data *data =3D info; =20 - /* - * We use this same function to initialize the mtrrs during boot, - * resume, runtime cpu online and on an explicit request to set a - * specific MTRR. - * - * During boot or suspend, the state of the boot cpu's mtrrs has been - * saved, and we want to replicate that across all the cpus that come - * online (either at the end of boot or resume or during a runtime cpu - * online). If we're doing that, @reg is set to something special and on - * all the cpu's we do cache_cpu_init() (On the logical cpu that - * started the boot/resume sequence, this might be a duplicate - * cache_cpu_init()). - */ - if (data->smp_reg !=3D ~0U) { - mtrr_if->set(data->smp_reg, data->smp_base, - data->smp_size, data->smp_type); - } else if (cache_aps_delayed_init || !cpu_online(smp_processor_id())) { - cache_cpu_init(); - } + mtrr_if->set(data->smp_reg, data->smp_base, + data->smp_size, data->smp_type); return 0; } =20 @@ -242,19 +222,6 @@ static void set_mtrr_cpuslocked(unsigned int reg, unsi= gned long base, stop_machine_cpuslocked(mtrr_rendezvous_handler, &data, cpu_online_mask); } =20 -static void set_mtrr_from_inactive_cpu(unsigned int reg, unsigned long bas= e, - unsigned long size, mtrr_type type) -{ - struct set_mtrr_data data =3D { .smp_reg =3D reg, - .smp_base =3D base, - .smp_size =3D size, - .smp_type =3D type - }; - - stop_machine_from_inactive_cpu(mtrr_rendezvous_handler, &data, - cpu_callout_mask); -} - /** * mtrr_add_page - Add a memory type region * @base: Physical base address of region in pages (in units of 4 kB!) @@ -756,7 +723,6 @@ void __init mtrr_bp_init(void) if (get_mtrr_state()) { memory_caching_control |=3D CACHE_MTRR | CACHE_PAT; changed_by_mtrr_cleanup =3D mtrr_cleanup(phys_addr); - cache_cpu_init(); } else { mtrr_if =3D NULL; } @@ -775,27 +741,6 @@ void __init mtrr_bp_init(void) } } =20 -void mtrr_ap_init(void) -{ - if (!memory_caching_control || cache_aps_delayed_init) - return; - - /* - * Ideally we should hold mtrr_mutex here to avoid mtrr entries - * changed, but this routine will be called in cpu boot time, - * holding the lock breaks it. - * - * This routine is called in two cases: - * - * 1. very early time of software resume, when there absolutely - * isn't mtrr entry changes; - * - * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug - * lock to prevent mtrr entry changes - */ - set_mtrr_from_inactive_cpu(~0U, 0, 0, 0); -} - /** * mtrr_save_state - Save current fixed-range MTRR state of the first * cpu in cpu_online_mask. @@ -811,34 +756,6 @@ void mtrr_save_state(void) smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); } =20 -/* - * Delayed MTRR initialization for all AP's - */ -void mtrr_aps_init(void) -{ - if (!memory_caching_control) - return; - - /* - * Check if someone has requested the delay of AP MTRR initialization, - * by doing set_mtrr_aps_delayed_init(), prior to this point. If not, - * then we are done. - */ - if (!cache_aps_delayed_init) - return; - - set_mtrr(~0U, 0, 0, 0); - cache_aps_delayed_init =3D false; -} - -void mtrr_bp_restore(void) -{ - if (!memory_caching_control) - return; - - cache_cpu_init(); -} - static int __init mtrr_init_finialize(void) { if (!mtrr_if) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 216fee7144ee..e0e185ee0229 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -1075,7 +1076,7 @@ void __init setup_arch(char **cmdline_p) =20 /* update e820 for memory not covered by WB MTRRs */ if (IS_ENABLED(CONFIG_MTRR)) - mtrr_bp_init(); + cache_bp_init(); else pat_disable("PAT support disabled because CONFIG_MTRR is disabled in the= kernel."); =20 diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index de2082c21e8b..fb225a02455f 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1445,7 +1445,7 @@ void arch_thaw_secondary_cpus_begin(void) =20 void arch_thaw_secondary_cpus_end(void) { - mtrr_aps_init(); + cache_aps_init(); } =20 /* @@ -1488,7 +1488,7 @@ void __init native_smp_cpus_done(unsigned int max_cpu= s) =20 nmi_selftest(); impress_friends(); - mtrr_aps_init(); + cache_aps_init(); } =20 static int __initdata setup_possible_cpus =3D -1; diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index bb176c72891c..754221c9a1c3 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -261,7 +262,7 @@ static void notrace __restore_processor_state(struct sa= ved_context *ctxt) do_fpu_end(); tsc_verify_tsc_adjust(true); x86_platform.restore_sched_clock_state(); - mtrr_bp_restore(); + cache_bp_restore(); perf_restore_debug_store(); =20 c =3D &cpu_data(smp_processor_id()); --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E686DC433FE for ; Tue, 4 Oct 2022 08:13:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230156AbiJDINS (ORCPT ); Tue, 4 Oct 2022 04:13:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50102 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229996AbiJDIL7 (ORCPT ); Tue, 4 Oct 2022 04:11:59 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 698441F0 for ; Tue, 4 Oct 2022 01:11:42 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 9A9F4219B0; Tue, 4 Oct 2022 08:11:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871100; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Cfd9GXwMsF2oHrjWI8khgMyNgY9guc85ahmXq4+XzZc=; b=rXkYpHqMUoG5cNNyWPcpg+oX5S/E24G6GuSjnJTJj185dYM/fKCyVPqEveVj9CkDzZpgwN PNunlTN1Ve+Ro7t3IhADWy3Lz5Ze5KwwJ/lAQtw/zMXo9xCk96BYW2IKi9jNzY+PLh3Sv2 bF96XbN4YqBQokPO3F4Wn1qqXNfyJu4= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5442A139EF; Tue, 4 Oct 2022 08:11:40 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id WFJEE7zqO2OySAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:40 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Andy Lutomirski , Peter Zijlstra Subject: [PATCH v4 13/16] x86: decouple pat and mtrr handling Date: Tue, 4 Oct 2022 10:10:20 +0200 Message-Id: <20221004081023.32402-14-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Today PAT is usable only with MTRR being active, with some nasty tweaks to make PAT usable when running as Xen PV guest, which doesn't support MTRR. The reason for this coupling is, that both, PAT MSR changes and MTRR changes, require a similar sequence and so full PAT support was added using the already available MTRR handling. Xen PV PAT handling can work without MTRR, as it just needs to consume the PAT MSR setting done by the hypervisor without the ability and need to change it. This in turn has resulted in a convoluted initialization sequence and wrong decisions regarding cache mode availability due to misguiding PAT availability flags. Fix all of that by allowing to use PAT without MTRR and by reworking the current PAT initialization sequence to match better with the newly introduced generic cache initialization. This removes the need of the recently added pat_force_disabled flag, so remove the remnants of the patch adding it. Signed-off-by: Juergen Gross --- V2: - former patch 3 completely reworked --- arch/x86/include/asm/memtype.h | 5 +- arch/x86/kernel/cpu/cacheinfo.c | 3 +- arch/x86/kernel/cpu/mtrr/mtrr.c | 12 +-- arch/x86/kernel/setup.c | 13 +--- arch/x86/mm/pat/memtype.c | 127 ++++++++++---------------------- 5 files changed, 45 insertions(+), 115 deletions(-) diff --git a/arch/x86/include/asm/memtype.h b/arch/x86/include/asm/memtype.h index 9ca760e430b9..113b2fa51849 100644 --- a/arch/x86/include/asm/memtype.h +++ b/arch/x86/include/asm/memtype.h @@ -6,9 +6,8 @@ #include =20 extern bool pat_enabled(void); -extern void pat_disable(const char *reason); -extern void pat_init(void); -extern void init_cache_modes(void); +extern void pat_bp_init(void); +extern void pat_cpu_init(void); =20 extern int memtype_reserve(u64 start, u64 end, enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm); diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 5867325809a6..40c304314513 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -1133,7 +1133,7 @@ static void cache_cpu_init(void) mtrr_generic_set_state(); =20 if (memory_caching_control & CACHE_PAT) - pat_init(); + pat_cpu_init(); =20 cache_enable(); local_irq_restore(flags); @@ -1157,6 +1157,7 @@ static int cache_rendezvous_handler(void *unused) void __init cache_bp_init(void) { mtrr_bp_init(); + pat_bp_init(); =20 if (memory_caching_control) cache_cpu_init(); diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 61666931abc4..1b652fa768a6 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -721,7 +721,7 @@ void __init mtrr_bp_init(void) if (mtrr_if =3D=3D &generic_mtrr_ops) { /* BIOS may override */ if (get_mtrr_state()) { - memory_caching_control |=3D CACHE_MTRR | CACHE_PAT; + memory_caching_control |=3D CACHE_MTRR; changed_by_mtrr_cleanup =3D mtrr_cleanup(phys_addr); } else { mtrr_if =3D NULL; @@ -729,16 +729,8 @@ void __init mtrr_bp_init(void) } } =20 - if (!mtrr_if) { + if (!mtrr_if) pr_info("Disabled\n"); - - /* - * PAT initialization relies on MTRR's rendezvous handler. - * Skip PAT init until the handler can initialize both - * features independently. - */ - pat_disable("MTRRs disabled, skipping PAT initialization too."); - } } =20 /** diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index e0e185ee0229..aacaa96f0195 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1075,23 +1075,12 @@ void __init setup_arch(char **cmdline_p) max_pfn =3D e820__end_of_ram_pfn(); =20 /* update e820 for memory not covered by WB MTRRs */ - if (IS_ENABLED(CONFIG_MTRR)) - cache_bp_init(); - else - pat_disable("PAT support disabled because CONFIG_MTRR is disabled in the= kernel."); - + cache_bp_init(); if (mtrr_trim_uncached_memory(max_pfn)) max_pfn =3D e820__end_of_ram_pfn(); =20 max_possible_pfn =3D max_pfn; =20 - /* - * This call is required when the CPU does not support PAT. If - * mtrr_bp_init() invoked it already via pat_init() the call has no - * effect. - */ - init_cache_modes(); - /* * Define random base addresses for memory sections after max_pfn is * defined and before each memory section base is used. diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c index 66a209f7eb86..ce1f3246a3e3 100644 --- a/arch/x86/mm/pat/memtype.c +++ b/arch/x86/mm/pat/memtype.c @@ -43,6 +43,7 @@ #include =20 #include +#include #include #include #include @@ -60,41 +61,34 @@ #undef pr_fmt #define pr_fmt(fmt) "" fmt =20 -static bool __read_mostly pat_bp_initialized; static bool __read_mostly pat_disabled =3D !IS_ENABLED(CONFIG_X86_PAT); -static bool __initdata pat_force_disabled =3D !IS_ENABLED(CONFIG_X86_PAT); -static bool __read_mostly pat_bp_enabled; -static bool __read_mostly pat_cm_initialized; +static u64 __read_mostly pat_msr_val; =20 /* * PAT support is enabled by default, but can be disabled for * various user-requested or hardware-forced reasons: */ -void pat_disable(const char *msg_reason) +static void __init pat_disable(const char *msg_reason) { if (pat_disabled) return; =20 - if (pat_bp_initialized) { - WARN_ONCE(1, "x86/PAT: PAT cannot be disabled after initialization\n"); - return; - } - pat_disabled =3D true; pr_info("x86/PAT: %s\n", msg_reason); + + memory_caching_control &=3D ~CACHE_PAT; } =20 static int __init nopat(char *str) { pat_disable("PAT support disabled via boot option."); - pat_force_disabled =3D true; return 0; } early_param("nopat", nopat); =20 bool pat_enabled(void) { - return pat_bp_enabled; + return !pat_disabled; } EXPORT_SYMBOL_GPL(pat_enabled); =20 @@ -192,7 +186,8 @@ enum { =20 #define CM(c) (_PAGE_CACHE_MODE_ ## c) =20 -static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg) +static enum page_cache_mode __init pat_get_cache_mode(unsigned int pat_val, + char *msg) { enum page_cache_mode cache; char *cache_mode; @@ -219,14 +214,12 @@ static enum page_cache_mode pat_get_cache_mode(unsign= ed pat_val, char *msg) * configuration. * Using lower indices is preferred, so we start with highest index. */ -static void __init_cache_modes(u64 pat) +static void __init init_cache_modes(u64 pat) { enum page_cache_mode cache; char pat_msg[33]; int i; =20 - WARN_ON_ONCE(pat_cm_initialized); - pat_msg[32] =3D 0; for (i =3D 7; i >=3D 0; i--) { cache =3D pat_get_cache_mode((pat >> (i * 8)) & 7, @@ -234,34 +227,11 @@ static void __init_cache_modes(u64 pat) update_cache_mode_entry(i, cache); } pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg); - - pat_cm_initialized =3D true; } =20 #define PAT(x, y) ((u64)PAT_ ## y << ((x)*8)) =20 -static void pat_bp_init(u64 pat) -{ - u64 tmp_pat; - - if (!boot_cpu_has(X86_FEATURE_PAT)) { - pat_disable("PAT not supported by the CPU."); - return; - } - - rdmsrl(MSR_IA32_CR_PAT, tmp_pat); - if (!tmp_pat) { - pat_disable("PAT support disabled by the firmware."); - return; - } - - wrmsrl(MSR_IA32_CR_PAT, pat); - pat_bp_enabled =3D true; - - __init_cache_modes(pat); -} - -static void pat_ap_init(u64 pat) +void pat_cpu_init(void) { if (!boot_cpu_has(X86_FEATURE_PAT)) { /* @@ -271,30 +241,35 @@ static void pat_ap_init(u64 pat) panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n"); } =20 - wrmsrl(MSR_IA32_CR_PAT, pat); + wrmsrl(MSR_IA32_CR_PAT, pat_msr_val); } =20 -void __init init_cache_modes(void) +/** + * pat_bp_init - Initialize the PAT MSR value and PAT table + * + * This function initializes PAT MSR value and PAT table with an OS-defined + * value to enable additional cache attributes, WC, WT and WP. + * + * This function prepares the calls of pat_cpu_init() via cache_cpu_init() + * on all cpus. + */ +void __init pat_bp_init(void) { + struct cpuinfo_x86 *c =3D &boot_cpu_data; u64 pat =3D 0; =20 - if (pat_cm_initialized) - return; +#ifndef CONFIG_X86_PAT + pr_info_once("x86/PAT: PAT support disabled because CONFIG_X86_PAT is dis= abled in the kernel.\n"); +#endif =20 - if (boot_cpu_has(X86_FEATURE_PAT)) { - /* - * CPU supports PAT. Set PAT table to be consistent with - * PAT MSR. This case supports "nopat" boot option, and - * virtual machine environments which support PAT without - * MTRRs. In specific, Xen has unique setup to PAT MSR. - * - * If PAT MSR returns 0, it is considered invalid and emulates - * as No PAT. - */ + if (!boot_cpu_has(X86_FEATURE_PAT)) + pat_disable("PAT not supported by the CPU."); + else rdmsrl(MSR_IA32_CR_PAT, pat); - } =20 if (!pat) { + pat_disable("PAT support disabled by the firmware."); + /* * No PAT. Emulate the PAT table that corresponds to the two * cache bits, PWT (Write Through) and PCD (Cache Disable). @@ -315,38 +290,14 @@ void __init init_cache_modes(void) */ pat =3D PAT(0, WB) | PAT(1, WT) | PAT(2, UC_MINUS) | PAT(3, UC) | PAT(4, WB) | PAT(5, WT) | PAT(6, UC_MINUS) | PAT(7, UC); - } else if (!pat_force_disabled && cpu_feature_enabled(X86_FEATURE_HYPERVI= SOR)) { - /* - * Clearly PAT is enabled underneath. Allow pat_enabled() to - * reflect this. - */ - pat_bp_enabled =3D true; } =20 - __init_cache_modes(pat); -} - -/** - * pat_init - Initialize the PAT MSR and PAT table on the current CPU - * - * This function initializes PAT MSR and PAT table with an OS-defined value - * to enable additional cache attributes, WC, WT and WP. - * - * This function must be called on all CPUs using the specific sequence of - * operations defined in Intel SDM. mtrr_rendezvous_handler() provides this - * procedure for PAT. - */ -void pat_init(void) -{ - u64 pat; - struct cpuinfo_x86 *c =3D &boot_cpu_data; - -#ifndef CONFIG_X86_PAT - pr_info_once("x86/PAT: PAT support disabled because CONFIG_X86_PAT is dis= abled in the kernel.\n"); -#endif + /* Xen PV doesn't allow to set PAT MSR, but all cache modes are fine. */ + if (pat_disabled || cpu_feature_enabled(X86_FEATURE_XENPV)) { + init_cache_modes(pat); =20 - if (pat_disabled) return; + } =20 if ((c->x86_vendor =3D=3D X86_VENDOR_INTEL) && (((c->x86 =3D=3D 0x6) && (c->x86_model <=3D 0xd)) || @@ -404,12 +355,10 @@ void pat_init(void) PAT(4, WB) | PAT(5, WP) | PAT(6, UC_MINUS) | PAT(7, WT); } =20 - if (!pat_bp_initialized) { - pat_bp_init(pat); - pat_bp_initialized =3D true; - } else { - pat_ap_init(pat); - } + pat_msr_val =3D pat; + memory_caching_control |=3D CACHE_PAT; + + init_cache_modes(pat); } =20 #undef PAT --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5ED8C4332F for ; Tue, 4 Oct 2022 08:13:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230150AbiJDINM (ORCPT ); Tue, 4 Oct 2022 04:13:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229997AbiJDIL7 (ORCPT ); Tue, 4 Oct 2022 04:11:59 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E21FE65F1 for ; Tue, 4 Oct 2022 01:11:47 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 46BC7219B8; Tue, 4 Oct 2022 08:11:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871106; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uJa/dAa21xOVGetzO/ryAsH/eOO4Um4qAZoEyJh4VLY=; b=Fvn+Y6N82fq4DL9aBZfloJXupWQ/sxaLlU3k4rU43r2FI/bOPlsKrkJEuYuQ8A04kcIIgw lUdTSJ9qdaHceYwG32j2Y8LKRYFkO1r2Y+T1uJfJptZkWBgRKTr7L0wLGqjfRK0wG+GOAE B2ErVBZ8QBT8pFFECt8lT6mp8+Aah78= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 0BB37139EF; Tue, 4 Oct 2022 08:11:46 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id I39wAcLqO2O5SAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:46 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 14/16] x86: switch cache_ap_init() to hotplug callback Date: Tue, 4 Oct 2022 10:10:21 +0200 Message-Id: <20221004081023.32402-15-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Instead of explicitly calling cache_ap_init() in identify_secondary_cpu() use a cpu hotplug callback instead. By registering the callback only after having started the non-boot CPUs and initializing cache_aps_delayed_init with "true", calling set_cache_aps_delayed_init() at boot time can be dropped. It should be noted that this change results in cache_ap_init() being called a little bit later when hotplugging CPUs. By using a new hotplug slot right at the start of the low level bringup this is not problematic, as no operations requiring a specific caching mode are performed that early in CPU initialization. Suggested-by: Borislav Petkov Signed-off-by: Juergen Gross --- V4: - new patch --- arch/x86/include/asm/cacheinfo.h | 1 - arch/x86/kernel/cpu/cacheinfo.c | 18 +++++++++++++++--- arch/x86/kernel/cpu/common.c | 1 - arch/x86/kernel/smpboot.c | 2 -- include/linux/cpuhotplug.h | 1 + 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index 77fe39a11679..f6c521687535 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -15,7 +15,6 @@ void cache_enable(void); void set_cache_aps_delayed_init(void); void cache_bp_init(void); void cache_bp_restore(void); -void cache_ap_init(void); void cache_aps_init(void); =20 #endif /* _ASM_X86_CACHEINFO_H */ diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 40c304314513..48ce48827f87 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -1139,7 +1140,7 @@ static void cache_cpu_init(void) local_irq_restore(flags); } =20 -static bool cache_aps_delayed_init; +static bool cache_aps_delayed_init =3D true; =20 void set_cache_aps_delayed_init(void) { @@ -1169,10 +1170,10 @@ void cache_bp_restore(void) cache_cpu_init(); } =20 -void cache_ap_init(void) +static int cache_ap_init(unsigned int cpu) { if (!memory_caching_control || cache_aps_delayed_init) - return; + return 0; =20 /* * Ideally we should hold mtrr_mutex here to avoid mtrr entries @@ -1189,6 +1190,8 @@ void cache_ap_init(void) */ stop_machine_from_inactive_cpu(cache_rendezvous_handler, NULL, cpu_callout_mask); + + return 0; } =20 /* @@ -1202,3 +1205,12 @@ void cache_aps_init(void) stop_machine(cache_rendezvous_handler, NULL, cpu_online_mask); cache_aps_delayed_init =3D false; } + +static int __init cache_ap_register(void) +{ + cpuhp_setup_state_nocalls(CPUHP_AP_CACHECTRL_STARTING, + "x86/cachectrl:starting", + cache_ap_init, NULL); + return 0; +} +core_initcall(cache_ap_register); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index fd058b547f8d..bf4ac1cb93d7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1949,7 +1949,6 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_32 enable_sep_cpu(); #endif - cache_ap_init(); validate_apic_and_package_id(c); x86_spec_ctrl_setup_ap(); update_srbds_msr(); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index fb225a02455f..d90be0a80560 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1429,8 +1429,6 @@ void __init native_smp_prepare_cpus(unsigned int max_= cpus) =20 uv_system_init(); =20 - set_cache_aps_delayed_init(); - smp_quirk_init_udelay(); =20 speculative_store_bypass_ht_init(); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index f61447913db9..0d277b4b025a 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -140,6 +140,7 @@ enum cpuhp_state { */ CPUHP_AP_IDLE_DEAD, CPUHP_AP_OFFLINE, + CPUHP_AP_CACHECTRL_STARTING, CPUHP_AP_SCHED_STARTING, CPUHP_AP_RCUTREE_DYING, CPUHP_AP_CPU_PM_STARTING, --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0A65C433FE for ; Tue, 4 Oct 2022 08:13:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230157AbiJDINW (ORCPT ); Tue, 4 Oct 2022 04:13:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230035AbiJDIMA (ORCPT ); Tue, 4 Oct 2022 04:12:00 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D01D71D0EE for ; Tue, 4 Oct 2022 01:11:53 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E08E81F8DD; Tue, 4 Oct 2022 08:11:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871111; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=B4UDd4hN7dTQvOXIaEPV/5i9Gpf+GSG8abRcI7GR1DY=; b=PwBP/gYqdXHvj50lqyvLgjcGnDeIuiKOggPBCMVc2y11TkOnProFtSJ8+/H9UHOygWc9C9 H2MixRvfKTmim6aUQ6lme7qPRvqIC6JE2RT0utnp61siN7ZuiKm/MY9oQ3givm6GU626yb HQjT2DjS6attlIZSmnwYGiszmINTbq4= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id A72E7139EF; Tue, 4 Oct 2022 08:11:51 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id s4+XJ8fqO2PDSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:51 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 15/16] x86: do MTRR/PAT setup on all secondary CPUs in parallel Date: Tue, 4 Oct 2022 10:10:22 +0200 Message-Id: <20221004081023.32402-16-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Instead of serializing MTRR/PAT setup on the secondary CPUs in order to avoid clobbering of static variables used by the setup process, put those variables into a structure held on the stack and drop the serialization. This speeds up the start of secondary cpus a little bit (on a small system with 8 CPUs the time needed for starting the secondary CPUs was measured to go down from about 60 milliseconds without this patch to about 55 milliseconds with this patch applied). Signed-off-by: Juergen Gross --- V4: - new patch --- arch/x86/include/asm/cacheinfo.h | 10 ++++++-- arch/x86/include/asm/mtrr.h | 13 +++++----- arch/x86/kernel/cpu/cacheinfo.c | 28 ++++++++------------- arch/x86/kernel/cpu/mtrr/generic.c | 40 ++++++++++++++---------------- 4 files changed, 45 insertions(+), 46 deletions(-) diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cachei= nfo.h index f6c521687535..77ddc04c4975 100644 --- a/arch/x86/include/asm/cacheinfo.h +++ b/arch/x86/include/asm/cacheinfo.h @@ -10,8 +10,14 @@ extern unsigned int memory_caching_control; void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); =20 -void cache_disable(void); -void cache_enable(void); +struct cache_state { + unsigned long cr4; + u32 mtrr_deftype_lo; + u32 mtrr_deftype_hi; +}; + +void cache_disable(struct cache_state *state); +void cache_enable(struct cache_state *state); void set_cache_aps_delayed_init(void); void cache_bp_init(void); void cache_bp_restore(void); diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index ec73d1e5bafb..67c16c813259 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -23,6 +23,7 @@ #ifndef _ASM_X86_MTRR_H #define _ASM_X86_MTRR_H =20 +#include #include =20 void mtrr_bp_init(void); @@ -45,9 +46,9 @@ extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 = hi); extern void mtrr_bp_restore(void); extern int mtrr_trim_uncached_memory(unsigned long end_pfn); extern int amd_special_default_mtrr(void); -void mtrr_disable(void); -void mtrr_enable(void); -void mtrr_generic_set_state(void); +void mtrr_disable(struct cache_state *state); +void mtrr_enable(struct cache_state *state); +void mtrr_generic_set_state(struct cache_state *state); # else static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform) { @@ -84,9 +85,9 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 l= o, u32 hi) { } #define mtrr_bp_restore() do {} while (0) -#define mtrr_disable() do {} while (0) -#define mtrr_enable() do {} while (0) -#define mtrr_generic_set_state() do {} while (0) +#define mtrr_disable(s) do {} while (0) +#define mtrr_enable(s) do {} while (0) +#define mtrr_generic_set_state(s) do {} while (0) # endif =20 #ifdef CONFIG_COMPAT diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinf= o.c index 48ce48827f87..84684b50a5ce 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -1057,10 +1057,7 @@ int populate_cache_leaves(unsigned int cpu) * The caller must ensure that local interrupts are disabled and * are reenabled after cache_enable() has been called. */ -static unsigned long saved_cr4; -static DEFINE_RAW_SPINLOCK(cache_disable_lock); - -void cache_disable(void) __acquires(cache_disable_lock) +void cache_disable(struct cache_state *state) { unsigned long cr0; =20 @@ -1071,8 +1068,6 @@ void cache_disable(void) __acquires(cache_disable_loc= k) * changes to the way the kernel boots */ =20 - raw_spin_lock(&cache_disable_lock); - /* Enter the no-fill (CD=3D1, NW=3D0) cache mode and flush caches. */ cr0 =3D read_cr0() | X86_CR0_CD; write_cr0(cr0); @@ -1088,8 +1083,8 @@ void cache_disable(void) __acquires(cache_disable_loc= k) =20 /* Save value of CR4 and clear Page Global Enable (bit 7) */ if (boot_cpu_has(X86_FEATURE_PGE)) { - saved_cr4 =3D __read_cr4(); - __write_cr4(saved_cr4 & ~X86_CR4_PGE); + state->cr4 =3D __read_cr4(); + __write_cr4(state->cr4 & ~X86_CR4_PGE); } =20 /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ @@ -1097,46 +1092,45 @@ void cache_disable(void) __acquires(cache_disable_l= ock) flush_tlb_local(); =20 if (boot_cpu_has(X86_FEATURE_MTRR)) - mtrr_disable(); + mtrr_disable(state); =20 /* Again, only flush caches if we have to. */ if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) wbinvd(); } =20 -void cache_enable(void) __releases(cache_disable_lock) +void cache_enable(struct cache_state *state) { /* Flush TLBs (no need to flush caches - they are disabled) */ count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); flush_tlb_local(); =20 if (boot_cpu_has(X86_FEATURE_MTRR)) - mtrr_enable(); + mtrr_enable(state); =20 /* Enable caches */ write_cr0(read_cr0() & ~X86_CR0_CD); =20 /* Restore value of CR4 */ if (boot_cpu_has(X86_FEATURE_PGE)) - __write_cr4(saved_cr4); - - raw_spin_unlock(&cache_disable_lock); + __write_cr4(state->cr4); } =20 static void cache_cpu_init(void) { unsigned long flags; + struct cache_state state; =20 local_irq_save(flags); - cache_disable(); + cache_disable(&state); =20 if (memory_caching_control & CACHE_MTRR) - mtrr_generic_set_state(); + mtrr_generic_set_state(&state); =20 if (memory_caching_control & CACHE_PAT) pat_cpu_init(); =20 - cache_enable(); + cache_enable(&state); local_irq_restore(flags); } =20 diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/= generic.c index 2f2485d6657f..cddb440f330d 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -663,18 +663,13 @@ static bool set_mtrr_var_ranges(unsigned int index, s= truct mtrr_var_range *vr) return changed; } =20 -static u32 deftype_lo, deftype_hi; - /** * set_mtrr_state - Set the MTRR state for this CPU. * - * NOTE: The CPU must already be in a safe state for MTRR changes, includi= ng - * measures that only a single CPU can be active in set_mtrr_state()= in - * order to not be subject to races for usage of deftype_lo (this is - * accomplished by taking cache_disable_lock). + * NOTE: The CPU must already be in a safe state for MTRR changes. * RETURNS: 0 if no changes made, else a mask indicating what was changed. */ -static unsigned long set_mtrr_state(void) +static unsigned long set_mtrr_state(struct cache_state *state) { unsigned long change_mask =3D 0; unsigned int i; @@ -691,38 +686,40 @@ static unsigned long set_mtrr_state(void) * Set_mtrr_restore restores the old value of MTRRdefType, * so to set it we fiddle with the saved value: */ - if ((deftype_lo & 0xff) !=3D mtrr_state.def_type - || ((deftype_lo & 0xc00) >> 10) !=3D mtrr_state.enabled) { - - deftype_lo =3D (deftype_lo & ~0xcff) | mtrr_state.def_type | - (mtrr_state.enabled << 10); + if ((state->mtrr_deftype_lo & 0xff) !=3D mtrr_state.def_type + || ((state->mtrr_deftype_lo & 0xc00) >> 10) !=3D mtrr_state.enabled) { + state->mtrr_deftype_lo =3D (state->mtrr_deftype_lo & ~0xcff) | + mtrr_state.def_type | + (mtrr_state.enabled << 10); change_mask |=3D MTRR_CHANGE_MASK_DEFTYPE; } =20 return change_mask; } =20 -void mtrr_disable(void) +void mtrr_disable(struct cache_state *state) { /* Save MTRR state */ - rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); + rdmsr(MSR_MTRRdefType, state->mtrr_deftype_lo, state->mtrr_deftype_hi); =20 /* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); + mtrr_wrmsr(MSR_MTRRdefType, state->mtrr_deftype_lo & ~0xcff, + state->mtrr_deftype_hi); } =20 -void mtrr_enable(void) +void mtrr_enable(struct cache_state *state) { /* Intel (P6) standard MTRRs */ - mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); + mtrr_wrmsr(MSR_MTRRdefType, state->mtrr_deftype_lo, + state->mtrr_deftype_hi); } =20 -void mtrr_generic_set_state(void) +void mtrr_generic_set_state(struct cache_state *state) { unsigned long mask, count; =20 /* Actually set the state */ - mask =3D set_mtrr_state(); + mask =3D set_mtrr_state(state); =20 /* Use the atomic bitops to update the global mask */ for (count =3D 0; count < sizeof(mask) * 8; ++count) { @@ -747,11 +744,12 @@ static void generic_set_mtrr(unsigned int reg, unsign= ed long base, { unsigned long flags; struct mtrr_var_range *vr; + struct cache_state state; =20 vr =3D &mtrr_state.var_ranges[reg]; =20 local_irq_save(flags); - cache_disable(); + cache_disable(&state); =20 if (size =3D=3D 0) { /* @@ -770,7 +768,7 @@ static void generic_set_mtrr(unsigned int reg, unsigned= long base, mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi); } =20 - cache_enable(); + cache_enable(&state); local_irq_restore(flags); } =20 --=20 2.35.3 From nobody Mon Apr 6 09:46:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03175C433F5 for ; Tue, 4 Oct 2022 08:13:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230163AbiJDIN0 (ORCPT ); Tue, 4 Oct 2022 04:13:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230012AbiJDIMB (ORCPT ); Tue, 4 Oct 2022 04:12:01 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC853101EE for ; Tue, 4 Oct 2022 01:11:58 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 8BA4B1F8E6; Tue, 4 Oct 2022 08:11:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1664871117; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BjjZMZb/A25GCQ+scz6LJmjfKGXZEm1tcVtvdvPahA8=; b=QQf9f+Wpo7w3nbV14ErV3b0nJfDxn8vnr6mO93NEsQ+kDVOki/NZ5Et//N9gxbXaDvMiv0 2a0ScoJj+R+AH5V+ln2QEO7BOgy7ixz6G5hx+973MP0VPwBVaHL6Vi0IsO966g/tnwIAO8 MEDVVVP5uC0KS2srj0tXfAwiWOTHHsc= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 4F006139EF; Tue, 4 Oct 2022 08:11:57 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 9koDEs3qO2PPSAAAMHmgww (envelope-from ); Tue, 04 Oct 2022 08:11:57 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v4 16/16] x86/mtrr: simplify mtrr_ops initialization Date: Tue, 4 Oct 2022 10:10:23 +0200 Message-Id: <20221004081023.32402-17-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221004081023.32402-1-jgross@suse.com> References: <20221004081023.32402-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The way mtrr_if is initialized with the correct mtrr_ops structure is quite weird. Simplify that by dropping the vendor specific init functions and the mtrr_ops[] array. Replace those with direct assignments of the related vendor specific ops array to mtrr_if. Signed-off-by: Juergen Gross --- V4: - new patch --- arch/x86/kernel/cpu/mtrr/amd.c | 8 +------- arch/x86/kernel/cpu/mtrr/centaur.c | 8 +------- arch/x86/kernel/cpu/mtrr/cyrix.c | 8 +------- arch/x86/kernel/cpu/mtrr/mtrr.c | 30 +++--------------------------- arch/x86/kernel/cpu/mtrr/mtrr.h | 15 +++++++++------ 5 files changed, 15 insertions(+), 54 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c index a65a0272096d..eff6ac62c0ff 100644 --- a/arch/x86/kernel/cpu/mtrr/amd.c +++ b/arch/x86/kernel/cpu/mtrr/amd.c @@ -109,7 +109,7 @@ amd_validate_add_page(unsigned long base, unsigned long= size, unsigned int type) return 0; } =20 -static const struct mtrr_ops amd_mtrr_ops =3D { +const struct mtrr_ops amd_mtrr_ops =3D { .vendor =3D X86_VENDOR_AMD, .set =3D amd_set_mtrr, .get =3D amd_get_mtrr, @@ -117,9 +117,3 @@ static const struct mtrr_ops amd_mtrr_ops =3D { .validate_add_page =3D amd_validate_add_page, .have_wrcomb =3D positive_have_wrcomb, }; - -int __init amd_init_mtrr(void) -{ - set_mtrr_ops(&amd_mtrr_ops); - return 0; -} diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/= centaur.c index f27177816569..b8a74eddde83 100644 --- a/arch/x86/kernel/cpu/mtrr/centaur.c +++ b/arch/x86/kernel/cpu/mtrr/centaur.c @@ -111,7 +111,7 @@ centaur_validate_add_page(unsigned long base, unsigned = long size, unsigned int t return 0; } =20 -static const struct mtrr_ops centaur_mtrr_ops =3D { +const struct mtrr_ops centaur_mtrr_ops =3D { .vendor =3D X86_VENDOR_CENTAUR, .set =3D centaur_set_mcr, .get =3D centaur_get_mcr, @@ -119,9 +119,3 @@ static const struct mtrr_ops centaur_mtrr_ops =3D { .validate_add_page =3D centaur_validate_add_page, .have_wrcomb =3D positive_have_wrcomb, }; - -int __init centaur_init_mtrr(void) -{ - set_mtrr_ops(¢aur_mtrr_ops); - return 0; -} diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cy= rix.c index c77d3b0a5bf2..173b9e01e623 100644 --- a/arch/x86/kernel/cpu/mtrr/cyrix.c +++ b/arch/x86/kernel/cpu/mtrr/cyrix.c @@ -234,7 +234,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned lo= ng base, post_set(); } =20 -static const struct mtrr_ops cyrix_mtrr_ops =3D { +const struct mtrr_ops cyrix_mtrr_ops =3D { .vendor =3D X86_VENDOR_CYRIX, .set =3D cyrix_set_arr, .get =3D cyrix_get_arr, @@ -242,9 +242,3 @@ static const struct mtrr_ops cyrix_mtrr_ops =3D { .validate_add_page =3D generic_validate_add_page, .have_wrcomb =3D positive_have_wrcomb, }; - -int __init cyrix_init_mtrr(void) -{ - set_mtrr_ops(&cyrix_mtrr_ops); - return 0; -} diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtr= r.c index 1b652fa768a6..7ba68356c0ff 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -65,16 +65,8 @@ static DEFINE_MUTEX(mtrr_mutex); =20 u64 size_or_mask, size_and_mask; =20 -static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __ro_after_init; - const struct mtrr_ops *mtrr_if; =20 -void __init set_mtrr_ops(const struct mtrr_ops *ops) -{ - if (ops->vendor && ops->vendor < X86_VENDOR_NUM) - mtrr_ops[ops->vendor] =3D ops; -} - /* Returns non-zero if we have the write-combining memory type */ static int have_wrcomb(void) { @@ -578,20 +570,6 @@ int arch_phys_wc_index(int handle) } EXPORT_SYMBOL_GPL(arch_phys_wc_index); =20 -/* - * HACK ALERT! - * These should be called implicitly, but we can't yet until all the initc= all - * stuff is done... - */ -static void __init init_ifs(void) -{ -#ifndef CONFIG_X86_64 - amd_init_mtrr(); - cyrix_init_mtrr(); - centaur_init_mtrr(); -#endif -} - /* The suspend/resume methods are only for CPU without MTRR. CPU using gen= eric * MTRR driver doesn't require this */ @@ -649,8 +627,6 @@ void __init mtrr_bp_init(void) { u32 phys_addr; =20 - init_ifs(); - phys_addr =3D 32; =20 if (boot_cpu_has(X86_FEATURE_MTRR)) { @@ -691,21 +667,21 @@ void __init mtrr_bp_init(void) case X86_VENDOR_AMD: if (cpu_feature_enabled(X86_FEATURE_K6_MTRR)) { /* Pre-Athlon (K6) AMD CPU MTRRs */ - mtrr_if =3D mtrr_ops[X86_VENDOR_AMD]; + mtrr_if =3D vendor_mtrr_ops(amd_mtrr_ops); size_or_mask =3D SIZE_OR_MASK_BITS(32); size_and_mask =3D 0; } break; case X86_VENDOR_CENTAUR: if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR)) { - mtrr_if =3D mtrr_ops[X86_VENDOR_CENTAUR]; + mtrr_if =3D vendor_mtrr_ops(centaur_mtrr_ops); size_or_mask =3D SIZE_OR_MASK_BITS(32); size_and_mask =3D 0; } break; case X86_VENDOR_CYRIX: if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR)) { - mtrr_if =3D mtrr_ops[X86_VENDOR_CYRIX]; + mtrr_if =3D vendor_mtrr_ops(cyrix_mtrr_ops); size_or_mask =3D SIZE_OR_MASK_BITS(32); size_and_mask =3D 0; } diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtr= r.h index c98928ceee6a..7a7387356192 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -51,8 +51,6 @@ void fill_mtrr_var_range(unsigned int index, u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); bool get_mtrr_state(void); =20 -extern void __init set_mtrr_ops(const struct mtrr_ops *ops); - extern u64 size_or_mask, size_and_mask; extern const struct mtrr_ops *mtrr_if; =20 @@ -66,10 +64,15 @@ void mtrr_state_warn(void); const char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); =20 -/* CPU specific mtrr init functions */ -int amd_init_mtrr(void); -int cyrix_init_mtrr(void); -int centaur_init_mtrr(void); +/* CPU specific mtrr_ops vectors. */ +extern const struct mtrr_ops amd_mtrr_ops; +extern const struct mtrr_ops cyrix_mtrr_ops; +extern const struct mtrr_ops centaur_mtrr_ops; +#ifdef CONFIG_X86_64 +#define vendor_mtrr_ops(x) NULL +#else +#define vendor_mtrr_ops(x) &(x) +#endif =20 extern int changed_by_mtrr_cleanup; extern int mtrr_cleanup(unsigned address_bits); --=20 2.35.3