From patchwork Thu Feb 9 07:22:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Juergen Gross X-Patchwork-Id: 54775 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp186547wrn; Wed, 8 Feb 2023 23:23:50 -0800 (PST) X-Google-Smtp-Source: AK7set+m+6MloGpmP8UMxZ8Pxi52tubsi/oVciY4G+UeOV/K8sQ2b2VIUhVSXBgDdJLmU3JdvAGw X-Received: by 2002:a17:906:cb92:b0:889:5ca0:146e with SMTP id mf18-20020a170906cb9200b008895ca0146emr10308364ejb.16.1675927430292; Wed, 08 Feb 2023 23:23:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675927430; cv=none; d=google.com; s=arc-20160816; b=Yi7hlM4jeJwbraYCPT0ZV/BUyyuVWAY94XAAIV/iN4FcZnBuZKRSEKv+WXTkqbBigo 42PozANr5JCS23VIaFYf/I6RabtO1pz9cgT1VMevXEHmV/fi+AwuD2z+4bgKQFmG2moU 3wuwWe7TE/d6eEMQFFmd23twO8Vb/AqyJ4fy7lyjhj+y1/Azi+vSyQx9F0ljQrAWYd4h K1Cos5pNdTqvKMO9mEGPRhbu6smtmZhzGB3gH06j63sdxgPJxwriPaZU1gPc1u1aV2WG Jtxz2Lfhx2WO/VBwmgXJctu8AZUszXZh07PhDhNzTESS6CgvttQk5MVXYafECox4BPUZ vqZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6KlzZtRVU/BktL0oxuQOwlCZm+eOW7c+Ihxdj/RddRU=; b=qFb8akTPkMYgQR2fdMgfvKpIva4lrXojAyEquug2Z9gl2Bl39hd3sX9C+gKxJJn+zK X1jbGyCKXUGu+ap9Gj0XR/9x9yV8GqHtlnadXPJJFFt+JHLQa3wrchfmDLkMjwM0nGOI y1HwjnI/eHAhsyA3a7q0NMcrZzxNtSS6OwCswVKtUvTJyWdrq9Tjo3jLBKGvbLXWxw53 rk+QCGzTZOW5NLAbKPp0WwAswnE3YzycsYwdLVxJ5l2+GEnef3D5XSBPdho6d1rzrTzC scFGjuAbBiHfUG8QnkrFWdLP0Uc3AgIGDUkOzssN44q/BKa7mG/CpPE/tegikZzvq7+g Ob7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b=SghSS7Pt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=suse.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id fd24-20020a1709072a1800b008911a333905si1445299ejc.11.2023.02.08.23.23.27; Wed, 08 Feb 2023 23:23:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b=SghSS7Pt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=suse.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229853AbjBIHXL (ORCPT + 99 others); Thu, 9 Feb 2023 02:23:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229672AbjBIHXF (ORCPT ); Thu, 9 Feb 2023 02:23:05 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5AB31C59E for ; Wed, 8 Feb 2023 23:22:35 -0800 (PST) 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 A942F34DB4; Thu, 9 Feb 2023 07:22:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1675927354; 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=6KlzZtRVU/BktL0oxuQOwlCZm+eOW7c+Ihxdj/RddRU=; b=SghSS7PtDhKUO4VPKdXdgTYUXvRc6OBO3BazFVVGVDSKJq1l9SDT4wz6p9G9ynon3ndyEI UetnZPhGah5APTgvI58VZrC1vMRgjtivd3NkzGtzqDzXMtLOF+mwAYOpTh4b9s22cC8Fka YnfIYXeaPFKaGefmU0jzkBfIdtmECHk= 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 5CC2D1339E; Thu, 9 Feb 2023 07:22:34 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id SPNcFTqf5GPzeAAAMHmgww (envelope-from ); Thu, 09 Feb 2023 07:22:34 +0000 From: Juergen Gross To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: lists@nerdbynature.de, mikelley@microsoft.com, torvalds@linux-foundation.org, Juergen Gross , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" Subject: [PATCH v2 2/8] x86/mtrr: support setting MTRR state for software defined MTRRs Date: Thu, 9 Feb 2023 08:22:14 +0100 Message-Id: <20230209072220.6836-3-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230209072220.6836-1-jgross@suse.com> References: <20230209072220.6836-1-jgross@suse.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757337281287459748?= X-GMAIL-MSGID: =?utf-8?q?1757337281287459748?= When running virtualized, MTRR access can be reduced (e.g. in Xen PV guests or when running as a SEV-SNP guest under Hyper-V). Typically the hypervisor will reset the MTRR feature in cpuid data, resulting in no MTRR memory type information being available for the kernel. This has turned out to result in problems: - Hyper-V SEV-SNP guests using uncached mappings where they shouldn't - Xen PV dom0 mapping memory as WB which should be UC- instead Solve those problems by supporting to set a fixed MTRR state, overwriting the empty state used today. In case such a state has been set, don't call get_mtrr_state() in mtrr_bp_init(). The set state will only be used by mtrr_type_lookup(), as in all other cases mtrr_enabled() is being checked, which will return false. Accept the overwrite call only in case of MTRRs being disabled in cpuid. Signed-off-by: Juergen Gross --- V2: - new patch --- arch/x86/include/asm/mtrr.h | 2 ++ arch/x86/kernel/cpu/mtrr/generic.c | 38 ++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/mtrr/mtrr.c | 9 +++++++ 3 files changed, 49 insertions(+) diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index f0eeaf6e5f5f..0b8f51d683dc 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -31,6 +31,8 @@ */ # ifdef CONFIG_MTRR void mtrr_bp_init(void); +void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, + mtrr_type *fixed, mtrr_type def_type); extern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform); extern void mtrr_save_fixed_ranges(void *); extern void mtrr_save_state(void); diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index ee09d359e08f..788bc16888a5 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -240,6 +240,44 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, return mtrr_state.def_type; } +/** + * mtrr_overwrite_state - set fixed MTRR state + * + * Used to set MTRR state via different means (e.g. with data obtained from + * a hypervisor). + */ +void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, + mtrr_type *fixed, mtrr_type def_type) +{ + unsigned int i; + + if (boot_cpu_has(X86_FEATURE_MTRR)) + return; + + if (var) { + if (num_var > MTRR_MAX_VAR_RANGES) { + pr_warn("Trying to overwrite MTRR state with %u variable entries\n", + num_var); + num_var = MTRR_MAX_VAR_RANGES; + } + for (i = 0; i < num_var; i++) + mtrr_state.var_ranges[i] = var[i]; + num_var_ranges = num_var; + } + + if (fixed) { + for (i = 0; i < MTRR_NUM_FIXED_RANGES; i++) + mtrr_state.fixed_ranges[i] = fixed[i]; + mtrr_state.enabled |= MTRR_STATE_MTRR_FIXED_ENABLED; + mtrr_state.have_fixed = 1; + } + + mtrr_state.def_type = def_type; + mtrr_state.enabled |= MTRR_STATE_MTRR_ENABLED; + + mtrr_state_set = 1; +} + /** * mtrr_type_lookup - look up memory type in MTRR * diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c index 542ca5639dfd..b73fe243c7fd 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -668,6 +668,15 @@ void __init mtrr_bp_init(void) const char *why = "(not available)"; unsigned int phys_addr; + if (mtrr_state.enabled) { + /* Software overwrite of MTRR state, only for generic case. */ + mtrr_calc_physbits(true); + init_table(); + pr_info("MTRRs set to read-only\n"); + + return; + } + phys_addr = mtrr_calc_physbits(boot_cpu_has(X86_FEATURE_MTRR)); if (boot_cpu_has(X86_FEATURE_MTRR)) {