git: 74d325fee2db - main - amd64: cache MSR_MEMORY_CTL in pcpu

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 22 Sep 2026 15:41:52 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=74d325fee2dbcb5f8541819481ce76f87c151a21

commit 74d325fee2dbcb5f8541819481ce76f87c151a21
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-09-19 07:43:34 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-22 15:40:41 +0000

    amd64: cache MSR_MEMORY_CTL in pcpu
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D59815
---
 sys/amd64/amd64/initcpu.c    | 11 +++++++++++
 sys/amd64/amd64/machdep.c    |  7 +++----
 sys/amd64/amd64/mp_machdep.c |  2 ++
 sys/amd64/include/md_var.h   |  1 +
 sys/amd64/include/pcpu.h     |  3 ++-
 5 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 4ae79693addf..2d2f5835e3b3 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -458,3 +458,14 @@ amd64_init_splitlock(void)
 		ia32_splitlock_force = 0;
 	}
 }
+
+void
+amd64_cpu_init_msr_memctl(void)
+{
+	uint64_t msr;
+
+	if ((cpu_stdext_feature3 & CPUID_STDEXT3_CORE_CAP) != 0 &&
+	    rdmsr_safe(MSR_IA32_CORE_CAP, &msr) == 0 &&
+	    (msr & IA32_CORE_CAP_SPLITLOCK) != 0)
+		PCPU_SET(msr_memctl, rdmsr(MSR_MEMORY_CTL));
+}
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index b10c58955ce0..a1b2d116295f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1658,6 +1658,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 	thread0.td_pcb->pcb_flags = 0;
 
 	amd64_init_splitlock();
+	amd64_cpu_init_msr_memctl();
 
         env = kern_getenv("kernelname");
 	if (env != NULL)
@@ -1932,8 +1933,7 @@ void
 enable_splitlock_ac(void)
 {
 	MPASS(ia32_splitlock);
-	wrmsr(MSR_MEMORY_CTL, rdmsr(MSR_MEMORY_CTL) |
-	    MSR_MEMORY_CTL_SPLITLOCK);
+	wrmsr(MSR_MEMORY_CTL, PCPU_GET(msr_memctl) | MSR_MEMORY_CTL_SPLITLOCK);
 }
 
 void
@@ -1950,8 +1950,7 @@ void
 disable_splitlock_ac(void)
 {
 	MPASS(ia32_splitlock);
-	wrmsr(MSR_MEMORY_CTL, rdmsr(MSR_MEMORY_CTL) &
-	    ~MSR_MEMORY_CTL_SPLITLOCK);
+	wrmsr(MSR_MEMORY_CTL, PCPU_GET(msr_memctl) & ~MSR_MEMORY_CTL_SPLITLOCK);
 }
 
 void
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 63e0180baeee..1b211026e386 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -309,6 +309,8 @@ init_secondary(void)
 	else
 		lidt(&r_idt);
 
+	amd64_cpu_init_msr_memctl();
+
 	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
 	ltr(gsel_tss);
 
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index b85e442e559a..2eec4fde80a6 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -68,6 +68,7 @@ struct trapframe;
 
 void	amd64_conf_fast_syscall(void);
 void	amd64_cpu_init_fred(void);
+void	amd64_cpu_init_msr_memctl(void);
 void	amd64_db_resume_dbreg(void);
 void	amd64_init_splitlock(void);
 vm_paddr_t amd64_loadaddr(void);
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index 213790d245dc..6a91122eb2ec 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -101,7 +101,8 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
 	u_int	pc_small_core;						\
 	u_int	pc_pcid_invlpg_workaround;				\
 	struct pmap_pcid pc_kpmap_store;				\
-	char	__pad[2900]		/* pad to UMA_PCPU_ALLOC_SIZE */
+	uint64_t pc_msr_memctl;						\
+	char	__pad[2892]		/* pad to UMA_PCPU_ALLOC_SIZE */
 
 #define	PC_DBREG_CMD_NONE	0
 #define	PC_DBREG_CMD_LOAD	1