Skip to content

Commit 3ef3ace

Browse files
committed
Merge tag 'x86_cpu_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cpu updates from Borislav Petkov: - Split MTRR and PAT init code to accomodate at least Xen PV and TDX guests which do not get MTRRs exposed but only PAT. (TDX guests do not support the cache disabling dance when setting up MTRRs so they fall under the same category) This is a cleanup work to remove all the ugly workarounds for such guests and init things separately (Juergen Gross) - Add two new Intel CPUs to the list of CPUs with "normal" Energy Performance Bias, leading to power savings - Do not do bus master arbitration in C3 (ARB_DISABLE) on modern Centaur CPUs * tag 'x86_cpu_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) x86/mtrr: Make message for disabled MTRRs more descriptive x86/pat: Handle TDX guest PAT initialization x86/cpuid: Carve out all CPUID functionality x86/cpu: Switch to cpu_feature_enabled() for X86_FEATURE_XENPV x86/cpu: Remove X86_FEATURE_XENPV usage in setup_cpu_entry_area() x86/cpu: Drop 32-bit Xen PV guest code in update_task_stack() x86/cpu: Remove unneeded 64-bit dependency in arch_enter_from_user_mode() x86/cpufeatures: Add X86_FEATURE_XENPV to disabled-features.h x86/acpi/cstate: Optimize ARB_DISABLE on Centaur CPUs x86/mtrr: Simplify mtrr_ops initialization x86/cacheinfo: Switch cache_ap_init() to hotplug callback x86: Decouple PAT and MTRR handling x86/mtrr: Add a stop_machine() handler calling only cache_cpu_init() x86/mtrr: Let cache_aps_delayed_init replace mtrr_aps_delayed_init x86/mtrr: Get rid of __mtrr_enabled bool x86/mtrr: Simplify mtrr_bp_init() x86/mtrr: Remove set_all callback from struct mtrr_ops x86/mtrr: Disentangle MTRR init from PAT init x86/mtrr: Move cache control code to cacheinfo.c x86/mtrr: Split MTRR-specific handling from cache dis/enabling ...
2 parents 4eb77fa + 7882b69 commit 3ef3ace

30 files changed

+538
-662
lines changed

arch/x86/include/asm/cacheinfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@
22
#ifndef _ASM_X86_CACHEINFO_H
33
#define _ASM_X86_CACHEINFO_H
44

5+
/* Kernel controls MTRR and/or PAT MSRs. */
6+
extern unsigned int memory_caching_control;
7+
#define CACHE_MTRR 0x01
8+
#define CACHE_PAT 0x02
9+
510
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu);
611
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu);
712

13+
void cache_disable(void);
14+
void cache_enable(void);
15+
void set_cache_aps_delayed_init(bool val);
16+
bool get_cache_aps_delayed_init(void);
17+
void cache_bp_init(void);
18+
void cache_bp_restore(void);
19+
void cache_aps_init(void);
20+
821
#endif /* _ASM_X86_CACHEINFO_H */

arch/x86/include/asm/cpuid.h

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,132 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/*
33
* CPUID-related helpers/definitions
4-
*
5-
* Derived from arch/x86/kvm/cpuid.c
64
*/
75

86
#ifndef _ASM_X86_CPUID_H
97
#define _ASM_X86_CPUID_H
108

