linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: X86 ML <x86@kernel.org>
Cc: Tom Lendacky <thomas.lendacky@amd.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Eric Morton <Eric.Morton@amd.com>
Subject: [PATCH 3/3] x86/msr: Add an MSR write callback
Date: Wed, 10 Jun 2020 13:00:37 +0200	[thread overview]
Message-ID: <20200610110037.11853-4-bp@alien8.de> (raw)
In-Reply-To: <20200610110037.11853-1-bp@alien8.de>

From: Borislav Petkov <bp@suse.de>

Add a callback which gets executed after a MSR is written from
userspace. This is needed because in the case of AMD's MSR_AMD64_LS_CFG
MSR which gets cached in the kernel, the cached value needs to be
updated after the write, otherwise latter doesn't stick.

Reported-by: Eric Morton <Eric.Morton@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/msr.h   |  2 ++
 arch/x86/kernel/cpu/bugs.c   |  2 +-
 arch/x86/kernel/cpu/common.c | 31 +++++++++++++++++++++++++++++++
 arch/x86/kernel/msr.c        |  3 +++
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 71393a4c2104..d151eb8cbd51 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -335,6 +335,8 @@ void msrs_free(struct msr *msrs);
 int msr_set_bit(u32 msr, u8 bit);
 int msr_clear_bit(u32 msr, u8 bit);
 
+void msr_write_callback(int cpu, u32 reg, u32 low, u32 hi);
+
 #ifdef CONFIG_SMP
 int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
 int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index ed54b3b21c39..bfaf303d6965 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -57,7 +57,7 @@ static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS;
  * AMD specific MSR info for Speculative Store Bypass control.
  * x86_amd_ls_cfg_ssbd_mask is initialized in identify_boot_cpu().
  */
-u64 __ro_after_init x86_amd_ls_cfg_base;
+u64 x86_amd_ls_cfg_base;
 u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask;
 
 /* Control conditional STIBP in switch_to() */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index bed0cb83fe24..8d6fa73940a3 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -55,6 +55,7 @@
 #include <asm/microcode_intel.h>
 #include <asm/intel-family.h>
 #include <asm/cpu_device_id.h>
+#include <asm/spec-ctrl.h>
 #include <asm/uv/uv.h>
 
 #include "cpu.h"
@@ -1960,3 +1961,33 @@ void arch_smt_update(void)
 	/* Check whether IPI broadcasting can be enabled */
 	apic_smt_update();
 }
+
+void msr_write_callback(int cpu, u32 reg, u32 lo, u32 hi)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+		return;
+
+	if (reg == MSR_AMD64_LS_CFG) {
+		u64 new = ((u64)hi << 32) | lo;
+		cpumask_var_t tmp_mask;
+
+		if (new == x86_amd_ls_cfg_base)
+			return;
+
+		if (WARN_ON_ONCE(!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)))
+			return;
+
+		/*
+		 * Remove the @cpu it was just written to from the mask
+		 * so that it doesn't get written to again pointlessly.
+		 */
+		cpumask_xor(tmp_mask, cpu_online_mask, cpumask_of(cpu));
+
+		x86_amd_ls_cfg_base = new;
+
+		wrmsrl_val_on_cpus(tmp_mask, MSR_AMD64_LS_CFG, new);
+
+		free_cpumask_var(tmp_mask);
+	}
+}
+EXPORT_SYMBOL_GPL(msr_write_callback);
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 1547be359d7f..167125088eda 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -95,6 +95,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
 		err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
 		if (err)
 			break;
+
+		msr_write_callback(cpu, reg, data[0], data[1]);
+
 		tmp += 2;
 		bytes += 8;
 	}
-- 
2.21.0


  parent reply	other threads:[~2020-06-10 11:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-10 11:00 [PATCH 0/3] x86/MSR: Add a MSR write callback Borislav Petkov
2020-06-10 11:00 ` [PATCH 1/3] x86/msr: Pass a single MSR value to __rwmsr_on_cpus() too Borislav Petkov
2020-06-10 11:00 ` [PATCH 2/3] x86/msr: Add wrmsrl_val_on_cpus() Borislav Petkov
2020-06-10 11:00 ` Borislav Petkov [this message]
2020-06-10 12:32   ` [PATCH 3/3] x86/msr: Add an MSR write callback Peter Zijlstra
2020-06-10 13:21     ` Borislav Petkov
2020-06-10 14:01       ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200610110037.11853-4-bp@alien8.de \
    --to=bp@alien8.de \
    --cc=Eric.Morton@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).