9+
#include <asm/string.h>
10+
11+
struct cpuid_regs {
12+
u32 eax, ebx, ecx, edx;
13+
};
14+
15+
enum cpuid_regs_idx {
16+
CPUID_EAX = 0,
17+
CPUID_EBX,
18+
CPUID_ECX,
19+
CPUID_EDX,
20+
};
21+
22+
#ifdef CONFIG_X86_32
23+
extern int have_cpuid_p(void);
24+
#else
25+
static inline int have_cpuid_p(void)
26+
{
27+
return 1;
28+
}
29+
#endif
30+
static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
31+
unsigned int *ecx, unsigned int *edx)
32+
{
33+
/* ecx is often an input as well as an output. */
34+
asm volatile("cpuid"
35+
: "=a" (*eax),
36+
"=b" (*ebx),
37+
"=c" (*ecx),
38+
"=d" (*edx)
39+
: "0" (*eax), "2" (*ecx)
40+
: "memory");
41+
}
42+
43+
#define native_cpuid_reg(reg) \
44+
static inline unsigned int native_cpuid_##reg(unsigned int op) \
45+
{ \
46+
unsigned int eax = op, ebx, ecx = 0, edx; \
47+
\
48+
native_cpuid(&eax, &ebx, &ecx, &edx); \
49+
\
50+
return reg; \
51+
}
52+
53+
/*
54+
* Native CPUID functions returning a single datum.
55+
*/
56+
native_cpuid_reg(eax)
57+
native_cpuid_reg(ebx)
58+
native_cpuid_reg(ecx)
59+
native_cpuid_reg(edx)
60+
61+
#ifdef CONFIG_PARAVIRT_XXL
62+
#include <asm/paravirt.h>
63+
#else
64+
#define __cpuid native_cpuid
65+
#endif
66+
67+
/*
68+
* Generic CPUID function
69+
* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
70+
* resulting in stale register contents being returned.
71+
*/
72+
static inline void cpuid(unsigned int op,
73+
unsigned int *eax, unsigned int *ebx,
74+
unsigned int *ecx, unsigned int *edx)
75+
{
76+
*eax = op;
77+
*ecx = 0;
78+
__cpuid(eax, ebx, ecx, edx);
79+
}
80+
81+
/* Some CPUID calls want 'count' to be placed in ecx */
82+
static inline void cpuid_count(unsigned int op, int count,
83+
unsigned int *eax, unsigned int *ebx,
84+
unsigned int *ecx, unsigned int *edx)
85+
{
86+
*eax = op;
87+
*ecx = count;
88+
__cpuid(eax, ebx, ecx, edx);
89+
}
90+
91+
/*
92+
* CPUID functions returning a single datum
93+
*/
94+
static inline unsigned int cpuid_eax(unsigned int op)
95+
{
96+
unsigned int eax, ebx, ecx, edx;
97+
98+
cpuid(op, &eax, &ebx, &ecx, &edx);
99+
100+
return eax;
101+
}
102+
103+
static inline unsigned int cpuid_ebx(unsigned int op)
104+
{
105+
unsigned int eax, ebx, ecx, edx;
106+
107+
cpuid(op, &eax, &ebx, &ecx, &edx);
108+
109+
return ebx;
110+
}
111+
112+
static inline unsigned int cpuid_ecx(unsigned int op)
113+
{
114+
unsigned int eax, ebx, ecx, edx;
115+
116+
cpuid(op, &eax, &ebx, &ecx, &edx);
117+
118+
return ecx;
119+
}
120+
121+
static inline unsigned int cpuid_edx(unsigned int op)
122+
{
123+
unsigned int eax, ebx, ecx, edx;
124+
125+
cpuid(op, &eax, &ebx, &ecx, &edx);
126+
127+
return edx;
128+
}
129+
11130
static __always_inline bool cpuid_function_is_indexed(u32 function)
12131
{
13132
switch (function) {
@@ -31,4 +150,22 @@ static __always_inline bool cpuid_function_is_indexed(u32 function)
31150
return false;
32151
}
33152

153+
#define for_each_possible_hypervisor_cpuid_base(function) \
154+
for (function = 0x40000000; function < 0x40010000; function += 0x100)
155+
156+
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
157+
{
158+
uint32_t base, eax, signature[3];
159+
160+
for_each_possible_hypervisor_cpuid_base(base) {
161+
cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
162+
163+
if (!memcmp(sig, signature, 12) &&
164+
(leaves == 0 || ((eax - base) >= leaves)))
165+
return base;
166+
}
167+
168+
return 0;
169+
}
170+
34171
#endif /* _ASM_X86_CPUID_H */

arch/x86/include/asm/disabled-features.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@
8181
# define DISABLE_SGX (1 << (X86_FEATURE_SGX & 31))
8282
#endif
8383

84+
#ifdef CONFIG_XEN_PV
85+
# define DISABLE_XENPV 0
86+
#else
87+
# define DISABLE_XENPV (1 << (X86_FEATURE_XENPV & 31))
88+
#endif
89+
8490
#ifdef CONFIG_INTEL_TDX_GUEST
8591
# define DISABLE_TDX_GUEST 0
8692
#else
@@ -98,7 +104,7 @@
98104
#define DISABLED_MASK5 0
99105
#define DISABLED_MASK6 0
100106
#define DISABLED_MASK7 (DISABLE_PTI)
101-
#define DISABLED_MASK8 (DISABLE_TDX_GUEST)
107+
#define DISABLED_MASK8 (DISABLE_XENPV|DISABLE_TDX_GUEST)
102108
#define DISABLED_MASK9 (DISABLE_SGX)
103109
#define DISABLED_MASK10 0
104110
#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET)

arch/x86/include/asm/entry-common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs)
2424
/*
2525
* For !SMAP hardware we patch out CLAC on entry.
2626
*/
27-
if (boot_cpu_has(X86_FEATURE_SMAP) ||
28-
(IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
27+
if (cpu_feature_enabled(X86_FEATURE_SMAP) ||
28+
cpu_feature_enabled(X86_FEATURE_XENPV))
2929
mask |= X86_EFLAGS_AC;
3030

3131
WARN_ON_ONCE(flags & mask);

arch/x86/include/asm/memtype.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
#include <asm/pgtable_types.h>
77

88
extern bool pat_enabled(void);
9-
extern void pat_disable(const char *reason);
10-
extern void pat_init(void);
11-
extern void init_cache_modes(void);
9+
extern void pat_bp_init(void);
10+
extern void pat_cpu_init(void);
1211

1312
extern int memtype_reserve(u64 start, u64 end,
1413
enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);

arch/x86/include/asm/msr-index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@
793793
#define ENERGY_PERF_BIAS_PERFORMANCE 0
794794
#define ENERGY_PERF_BIAS_BALANCE_PERFORMANCE 4
795795
#define ENERGY_PERF_BIAS_NORMAL 6
796+
#define ENERGY_PERF_BIAS_NORMAL_POWERSAVE 7
796797
#define ENERGY_PERF_BIAS_BALANCE_POWERSAVE 8
797798
#define ENERGY_PERF_BIAS_POWERSAVE 15
798799

arch/x86/include/asm/mtrr.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@
2525

2626
#include <uapi/asm/mtrr.h>
2727

28-
void mtrr_bp_init(void);
29-
3028
/*
3129
* The following functions are for use by other drivers that cannot use
3230
* arch_phys_wc_add and arch_phys_wc_del.
3331
*/
3432
# ifdef CONFIG_MTRR
33+
void mtrr_bp_init(void);
3534
extern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform);
3635
extern void mtrr_save_fixed_ranges(void *);
3736
extern void mtrr_save_state(void);
@@ -42,12 +41,12 @@ extern int mtrr_add_page(unsigned long base, unsigned long size,
4241
extern int mtrr_del(int reg, unsigned long base, unsigned long size);
4342
extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
4443
extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
45-
extern void mtrr_ap_init(void);
46-
extern void set_mtrr_aps_delayed_init(void);
47-
extern void mtrr_aps_init(void);
4844
extern void mtrr_bp_restore(void);
4945
extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
5046
extern int amd_special_default_mtrr(void);
47+
void mtrr_disable(void);
48+
void mtrr_enable(void);
49+
void mtrr_generic_set_state(void);
5150
# else
5251
static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform)
5352
{
@@ -83,10 +82,11 @@ static inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
8382
static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
8483
{
8584
}
86-
#define mtrr_ap_init() do {} while (0)
87-
#define set_mtrr_aps_delayed_init() do {} while (0)
88-
#define mtrr_aps_init() do {} while (0)
85+
#define mtrr_bp_init() do {} while (0)
8986
#define mtrr_bp_restore() do {} while (0)
87+
#define mtrr_disable() do {} while (0)
88+
#define mtrr_enable() do {} while (0)
89+
#define mtrr_generic_set_state() do {} while (0)
9090
# endif
9191

9292
#ifdef CONFIG_COMPAT

0 commit comments

Comments
 (0)