mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
Merge tag 'x86_cpu_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cpuid updates from Borislav Petkov: - Get rid of static_cpu_has() - one less API to care about testing CPU features - Unify the handling of CPU core types (performance, efficient, etc) by mapping the vendor-specific types to Linux ones - Continuation of the work of Ahmed Darwish to centralize CPUID leaf representation * tag 'x86_cpu_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/CPU: Rename struct cpuid_read_output to struct cpuid_output x86/cpu/scattered: Sort it properly x86/cpu: Use parsed CPUID(0x1) x86/lib: Add CPUID(0x1) family and model calculation x86/cpu: Use parsed CPUID(0x0) x86/cpu/transmeta: Rescan CPUID(0x1) after modifying capabilities x86/topology: Add TOPO_CPU_TYPE_LOW_POWER x86/topology: Name the AMD core-type values x86/topo: Map vendor CPU types to generic Linux such types x86/bugs: Don't use cpu-type matching in cpu_vuln_blacklist x86/cpu: Hide and rename static_cpu_has()
This commit is contained in:
@@ -49,7 +49,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
* is not relevant.
|
||||
*/
|
||||
#define cpu_feature_enabled(bit) \
|
||||
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
|
||||
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : _static_cpu_has(bit))
|
||||
|
||||
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
||||
|
||||
@@ -64,15 +64,7 @@ extern void setup_clear_cpu_cap(unsigned int bit);
|
||||
|
||||
#define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
|
||||
|
||||
/*
|
||||
* Static testing of CPU features. Used the same as boot_cpu_has(). It
|
||||
* statically patches the target code for additional performance. Use
|
||||
* static_cpu_has() only in fast paths, where every cycle counts. Which
|
||||
* means that the boot_cpu_has() variant is already fast enough for the
|
||||
* majority of cases and you should stick to using it as it is generally
|
||||
* only two instructions: a RIP-relative MOV and a TEST.
|
||||
*/
|
||||
static __always_inline bool _static_cpu_has(u16 bit)
|
||||
static __always_inline bool __static_cpu_has(u16 bit)
|
||||
{
|
||||
asm goto("1: jmp 6f\n"
|
||||
"2:\n"
|
||||
@@ -116,7 +108,7 @@ t_no:
|
||||
return false;
|
||||
}
|
||||
|
||||
#define static_cpu_has(bit) \
|
||||
#define _static_cpu_has(bit) \
|
||||
( \
|
||||
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
||||
boot_cpu_has(bit) : \
|
||||
@@ -126,7 +118,7 @@ t_no:
|
||||
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
|
||||
#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
|
||||
|
||||
#define static_cpu_has_bug(bit) static_cpu_has((bit))
|
||||
#define static_cpu_has_bug(bit) _static_cpu_has((bit))
|
||||
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
|
||||
#define boot_cpu_set_bug(bit) set_cpu_cap(&boot_cpu_data, (bit))
|
||||
|
||||
|
||||
@@ -1392,7 +1392,7 @@ static struct attribute *amd_brs_events_attrs[] = {
|
||||
static umode_t
|
||||
amd_brs_is_visible(struct kobject *kobj, struct attribute *attr, int i)
|
||||
{
|
||||
return static_cpu_has(X86_FEATURE_BRS) && x86_pmu.lbr_nr ?
|
||||
return cpu_feature_enabled(X86_FEATURE_BRS) && x86_pmu.lbr_nr ?
|
||||
attr->mode : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -6385,7 +6385,7 @@ static void intel_pmu_cpu_starting(int cpu)
|
||||
* Deal with CPUs that don't clear their LBRs on power-up, and that may
|
||||
* even boot with LBRs enabled.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr)
|
||||
msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT);
|
||||
intel_pmu_lbr_reset();
|
||||
|
||||
|
||||
+12
-12
@@ -109,7 +109,7 @@ static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
|
||||
|
||||
static __always_inline bool is_lbr_call_stack_bit_set(u64 config)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return !!(config & ARCH_LBR_CALL_STACK);
|
||||
|
||||
return !!(config & LBR_CALL_STACK);
|
||||
@@ -138,13 +138,13 @@ static void __intel_pmu_lbr_enable(bool pmi)
|
||||
*/
|
||||
if (cpuc->lbr_sel)
|
||||
lbr_select = cpuc->lbr_sel->config & x86_pmu.lbr_sel_mask;
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && !pmi && cpuc->lbr_sel)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) && !pmi && cpuc->lbr_sel)
|
||||
wrmsrq(MSR_LBR_SELECT, lbr_select);
|
||||
|
||||
rdmsrq(MSR_IA32_DEBUGCTLMSR, debugctl);
|
||||
orig_debugctl = debugctl;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
debugctl |= DEBUGCTLMSR_LBR;
|
||||
/*
|
||||
* LBR callstack does not work well with FREEZE_LBRS_ON_PMI.
|
||||
@@ -159,7 +159,7 @@ static void __intel_pmu_lbr_enable(bool pmi)
|
||||
if (orig_debugctl != debugctl)
|
||||
wrmsrq(MSR_IA32_DEBUGCTLMSR, debugctl);
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
wrmsrq(MSR_ARCH_LBR_CTL, lbr_select | ARCH_LBR_CTL_LBREN);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ void intel_pmu_lbr_reset(void)
|
||||
|
||||
cpuc->last_task_ctx = NULL;
|
||||
cpuc->last_log_id = 0;
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && cpuc->lbr_select)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) && cpuc->lbr_select)
|
||||
wrmsrq(MSR_LBR_SELECT, 0);
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ static void intel_pmu_arch_lbr_xrstors(void *ctx)
|
||||
|
||||
static __always_inline bool lbr_is_reset_in_cstate(void *ctx)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return x86_pmu.lbr_deep_c_reset && !rdlbr_from(0, NULL);
|
||||
|
||||
return !rdlbr_from(((struct x86_perf_task_context *)ctx)->tos, NULL);
|
||||
@@ -624,7 +624,7 @@ void release_lbr_buffers(void)
|
||||
struct cpu_hw_events *cpuc;
|
||||
int cpu;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
@@ -643,7 +643,7 @@ void reserve_lbr_buffers(void)
|
||||
struct cpu_hw_events *cpuc;
|
||||
int cpu;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
@@ -730,7 +730,7 @@ void intel_pmu_lbr_disable_all(void)
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
|
||||
if (cpuc->lbr_users && !vlbr_exclude_host()) {
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return __intel_pmu_arch_lbr_disable();
|
||||
|
||||
__intel_pmu_lbr_disable();
|
||||
@@ -889,7 +889,7 @@ static __always_inline u16 get_lbr_cycles(u64 info)
|
||||
{
|
||||
u16 cycles = info & LBR_INFO_CYCLES;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR) &&
|
||||
(!static_branch_likely(&x86_lbr_cycles) ||
|
||||
!(info & LBR_INFO_CYC_CNT_VALID)))
|
||||
cycles = 0;
|
||||
@@ -1124,7 +1124,7 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
|
||||
reg = &event->hw.branch_reg;
|
||||
reg->idx = EXTRA_REG_LBR;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
|
||||
reg->config = mask;
|
||||
|
||||
/*
|
||||
@@ -1285,7 +1285,7 @@ void intel_pmu_store_pebs_lbrs(struct lbr_entry *lbr)
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
|
||||
/* Cannot get TOS for large PEBS and Arch LBR */
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR) ||
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR) ||
|
||||
(cpuc->n_pebs == cpuc->n_large_pebs))
|
||||
cpuc->lbr_stack.hw_idx = -1ULL;
|
||||
else
|
||||
|
||||
@@ -1176,7 +1176,7 @@ DECLARE_STATIC_CALL(x86_pmu_pebs_disable_all, *x86_pmu.pebs_disable_all);
|
||||
|
||||
static __always_inline struct x86_perf_task_context_opt *task_context_opt(void *ctx)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR))
|
||||
if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return &((struct x86_perf_task_context_arch_lbr *)ctx)->opt;
|
||||
|
||||
return &((struct x86_perf_task_context *)ctx)->opt;
|
||||
|
||||
@@ -45,12 +45,12 @@ static inline bool __must_check rdseed_long(unsigned long *v)
|
||||
|
||||
static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
|
||||
{
|
||||
return max_longs && static_cpu_has(X86_FEATURE_RDRAND) && rdrand_long(v) ? 1 : 0;
|
||||
return max_longs && cpu_feature_enabled(X86_FEATURE_RDRAND) && rdrand_long(v) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs)
|
||||
{
|
||||
return max_longs && static_cpu_has(X86_FEATURE_RDSEED) && rdseed_long(v) ? 1 : 0;
|
||||
return max_longs && cpu_feature_enabled(X86_FEATURE_RDSEED) && rdseed_long(v) ? 1 : 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_UML
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include <linux/topology.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <asm/ibt.h>
|
||||
#include <asm/cpuid/leaf_types.h>
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
#define cpu_physical_id(cpu) boot_cpu_physical_apicid
|
||||
@@ -24,6 +26,10 @@ int mwait_usable(const struct cpuinfo_x86 *);
|
||||
unsigned int x86_family(unsigned int sig);
|
||||
unsigned int x86_model(unsigned int sig);
|
||||
unsigned int x86_stepping(unsigned int sig);
|
||||
|
||||
unsigned int cpuid_family(const struct leaf_0x1_0 *l);
|
||||
unsigned int cpuid_model(const struct leaf_0x1_0 *l);
|
||||
|
||||
#ifdef CONFIG_X86_BUS_LOCK_DETECT
|
||||
extern void __init sld_setup(struct cpuinfo_x86 *c);
|
||||
extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
|
||||
|
||||
@@ -69,7 +69,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
* is not relevant.
|
||||
*/
|
||||
#define cpu_feature_enabled(bit) \
|
||||
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
|
||||
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : _static_cpu_has(bit))
|
||||
|
||||
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
||||
|
||||
@@ -96,7 +96,7 @@ void check_cpufeature_deps(struct cpuinfo_x86 *c);
|
||||
* it to manifest the address of boot_cpu_data in a register, fouling
|
||||
* the mainline (post-initialization) code.
|
||||
*/
|
||||
static __always_inline bool _static_cpu_has(u16 bit)
|
||||
static __always_inline bool __static_cpu_has(u16 bit)
|
||||
{
|
||||
asm goto(ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]")
|
||||
".pushsection .altinstr_aux,\"ax\"\n"
|
||||
@@ -116,17 +116,17 @@ t_no:
|
||||
return false;
|
||||
}
|
||||
|
||||
#define static_cpu_has(bit) \
|
||||
#define _static_cpu_has(bit) \
|
||||
( \
|
||||
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
||||
boot_cpu_has(bit) : \
|
||||
_static_cpu_has(bit) \
|
||||
__static_cpu_has(bit) \
|
||||
)
|
||||
|
||||
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
|
||||
#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
|
||||
|
||||
#define static_cpu_has_bug(bit) static_cpu_has((bit))
|
||||
#define static_cpu_has_bug(bit) _static_cpu_has((bit))
|
||||
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
|
||||
#define boot_cpu_set_bug(bit) set_cpu_cap(&boot_cpu_data, (bit))
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ static __always_inline unsigned long local_db_save(void)
|
||||
{
|
||||
unsigned long dr7;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_HYPERVISOR) && !hw_breakpoint_active())
|
||||
if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR) && !hw_breakpoint_active())
|
||||
return 0;
|
||||
|
||||
get_debugreg(dr7, 7);
|
||||
|
||||
@@ -911,7 +911,7 @@ pgd_t __pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd);
|
||||
*/
|
||||
static inline pgd_t pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd)
|
||||
{
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return pgd;
|
||||
return __pti_set_user_pgtbl(pgdp, pgd);
|
||||
}
|
||||
@@ -1471,7 +1471,7 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
|
||||
{
|
||||
memcpy(dst, src, count * sizeof(pgd_t));
|
||||
#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return;
|
||||
/* Clone the user space pgd as well */
|
||||
memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
|
||||
|
||||
@@ -68,9 +68,14 @@ extern u16 __read_mostly tlb_lld_2m;
|
||||
extern u16 __read_mostly tlb_lld_4m;
|
||||
extern u16 __read_mostly tlb_lld_1g;
|
||||
|
||||
/*
|
||||
* CPU type and hardware bug flags. Kept separately for each CPU.
|
||||
*/
|
||||
enum x86_topology_cpu_type {
|
||||
/* X86_CPU_TYPE_ANY */
|
||||
TOPO_CPU_TYPE_ANY = 0,
|
||||
TOPO_CPU_TYPE_PERFORMANCE,
|
||||
TOPO_CPU_TYPE_EFFICIENCY,
|
||||
TOPO_CPU_TYPE_LOW_POWER,
|
||||
TOPO_CPU_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
struct cpuinfo_topology {
|
||||
// Real APIC ID read from the local APIC
|
||||
@@ -104,7 +109,7 @@ struct cpuinfo_topology {
|
||||
|
||||
// Hardware defined CPU-type
|
||||
union {
|
||||
u32 cpu_type;
|
||||
u32 hw_cpu_type;
|
||||
struct {
|
||||
// CPUID.1A.EAX[23-0]
|
||||
u32 intel_native_model_id :24;
|
||||
@@ -119,8 +124,14 @@ struct cpuinfo_topology {
|
||||
amd_type :4;
|
||||
};
|
||||
};
|
||||
|
||||
// Linux vendor-agnostic CPU type
|
||||
enum x86_topology_cpu_type cpu_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* CPU type and hardware bug flags. Kept separately for each CPU.
|
||||
*/
|
||||
struct cpuinfo_x86 {
|
||||
union {
|
||||
/*
|
||||
|
||||
@@ -61,7 +61,7 @@ static __always_inline void sync_core(void)
|
||||
* The SERIALIZE instruction is the most straightforward way to
|
||||
* do this, but it is not universally available.
|
||||
*/
|
||||
if (static_cpu_has(X86_FEATURE_SERIALIZE)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_SERIALIZE)) {
|
||||
serialize();
|
||||
return;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ static __always_inline void sync_core(void)
|
||||
static inline void sync_core_before_usermode(void)
|
||||
{
|
||||
/* With PTI, we unconditionally serialize before running user code. */
|
||||
if (static_cpu_has(X86_FEATURE_PTI))
|
||||
if (cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
||||
@@ -114,10 +114,10 @@ enum x86_topology_domains {
|
||||
TOPO_MAX_DOMAIN,
|
||||
};
|
||||
|
||||
enum x86_topology_cpu_type {
|
||||
TOPO_CPU_TYPE_PERFORMANCE,
|
||||
TOPO_CPU_TYPE_EFFICIENCY,
|
||||
TOPO_CPU_TYPE_UNKNOWN,
|
||||
enum amd_cpu_type {
|
||||
AMD_CPU_TYPE_PERFORMANCE = 0,
|
||||
AMD_CPU_TYPE_EFFICIENCY = 1,
|
||||
AMD_CPU_TYPE_LOW_POWER = 2,
|
||||
};
|
||||
|
||||
struct x86_topology_system {
|
||||
@@ -160,7 +160,6 @@ extern unsigned int __num_nodes_per_package;
|
||||
struct cpuinfo_x86;
|
||||
|
||||
const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
|
||||
enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
|
||||
|
||||
static inline unsigned int topology_max_packages(void)
|
||||
{
|
||||
|
||||
@@ -241,7 +241,6 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore);
|
||||
*/
|
||||
int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
|
||||
{
|
||||
enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu));
|
||||
bool prefcore;
|
||||
int ret;
|
||||
u32 tmp;
|
||||
@@ -273,16 +272,18 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
|
||||
|
||||
/* detect if running on heterogeneous design */
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) {
|
||||
switch (core_type) {
|
||||
switch (cpu_data(cpu).topo.cpu_type) {
|
||||
case TOPO_CPU_TYPE_UNKNOWN:
|
||||
case TOPO_CPU_TYPE_ANY:
|
||||
pr_warn("Undefined core type found for cpu %d\n", cpu);
|
||||
break;
|
||||
case TOPO_CPU_TYPE_PERFORMANCE:
|
||||
/* use the max scale for performance cores */
|
||||
*numerator = CPPC_HIGHEST_PERF_PERFORMANCE;
|
||||
return 0;
|
||||
case TOPO_CPU_TYPE_LOW_POWER:
|
||||
case TOPO_CPU_TYPE_EFFICIENCY:
|
||||
/* use the highest perf value for efficiency cores */
|
||||
/* use the highest perf value for efficiency and low-power cores */
|
||||
ret = amd_get_highest_perf(cpu, &tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -31,7 +31,7 @@ static u32 numachip1_get_apic_id(u32 x)
|
||||
unsigned long value;
|
||||
unsigned int id = (x >> 24) & 0xff;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_NODEID_MSR)) {
|
||||
rdmsrq(MSR_FAM10H_NODE_ID, value);
|
||||
id |= (value << 2) & 0xff00;
|
||||
}
|
||||
|
||||
@@ -192,8 +192,8 @@ x86_virt_spec_ctrl(u64 guest_virt_spec_ctrl, bool setguest)
|
||||
* If SSBD is not handled in MSR_SPEC_CTRL on AMD, update
|
||||
* MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_LS_CFG_SSBD) &&
|
||||
!static_cpu_has(X86_FEATURE_VIRT_SSBD))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_LS_CFG_SSBD) &&
|
||||
!cpu_feature_enabled(X86_FEATURE_VIRT_SSBD))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -201,7 +201,7 @@ x86_virt_spec_ctrl(u64 guest_virt_spec_ctrl, bool setguest)
|
||||
* virtual MSR value. If its not permanently enabled, evaluate
|
||||
* current's TIF_SSBD thread flag.
|
||||
*/
|
||||
if (static_cpu_has(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE))
|
||||
if (cpu_feature_enabled(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE))
|
||||
hostval = SPEC_CTRL_SSBD;
|
||||
else
|
||||
hostval = ssbd_tif_to_spec_ctrl(ti->flags);
|
||||
@@ -2499,8 +2499,8 @@ static void __init ssb_apply_mitigation(void)
|
||||
* Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD may
|
||||
* use a completely different MSR and bit dependent on family.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) &&
|
||||
!static_cpu_has(X86_FEATURE_AMD_SSBD)) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_SPEC_CTRL_SSBD) &&
|
||||
!cpu_feature_enabled(X86_FEATURE_AMD_SSBD)) {
|
||||
x86_amd_ssb_disable();
|
||||
} else {
|
||||
x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
|
||||
|
||||
@@ -654,7 +654,7 @@ static DEFINE_RAW_SPINLOCK(cache_disable_lock);
|
||||
*/
|
||||
static void maybe_flush_caches(void)
|
||||
{
|
||||
if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_SELFSNOOP))
|
||||
wbinvd();
|
||||
}
|
||||
|
||||
|
||||
@@ -942,26 +942,27 @@ void get_cpu_vendor(struct cpuinfo_x86 *c)
|
||||
|
||||
void cpu_detect(struct cpuinfo_x86 *c)
|
||||
{
|
||||
/* Get vendor name */
|
||||
cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
|
||||
(unsigned int *)&c->x86_vendor_id[0],
|
||||
(unsigned int *)&c->x86_vendor_id[8],
|
||||
(unsigned int *)&c->x86_vendor_id[4]);
|
||||
const struct leaf_0x0_0 *l0 = cpuid_leaf(c, 0x0);
|
||||
const struct leaf_0x1_0 *l1;
|
||||
|
||||
c->cpuid_level = l0->max_std_leaf;
|
||||
*(u32 *)&c->x86_vendor_id[0] = l0->cpu_vendorid_0;
|
||||
*(u32 *)&c->x86_vendor_id[4] = l0->cpu_vendorid_1;
|
||||
*(u32 *)&c->x86_vendor_id[8] = l0->cpu_vendorid_2;
|
||||
|
||||
c->x86 = 4;
|
||||
/* Intel-defined flags: level 0x00000001 */
|
||||
if (c->cpuid_level >= 0x00000001) {
|
||||
u32 junk, tfms, cap0, misc;
|
||||
|
||||
cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
|
||||
c->x86 = x86_family(tfms);
|
||||
c->x86_model = x86_model(tfms);
|
||||
c->x86_stepping = x86_stepping(tfms);
|
||||
l1 = cpuid_leaf(c, 0x1);
|
||||
if (!l1)
|
||||
return;
|
||||
|
||||
if (cap0 & (1<<19)) {
|
||||
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
|
||||
c->x86_cache_alignment = c->x86_clflush_size;
|
||||
}
|
||||
c->x86 = cpuid_family(l1);
|
||||
c->x86_model = cpuid_model(l1);
|
||||
c->x86_stepping = l1->stepping;
|
||||
|
||||
if (l1->clflush) {
|
||||
c->x86_clflush_size = l1->clflush_size * 8;
|
||||
c->x86_cache_alignment = c->x86_clflush_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1251,9 +1252,6 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
||||
#define VULNBL_INTEL_STEPS(vfm, max_stepping, issues) \
|
||||
X86_MATCH_VFM_STEPS(vfm, X86_STEP_MIN, max_stepping, issues)
|
||||
|
||||
#define VULNBL_INTEL_TYPE(vfm, cpu_type, issues) \
|
||||
X86_MATCH_VFM_CPU_TYPE(vfm, INTEL_CPU_TYPE_##cpu_type, issues)
|
||||
|
||||
#define VULNBL_AMD(family, blacklist) \
|
||||
VULNBL(AMD, family, X86_MODEL_ANY, blacklist)
|
||||
|
||||
@@ -1316,11 +1314,9 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
||||
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED),
|
||||
VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE, X86_STEP_MAX, VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE, X86_STEP_MAX, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE_P, X86_STEP_MAX, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE_S, X86_STEP_MAX, RFDS | VMSCAPE),
|
||||
VULNBL_INTEL_STEPS(INTEL_METEORLAKE_L, X86_STEP_MAX, VMSCAPE),
|
||||
@@ -1388,7 +1384,21 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
|
||||
return true;
|
||||
|
||||
/* Only consult the blacklist when there is no enumeration: */
|
||||
return cpu_matches(cpu_vuln_blacklist, RFDS);
|
||||
if (!cpu_matches(cpu_vuln_blacklist, RFDS))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* ADL and RPL are affected only if they have Atom CPUs. Hybrids have
|
||||
* both Core and Atom CPUs. Mark unaffected when Atom CPUs are not
|
||||
* present.
|
||||
*/
|
||||
if ((boot_cpu_data.x86_model == 0x97 ||
|
||||
boot_cpu_data.x86_model == 0xB7) &&
|
||||
boot_cpu_data.topo.intel_type != INTEL_CPU_TYPE_ATOM &&
|
||||
!boot_cpu_has(X86_FEATURE_HYBRID_CPU))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
#include "cpuid_parser.h"
|
||||
|
||||
/* Clear a single CPUID table entry */
|
||||
static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
|
||||
static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_output *out)
|
||||
{
|
||||
struct cpuid_regs *regs = output->regs;
|
||||
struct cpuid_regs *regs = out->regs;
|
||||
|
||||
for (int i = 0; i < e->maxcnt; i++, regs++)
|
||||
memset(regs, 0, sizeof(*regs));
|
||||
|
||||
memset(output->info, 0, sizeof(*output->info));
|
||||
memset(out->info, 0, sizeof(*out->info));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -29,12 +29,11 @@ static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_re
|
||||
* Default CPUID read function
|
||||
* Satisfies the requirements stated at 'struct cpuid_parse_entry'->read().
|
||||
*/
|
||||
static void
|
||||
cpuid_read_generic(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
|
||||
static void cpuid_read_generic(const struct cpuid_parse_entry *e, const struct cpuid_output *out)
|
||||
{
|
||||
struct cpuid_regs *regs = output->regs;
|
||||
struct cpuid_regs *regs = out->regs;
|
||||
|
||||
for (int i = 0; i < e->maxcnt; i++, regs++, output->info->nr_entries++)
|
||||
for (int i = 0; i < e->maxcnt; i++, regs++, out->info->nr_entries++)
|
||||
cpuid_read_subleaf(e->leaf, e->subleaf + i, regs);
|
||||
}
|
||||
|
||||
@@ -60,15 +59,14 @@ static unsigned int cpuid_range_max_leaf(const struct cpuid_table *t, unsigned i
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end, bool fill)
|
||||
static void __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end, bool fill)
|
||||
{
|
||||
const struct cpuid_parse_entry *entry = entries;
|
||||
unsigned int range = CPUID_RANGE(start);
|
||||
|
||||
for (unsigned int i = 0; i < nr_entries; i++, entry++) {
|
||||
struct cpuid_read_output output = {
|
||||
struct cpuid_output out = {
|
||||
.regs = cpuid_table_regs_p(t, entry->regs_offs),
|
||||
.info = cpuid_table_info_p(t, entry->info_offs),
|
||||
};
|
||||
@@ -76,14 +74,14 @@ __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entrie
|
||||
if (entry->leaf < start || entry->leaf > end)
|
||||
continue;
|
||||
|
||||
cpuid_clear(entry, &output);
|
||||
cpuid_clear(entry, &out);
|
||||
|
||||
/*
|
||||
* Read the range's anchor leaf unconditionally so that the cached
|
||||
* maximum valid leaf value is available for the remaining entries.
|
||||
*/
|
||||
if (fill && (entry->leaf == range || entry->leaf <= cpuid_range_max_leaf(t, range)))
|
||||
entry->read(entry, &output);
|
||||
entry->read(entry, &out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,22 +89,20 @@ __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entrie
|
||||
* Zero all cached CPUID entries within [@start-@end] range. This is needed when
|
||||
* certain operations like MSR writes induce changes to the CPU's CPUID layout.
|
||||
*/
|
||||
static void
|
||||
__cpuid_zero_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end)
|
||||
static void __cpuid_zero_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end)
|
||||
{
|
||||
__cpuid_reset_table(t, entries, nr_entries, start, end, false);
|
||||
}
|
||||
|
||||
static void
|
||||
__cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end)
|
||||
static void __cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries, unsigned int start, unsigned int end)
|
||||
{
|
||||
__cpuid_reset_table(t, entries, nr_entries, start, end, true);
|
||||
}
|
||||
|
||||
static void
|
||||
cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[], unsigned int nr_entries)
|
||||
static void cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
|
||||
unsigned int nr_entries)
|
||||
{
|
||||
static const struct {
|
||||
unsigned int start;
|
||||
@@ -127,8 +123,8 @@ static void __cpuid_scan_cpu_full(struct cpuinfo_x86 *c)
|
||||
cpuid_fill_table(table, cpuid_parse_entries, nr_entries);
|
||||
}
|
||||
|
||||
static void
|
||||
__cpuid_scan_cpu_partial(struct cpuinfo_x86 *c, unsigned int start_leaf, unsigned int end_leaf)
|
||||
static void __cpuid_scan_cpu_partial(struct cpuinfo_x86 *c, unsigned int start_leaf,
|
||||
unsigned int end_leaf)
|
||||
{
|
||||
unsigned int nr_entries = ARRAY_SIZE(cpuid_parse_entries);
|
||||
struct cpuid_table *table = &c->cpuid;
|
||||
|
||||
@@ -35,21 +35,21 @@
|
||||
* Translation of compile time offsets to generic runtime pointers:
|
||||
*/
|
||||
|
||||
static inline struct cpuid_regs *
|
||||
cpuid_table_regs_p(const struct cpuid_table *t, unsigned long regs_offset)
|
||||
static inline struct cpuid_regs *cpuid_table_regs_p(const struct cpuid_table *t,
|
||||
unsigned long regs_offset)
|
||||
{
|
||||
return (struct cpuid_regs *)((unsigned long)(&t->leaves) + regs_offset);
|
||||
}
|
||||
|
||||
static inline struct leaf_parse_info *
|
||||
cpuid_table_info_p(const struct cpuid_table *t, unsigned long info_offset)
|
||||
static inline struct leaf_parse_info *cpuid_table_info_p(const struct cpuid_table *t,
|
||||
unsigned long info_offset)
|
||||
{
|
||||
return (struct leaf_parse_info *)((unsigned long)(&t->leaves) + info_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct cpuid_read_output - Output of a CPUID read operation
|
||||
* @regs: Pointer to an array of CPUID outputs, where each array element covers the
|
||||
* struct cpuid_output - Output of a CPUID operation
|
||||
* @regs: Pointer to an array of CPUID results, where each array element covers the
|
||||
* full EAX->EDX output range.
|
||||
* @info: Pointer to query info; for saving the number of filled elements at @regs.
|
||||
*
|
||||
@@ -59,7 +59,7 @@ cpuid_table_info_p(const struct cpuid_table *t, unsigned long info_offset)
|
||||
*
|
||||
* See struct cpuid_parse_entry.read().
|
||||
*/
|
||||
struct cpuid_read_output {
|
||||
struct cpuid_output {
|
||||
struct cpuid_regs *regs;
|
||||
struct leaf_parse_info *info;
|
||||
};
|
||||
@@ -74,8 +74,8 @@ struct cpuid_read_output {
|
||||
* passed to cpuid_table_info_p().
|
||||
* @maxcnt: Maximum number of output storage entries available for the CPUID query.
|
||||
* @read: Read function for this entry. It must save the parsed CPUID output to the passed
|
||||
* 'struct cpuid_read_output'->regs array of size >= @maxcnt. It must set
|
||||
* 'struct cpuid_read_output'->info.nr_entries to the number of CPUID output entries
|
||||
* 'struct cpuid_output'->regs array of size >= @maxcnt. It must set
|
||||
* 'struct cpuid_output'->info.nr_entries to the number of CPUID output entries
|
||||
* parsed and filled. A generic implementation is provided at cpuid_read_generic().
|
||||
*/
|
||||
struct cpuid_parse_entry {
|
||||
@@ -84,7 +84,7 @@ struct cpuid_parse_entry {
|
||||
unsigned int regs_offs;
|
||||
unsigned int info_offs;
|
||||
unsigned int maxcnt;
|
||||
void (*read)(const struct cpuid_parse_entry *e, const struct cpuid_read_output *o);
|
||||
void (*read)(const struct cpuid_parse_entry *e, const struct cpuid_output *o);
|
||||
};
|
||||
|
||||
#define __CPUID_PARSE_ENTRY(_leaf, _subleaf, _suffix, _reader_fn) \
|
||||
|
||||
@@ -5,34 +5,6 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/**
|
||||
* x86_match_vendor_cpu_type - helper function to match the hardware defined
|
||||
* cpu-type for a single entry in the x86_cpu_id
|
||||
* table. Note, this function does not match the
|
||||
* generic cpu-types TOPO_CPU_TYPE_EFFICIENCY and
|
||||
* TOPO_CPU_TYPE_PERFORMANCE.
|
||||
* @c: Pointer to the cpuinfo_x86 structure of the CPU to match.
|
||||
* @m: Pointer to the x86_cpu_id entry to match against.
|
||||
*
|
||||
* Return: true if the cpu-type matches, false otherwise.
|
||||
*/
|
||||
static bool x86_match_vendor_cpu_type(struct cpuinfo_x86 *c, const struct x86_cpu_id *m)
|
||||
{
|
||||
if (m->type == X86_CPU_TYPE_ANY)
|
||||
return true;
|
||||
|
||||
/* Hybrid CPUs are special, they are assumed to match all cpu-types */
|
||||
if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
|
||||
return true;
|
||||
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL)
|
||||
return m->type == c->topo.intel_type;
|
||||
if (c->x86_vendor == X86_VENDOR_AMD)
|
||||
return m->type == c->topo.amd_type;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_match_cpu - match current CPU against an array of x86_cpu_ids
|
||||
* @match: Pointer to array of x86_cpu_ids. Last entry terminated with
|
||||
@@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
|
||||
continue;
|
||||
if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
|
||||
continue;
|
||||
if (!x86_match_vendor_cpu_type(c, m))
|
||||
if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type)
|
||||
continue;
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ static const struct cpuid_bit cpuid_bits[] = {
|
||||
{ X86_FEATURE_CQM_MBM_LOCAL, CPUID_EDX, 2, 0x0000000f, 1 },
|
||||
{ X86_FEATURE_CAT_L3, CPUID_EBX, 1, 0x00000010, 0 },
|
||||
{ X86_FEATURE_CAT_L2, CPUID_EBX, 2, 0x00000010, 0 },
|
||||
{ X86_FEATURE_MBA, CPUID_EBX, 3, 0x00000010, 0 },
|
||||
{ X86_FEATURE_CDP_L3, CPUID_ECX, 2, 0x00000010, 1 },
|
||||
{ X86_FEATURE_CDP_L2, CPUID_ECX, 2, 0x00000010, 2 },
|
||||
{ X86_FEATURE_MBA, CPUID_EBX, 3, 0x00000010, 0 },
|
||||
{ X86_FEATURE_PER_THREAD_MBA, CPUID_ECX, 0, 0x00000010, 3 },
|
||||
{ X86_FEATURE_SGX1, CPUID_EAX, 0, 0x00000012, 0 },
|
||||
{ X86_FEATURE_SGX2, CPUID_EAX, 1, 0x00000012, 0 },
|
||||
@@ -61,9 +61,9 @@ static const struct cpuid_bit cpuid_bits[] = {
|
||||
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
|
||||
{ X86_FEATURE_ABMC, CPUID_EBX, 5, 0x80000020, 0 },
|
||||
{ X86_FEATURE_SDCIAE, CPUID_EBX, 6, 0x80000020, 0 },
|
||||
{ X86_FEATURE_AMD_WORKLOAD_CLASS, CPUID_EAX, 22, 0x80000021, 0 },
|
||||
{ X86_FEATURE_TSA_SQ_NO, CPUID_ECX, 1, 0x80000021, 0 },
|
||||
{ X86_FEATURE_TSA_L1_NO, CPUID_ECX, 2, 0x80000021, 0 },
|
||||
{ X86_FEATURE_AMD_WORKLOAD_CLASS, CPUID_EAX, 22, 0x80000021, 0 },
|
||||
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 },
|
||||
|
||||
@@ -22,6 +22,7 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
|
||||
bool cpu_parse_topology_ext(struct topo_scan *tscan);
|
||||
void cpu_parse_topology_amd(struct topo_scan *tscan);
|
||||
void cpu_topology_fixup_amd(struct topo_scan *tscan);
|
||||
enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
|
||||
|
||||
static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom)
|
||||
{
|
||||
|
||||
@@ -177,8 +177,10 @@ static void topoext_fixup(struct topo_scan *tscan)
|
||||
|
||||
static void parse_topology_amd(struct topo_scan *tscan)
|
||||
{
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES))
|
||||
tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) {
|
||||
tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026);
|
||||
tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get SMT, CORE, TILE, and DIE shifts from extended
|
||||
|
||||
@@ -42,8 +42,9 @@ enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c)
|
||||
}
|
||||
if (c->x86_vendor == X86_VENDOR_AMD) {
|
||||
switch (c->topo.amd_type) {
|
||||
case 0: return TOPO_CPU_TYPE_PERFORMANCE;
|
||||
case 1: return TOPO_CPU_TYPE_EFFICIENCY;
|
||||
case AMD_CPU_TYPE_PERFORMANCE: return TOPO_CPU_TYPE_PERFORMANCE;
|
||||
case AMD_CPU_TYPE_EFFICIENCY: return TOPO_CPU_TYPE_EFFICIENCY;
|
||||
case AMD_CPU_TYPE_LOW_POWER: return TOPO_CPU_TYPE_LOW_POWER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +58,8 @@ const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c)
|
||||
return "performance";
|
||||
case TOPO_CPU_TYPE_EFFICIENCY:
|
||||
return "efficiency";
|
||||
case TOPO_CPU_TYPE_LOW_POWER:
|
||||
return "low_power";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
@@ -168,8 +171,12 @@ static void parse_topology(struct topo_scan *tscan, bool early)
|
||||
case X86_VENDOR_INTEL:
|
||||
if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
|
||||
parse_legacy(tscan);
|
||||
if (c->cpuid_level >= 0x1a)
|
||||
c->topo.cpu_type = cpuid_eax(0x1a);
|
||||
|
||||
if (c->cpuid_level >= 0x1a) {
|
||||
c->topo.hw_cpu_type = cpuid_eax(0x1a);
|
||||
c->topo.cpu_type = get_topology_cpu_type(c);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ static void init_transmeta(struct cpuinfo_x86 *c)
|
||||
/* Unhide possibly hidden capability flags */
|
||||
rdmsrq(0x80860004, msr);
|
||||
wrmsrq(0x80860004, msr | ~0U);
|
||||
cpuid_refresh_leaf(c, 0x1);
|
||||
c->x86_capability[CPUID_1_EDX] = cpuid_edx(0x00000001);
|
||||
wrmsrq(0x80860004, msr);
|
||||
|
||||
|
||||
@@ -874,7 +874,7 @@ void fpu_flush_thread(void)
|
||||
*/
|
||||
void switch_fpu_return(void)
|
||||
{
|
||||
if (!static_cpu_has(X86_FEATURE_FPU))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_FPU))
|
||||
return;
|
||||
|
||||
fpregs_restore_userregs();
|
||||
|
||||
@@ -187,7 +187,7 @@ bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size, u
|
||||
ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||
|
||||
IS_ENABLED(CONFIG_IA32_EMULATION));
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_FPU)) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_FPU)) {
|
||||
struct user_i387_ia32_struct fp;
|
||||
|
||||
fpregs_soft_get(current, NULL, (struct membuf){.p = &fp,
|
||||
|
||||
@@ -77,7 +77,7 @@ found:
|
||||
static void synthesize_clac(kprobe_opcode_t *addr)
|
||||
{
|
||||
/*
|
||||
* Can't be static_cpu_has() due to how objtool treats this feature bit.
|
||||
* Can't be cpu_feature_enabled() due to how objtool treats this feature bit.
|
||||
* This isn't a fast path anyway.
|
||||
*/
|
||||
if (!boot_cpu_has(X86_FEATURE_SMAP))
|
||||
|
||||
@@ -61,7 +61,7 @@ void load_mm_ldt(struct mm_struct *mm)
|
||||
*/
|
||||
|
||||
if (unlikely(ldt)) {
|
||||
if (static_cpu_has(X86_FEATURE_PTI)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_PTI)) {
|
||||
if (WARN_ON_ONCE((unsigned long)ldt->slot > 1)) {
|
||||
/*
|
||||
* Whoops -- either the new LDT isn't mapped
|
||||
|
||||
@@ -579,7 +579,7 @@ static __always_inline void amd_set_core_ssb_state(unsigned long tifn)
|
||||
struct ssb_state *st = this_cpu_ptr(&ssb_state);
|
||||
u64 msr = x86_amd_ls_cfg_base;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_ZEN)) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ZEN)) {
|
||||
msr |= ssbd_tif_to_amd_ls_cfg(tifn);
|
||||
wrmsrq(MSR_AMD64_LS_CFG, msr);
|
||||
return;
|
||||
@@ -646,14 +646,14 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
/* Handle change of TIF_SSBD depending on the mitigation method. */
|
||||
if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_VIRT_SSBD)) {
|
||||
if (tif_diff & _TIF_SSBD)
|
||||
amd_set_ssb_virt_state(tifn);
|
||||
} else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) {
|
||||
} else if (cpu_feature_enabled(X86_FEATURE_LS_CFG_SSBD)) {
|
||||
if (tif_diff & _TIF_SSBD)
|
||||
amd_set_core_ssb_state(tifn);
|
||||
} else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
|
||||
static_cpu_has(X86_FEATURE_AMD_SSBD)) {
|
||||
} else if (cpu_feature_enabled(X86_FEATURE_SPEC_CTRL_SSBD) ||
|
||||
cpu_feature_enabled(X86_FEATURE_AMD_SSBD)) {
|
||||
updmsr |= !!(tif_diff & _TIF_SSBD);
|
||||
msr |= ssbd_tif_to_spec_ctrl(tifn);
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ static __always_inline void save_fsgs(struct task_struct *task)
|
||||
{
|
||||
savesegment(fs, task->thread.fsindex);
|
||||
savesegment(gs, task->thread.gsindex);
|
||||
if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_FSGSBASE)) {
|
||||
/*
|
||||
* If FSGSBASE is enabled, we can't make any useful guesses
|
||||
* about the base, and user code expects us to save the current
|
||||
@@ -391,7 +391,7 @@ static __always_inline void x86_pkru_load(struct thread_struct *prev,
|
||||
static __always_inline void x86_fsgsbase_load(struct thread_struct *prev,
|
||||
struct thread_struct *next)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_FSGSBASE)) {
|
||||
/* Update the FS and GS selectors if they could have changed. */
|
||||
if (unlikely(prev->fsindex || next->fsindex))
|
||||
loadseg(FS, next->fsindex);
|
||||
@@ -533,7 +533,7 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
|
||||
{
|
||||
WARN_ON_ONCE(regs != current_pt_regs());
|
||||
|
||||
if (static_cpu_has(X86_BUG_NULL_SEG)) {
|
||||
if (cpu_feature_enabled(X86_BUG_NULL_SEG)) {
|
||||
/* Loading zero below won't clear the base. */
|
||||
loadsegment(fs, __USER_DS);
|
||||
load_gs_index(__USER_DS);
|
||||
|
||||
@@ -357,7 +357,7 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
|
||||
unsafe_put_user(ptr_to_compat(&frame->uc), &frame->puc, Efault);
|
||||
|
||||
/* Create the ucontext. */
|
||||
if (static_cpu_has(X86_FEATURE_XSAVE))
|
||||
if (cpu_feature_enabled(X86_FEATURE_XSAVE))
|
||||
unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault);
|
||||
else
|
||||
unsafe_put_user(0, &frame->uc.uc_flags, Efault);
|
||||
|
||||
@@ -82,7 +82,7 @@ static __init void x86_late_time_init(void)
|
||||
x86_init.irqs.intr_mode_init();
|
||||
tsc_init();
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_WAITPKG))
|
||||
if (cpu_feature_enabled(X86_FEATURE_WAITPKG))
|
||||
use_tpause_delay();
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ SECTIONS
|
||||
* references to such code must be patched out by alternatives, normally
|
||||
* by using X86_FEATURE_ALWAYS CPU feature bit.
|
||||
*
|
||||
* See static_cpu_has() for an example.
|
||||
* See cpu_feature_enabled() for an example.
|
||||
*/
|
||||
.altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {
|
||||
*(.altinstr_aux)
|
||||
|
||||
@@ -1507,7 +1507,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
||||
union cpuid10_eax eax = { };
|
||||
union cpuid10_edx edx = { };
|
||||
|
||||
if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) {
|
||||
if (!enable_pmu || !cpu_feature_enabled(X86_FEATURE_ARCH_PERFMON)) {
|
||||
entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1748,7 +1748,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
||||
* loop if said highest leaf has no subleaves indexed by ECX.
|
||||
*/
|
||||
if (entry->eax >= 0x8000001d &&
|
||||
(static_cpu_has(X86_FEATURE_LFENCE_RDTSC)
|
||||
(cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC)
|
||||
|| !static_cpu_has_bug(X86_BUG_NULL_SEG)))
|
||||
entry->eax = max(entry->eax, 0x80000021);
|
||||
break;
|
||||
|
||||
+11
-11
@@ -310,7 +310,7 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu,
|
||||
goto done;
|
||||
|
||||
if (nrips && svm->vmcb->control.next_rip != 0) {
|
||||
WARN_ON_ONCE(!static_cpu_has(X86_FEATURE_NRIPS));
|
||||
WARN_ON_ONCE(!cpu_feature_enabled(X86_FEATURE_NRIPS));
|
||||
svm->next_rip = svm->vmcb->control.next_rip;
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu, u8 vector)
|
||||
if (nrips)
|
||||
kvm_rip_write(vcpu, old_rip);
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_NRIPS))
|
||||
if (cpu_feature_enabled(X86_FEATURE_NRIPS))
|
||||
svm->vmcb->control.next_rip = rip;
|
||||
|
||||
return 0;
|
||||
@@ -583,7 +583,7 @@ static int svm_enable_virtualization_cpu(void)
|
||||
|
||||
wrmsrq(MSR_VM_HSAVE_PA, sd->save_area_pa);
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_TSCRATEMSR)) {
|
||||
/*
|
||||
* Set the default value, even if we don't use TSC scaling
|
||||
* to avoid having stale value in the msr
|
||||
@@ -1967,7 +1967,7 @@ static int pf_interception(struct kvm_vcpu *vcpu)
|
||||
u64 error_code = svm->vmcb->control.exit_info_1;
|
||||
|
||||
return kvm_handle_page_fault(vcpu, error_code, fault_address,
|
||||
static_cpu_has(X86_FEATURE_DECODEASSISTS) ?
|
||||
cpu_feature_enabled(X86_FEATURE_DECODEASSISTS) ?
|
||||
svm->vmcb->control.insn_bytes : NULL,
|
||||
svm->vmcb->control.insn_len);
|
||||
}
|
||||
@@ -2027,7 +2027,7 @@ static int npf_interception(struct kvm_vcpu *vcpu)
|
||||
|
||||
trace_kvm_page_fault(vcpu, gpa, error_code);
|
||||
rc = kvm_mmu_page_fault(vcpu, gpa, error_code,
|
||||
static_cpu_has(X86_FEATURE_DECODEASSISTS) ?
|
||||
cpu_feature_enabled(X86_FEATURE_DECODEASSISTS) ?
|
||||
svm->vmcb->control.insn_bytes : NULL,
|
||||
svm->vmcb->control.insn_len);
|
||||
|
||||
@@ -2533,7 +2533,7 @@ static int iret_interception(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int invlpg_interception(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_DECODEASSISTS))
|
||||
return kvm_emulate_instruction(vcpu, 0);
|
||||
|
||||
kvm_mmu_invlpg(vcpu, to_svm(vcpu)->vmcb->control.exit_info_1);
|
||||
@@ -2581,7 +2581,7 @@ static int cr_interception(struct kvm_vcpu *vcpu)
|
||||
unsigned long val;
|
||||
int err;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_DECODEASSISTS))
|
||||
return emulate_on_interception(vcpu);
|
||||
|
||||
if (unlikely((svm->vmcb->control.exit_info_1 & CR_VALID) == 0))
|
||||
@@ -4190,7 +4190,7 @@ static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
|
||||
* unconditionally does a TLB flush on both nested VM-Enter and nested
|
||||
* VM-Exit (via kvm_mmu_reset_context()).
|
||||
*/
|
||||
if (static_cpu_has(X86_FEATURE_FLUSHBYASID))
|
||||
if (cpu_feature_enabled(X86_FEATURE_FLUSHBYASID))
|
||||
svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
|
||||
else
|
||||
svm->current_vmcb->asid_generation--;
|
||||
@@ -4567,12 +4567,12 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
|
||||
* is no need to worry about the conditional branch over the wrmsr
|
||||
* being speculatively taken.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_V_SPEC_CTRL))
|
||||
x86_spec_ctrl_set_guest(svm->virt_spec_ctrl);
|
||||
|
||||
svm_vcpu_enter_exit(vcpu, enter_flags);
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_V_SPEC_CTRL))
|
||||
x86_spec_ctrl_restore_host(svm->virt_spec_ctrl);
|
||||
|
||||
/* SEV-ES guests must use the CR write traps to track CR registers. */
|
||||
@@ -4949,7 +4949,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
|
||||
}
|
||||
|
||||
/* TODO: Advertise NRIPS to guest hypervisor unconditionally */
|
||||
if (static_cpu_has(X86_FEATURE_NRIPS))
|
||||
if (cpu_feature_enabled(X86_FEATURE_NRIPS))
|
||||
vmcb->control.next_rip = info->next_rip;
|
||||
vmcb->control.exit_code = icpt_info.exit_code;
|
||||
vmexit = nested_svm_exit_handled(svm);
|
||||
|
||||
@@ -419,7 +419,7 @@ static noinstr void vmx_l1d_flush(struct kvm_vcpu *vcpu)
|
||||
|
||||
vcpu->stat.l1d_flush++;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_FLUSH_L1D)) {
|
||||
native_wrmsrq(MSR_IA32_FLUSH_CMD, L1D_FLUSH);
|
||||
return;
|
||||
}
|
||||
@@ -1802,7 +1802,7 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu)
|
||||
* (namely Hyper-V) don't set it due to it being undefined behavior,
|
||||
* i.e. we end up advancing IP with some random value.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_HYPERVISOR) ||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR) ||
|
||||
exit_reason.basic != EXIT_REASON_EPT_MISCONFIG) {
|
||||
instr_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
|
||||
|
||||
@@ -8793,7 +8793,7 @@ __init int vmx_hardware_setup(void)
|
||||
* caches properly. This also requires honoring guest PAT, and is forced
|
||||
* independent of the quirk in vmx_ignore_guest_pat().
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_SELFSNOOP))
|
||||
kvm_caps.supported_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT;
|
||||
|
||||
kvm_caps.inapplicable_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT;
|
||||
|
||||
+3
-3
@@ -1761,7 +1761,7 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
if ((efer ^ old_efer) & KVM_MMU_EFER_ROLE_BITS)
|
||||
kvm_mmu_reset_context(vcpu);
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_XSAVES) &&
|
||||
if (!cpu_feature_enabled(X86_FEATURE_XSAVES) &&
|
||||
(efer & EFER_SVME))
|
||||
kvm_hv_xsaves_xsavec_maybe_warn(vcpu);
|
||||
|
||||
@@ -3178,7 +3178,7 @@ static void kvm_update_masterclock(struct kvm *kvm)
|
||||
*/
|
||||
static unsigned long get_cpu_tsc_khz(void)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_CONSTANT_TSC))
|
||||
if (cpu_feature_enabled(X86_FEATURE_CONSTANT_TSC))
|
||||
return tsc_khz;
|
||||
else
|
||||
return __this_cpu_read(cpu_tsc_khz);
|
||||
@@ -3195,7 +3195,7 @@ static void __get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
|
||||
|
||||
data->flags = 0;
|
||||
if (ka->use_master_clock &&
|
||||
(static_cpu_has(X86_FEATURE_CONSTANT_TSC) || __this_cpu_read(cpu_tsc_khz))) {
|
||||
(cpu_feature_enabled(X86_FEATURE_CONSTANT_TSC) || __this_cpu_read(cpu_tsc_khz))) {
|
||||
#ifdef CONFIG_X86_64
|
||||
struct timespec64 ts;
|
||||
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ static void kvm_xen_start_timer(struct kvm_vcpu *vcpu, u64 guest_abs,
|
||||
struct pvclock_vcpu_time_info hv_clock;
|
||||
uint64_t host_tsc, guest_tsc;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_CONSTANT_TSC) ||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_CONSTANT_TSC) ||
|
||||
!vcpu->kvm->arch.use_master_clock)
|
||||
break;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne
|
||||
instrument_memcpy_after(dst, src, len, ret);
|
||||
return ret;
|
||||
}
|
||||
if (static_cpu_has(X86_FEATURE_ERMS)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ERMS)) {
|
||||
instrument_memcpy_before(dst, src, len);
|
||||
ret = copy_mc_enhanced_fast_string(dst, src, len);
|
||||
instrument_memcpy_after(dst, src, len, ret);
|
||||
@@ -93,7 +93,7 @@ unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, un
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_ERMS)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ERMS)) {
|
||||
instrument_copy_to_user(dst, src, len);
|
||||
__uaccess_begin();
|
||||
ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len);
|
||||
|
||||
+31
-18
@@ -1,33 +1,36 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/types.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpuid/leaf_types.h>
|
||||
|
||||
static unsigned int __x86_family(unsigned int base_fam, unsigned int ext_fam)
|
||||
{
|
||||
if (base_fam == 0xf)
|
||||
base_fam += ext_fam;
|
||||
|
||||
return base_fam;
|
||||
}
|
||||
|
||||
static unsigned int __x86_model(unsigned int family, unsigned int base_model,
|
||||
unsigned int ext_model)
|
||||
{
|
||||
if (family >= 0x6)
|
||||
base_model |= ext_model << 4;
|
||||
|
||||
return base_model;
|
||||
}
|
||||
|
||||
unsigned int x86_family(unsigned int sig)
|
||||
{
|
||||
unsigned int x86;
|
||||
|
||||
x86 = (sig >> 8) & 0xf;
|
||||
|
||||
if (x86 == 0xf)
|
||||
x86 += (sig >> 20) & 0xff;
|
||||
|
||||
return x86;
|
||||
return __x86_family((sig >> 8) & 0xf, (sig >> 20) & 0xff);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(x86_family);
|
||||
|
||||
unsigned int x86_model(unsigned int sig)
|
||||
{
|
||||
unsigned int fam, model;
|
||||
|
||||
fam = x86_family(sig);
|
||||
|
||||
model = (sig >> 4) & 0xf;
|
||||
|
||||
if (fam >= 0x6)
|
||||
model += ((sig >> 16) & 0xf) << 4;
|
||||
|
||||
return model;
|
||||
return __x86_model(x86_family(sig), (sig >> 4) & 0xf, (sig >> 16) & 0xf);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(x86_model);
|
||||
|
||||
@@ -36,3 +39,13 @@ unsigned int x86_stepping(unsigned int sig)
|
||||
return sig & 0xf;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(x86_stepping);
|
||||
|
||||
unsigned int cpuid_family(const struct leaf_0x1_0 *l)
|
||||
{
|
||||
return __x86_family(l->base_family_id, l->ext_family);
|
||||
}
|
||||
|
||||
unsigned int cpuid_model(const struct leaf_0x1_0 *l)
|
||||
{
|
||||
return __x86_model(cpuid_family(l), l->base_model, l->ext_model);
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ unsigned long copy_from_user_inatomic_nontemporal(void *to, const void __user *f
|
||||
if (!user_access_begin(from, n))
|
||||
return n;
|
||||
#ifdef CONFIG_X86_INTEL_USERCOPY
|
||||
if (n > 64 && static_cpu_has(X86_FEATURE_XMM2))
|
||||
if (n > 64 && cpu_feature_enabled(X86_FEATURE_XMM2))
|
||||
n = __copy_user_intel_nocache(to, from, n);
|
||||
else
|
||||
__copy_user(to, from, n);
|
||||
|
||||
@@ -194,7 +194,7 @@ static bool ex_handler_msr(const struct exception_table_entry *fixup,
|
||||
static bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
if (static_cpu_has(X86_BUG_NULL_SEG))
|
||||
if (cpu_feature_enabled(X86_BUG_NULL_SEG))
|
||||
asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS));
|
||||
asm volatile ("mov %0, %%fs" : : "rm" (0));
|
||||
return ex_handler_default(fixup, regs);
|
||||
|
||||
@@ -449,7 +449,7 @@ static void cpa_flush(struct cpa_data *cpa, int cache)
|
||||
|
||||
BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
|
||||
|
||||
if (cache && !static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
if (cache && !cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
cpa_flush_all(cache);
|
||||
goto collapse_large_pages;
|
||||
}
|
||||
|
||||
+7
-7
@@ -162,7 +162,7 @@ static inline unsigned long build_cr3(pgd_t *pgd, u16 asid, unsigned long lam)
|
||||
{
|
||||
unsigned long cr3 = __sme_pa(pgd) | lam;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_PCID)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_PCID)) {
|
||||
cr3 |= kern_pcid(asid);
|
||||
} else {
|
||||
VM_WARN_ON_ONCE(asid != 0);
|
||||
@@ -197,7 +197,7 @@ static void clear_asid_other(void)
|
||||
* This is only expected to be set if we have disabled
|
||||
* kernel _PAGE_GLOBAL pages.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_PTI)) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI)) {
|
||||
WARN_ON_ONCE(1);
|
||||
return;
|
||||
}
|
||||
@@ -227,7 +227,7 @@ static struct new_asid choose_new_asid(struct mm_struct *next, u64 next_tlb_gen)
|
||||
struct new_asid ns;
|
||||
u16 asid;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_PCID)) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PCID)) {
|
||||
ns.asid = 0;
|
||||
ns.need_flush = 1;
|
||||
return ns;
|
||||
@@ -555,7 +555,7 @@ static inline void invalidate_user_asid(u16 asid)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PCID))
|
||||
return;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
__set_bit(kern_pcid(asid),
|
||||
@@ -1558,7 +1558,7 @@ void flush_tlb_one_kernel(unsigned long addr)
|
||||
*/
|
||||
flush_tlb_one_user(addr);
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -1582,7 +1582,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr)
|
||||
invlpg(addr);
|
||||
|
||||
/* If PTI is off there is no user PCID and nothing to flush. */
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
|
||||
@@ -1611,7 +1611,7 @@ STATIC_NOPV void native_flush_tlb_global(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_INVPCID)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_INVPCID)) {
|
||||
/*
|
||||
* Using INVPCID is considerably faster than a pair of writes
|
||||
* to CR4 sandwiched inside an IRQ flag save/restore.
|
||||
|
||||
@@ -307,7 +307,7 @@ static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev
|
||||
const struct pci_dev *pcie_to_pci_bridge;
|
||||
|
||||
// Detect any type of AMD Ryzen machine.
|
||||
if (!static_cpu_has(X86_FEATURE_ZEN))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ZEN))
|
||||
return false;
|
||||
|
||||
// Detect VIA VT6306/6307/6308.
|
||||
|
||||
@@ -88,7 +88,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
|
||||
{
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
drm_cache_flush_clflush(pages, num_pages);
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ void
|
||||
drm_clflush_sg(struct sg_table *st)
|
||||
{
|
||||
#if defined(CONFIG_X86)
|
||||
if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
struct sg_page_iter sg_iter;
|
||||
|
||||
mb(); /*CLFLUSH is ordered only by using memory barriers*/
|
||||
@@ -157,7 +157,7 @@ void
|
||||
drm_clflush_virt_range(void *addr, unsigned long length)
|
||||
{
|
||||
#if defined(CONFIG_X86)
|
||||
if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
const int size = boot_cpu_data.x86_clflush_size;
|
||||
void *end = addr + length;
|
||||
|
||||
@@ -332,7 +332,7 @@ void drm_memcpy_init_early(void)
|
||||
* Some hypervisors (e.g. KVM) don't support VEX-prefix instructions
|
||||
* emulation. So don't enable movntdqa in hypervisor guest.
|
||||
*/
|
||||
if (static_cpu_has(X86_FEATURE_XMM4_1) &&
|
||||
if (cpu_feature_enabled(X86_FEATURE_XMM4_1) &&
|
||||
!boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||
static_branch_enable(&has_movntdqa);
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ int i915_gem_object_prepare_read(struct drm_i915_gem_object *obj,
|
||||
return ret;
|
||||
|
||||
if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ ||
|
||||
!static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
!cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
ret = i915_gem_object_set_to_cpu_domain(obj, false);
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
@@ -732,7 +732,7 @@ int i915_gem_object_prepare_write(struct drm_i915_gem_object *obj,
|
||||
return ret;
|
||||
|
||||
if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE ||
|
||||
!static_cpu_has(X86_FEATURE_CLFLUSH)) {
|
||||
!cpu_feature_enabled(X86_FEATURE_CLFLUSH)) {
|
||||
ret = i915_gem_object_set_to_cpu_domain(obj, true);
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
|
||||
@@ -166,7 +166,7 @@ void i915_memcpy_init_early(struct drm_i915_private *dev_priv)
|
||||
* Some hypervisors (e.g. KVM) don't support VEX-prefix instructions
|
||||
* emulation. So don't enable movntdqa in hypervisor guest.
|
||||
*/
|
||||
if (static_cpu_has(X86_FEATURE_XMM4_1) &&
|
||||
if (cpu_feature_enabled(X86_FEATURE_XMM4_1) &&
|
||||
!boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||
static_branch_enable(&has_movntdqa);
|
||||
}
|
||||
|
||||
@@ -1227,7 +1227,7 @@ static void memcpy_flushcache_optimized(void *dest, void *source, size_t size)
|
||||
* advantage seen with cache-allocating-writes plus flushing.
|
||||
*/
|
||||
#ifdef CONFIG_X86
|
||||
if (static_cpu_has(X86_FEATURE_CLFLUSHOPT) &&
|
||||
if (cpu_feature_enabled(X86_FEATURE_CLFLUSHOPT) &&
|
||||
likely(boot_cpu_data.x86_clflush_size == 64) &&
|
||||
likely(size >= 768)) {
|
||||
do {
|
||||
|
||||
@@ -558,7 +558,7 @@ static bool disable_dynamic_sst_features(void)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_HWP))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_HWP))
|
||||
return true;
|
||||
|
||||
rdmsrq(MSR_PM_ENABLE, value);
|
||||
|
||||
@@ -928,7 +928,7 @@ void intel_thermal_interrupt(void)
|
||||
{
|
||||
__u64 msr_val;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_HWP))
|
||||
if (cpu_feature_enabled(X86_FEATURE_HWP))
|
||||
notify_hwp_interrupt();
|
||||
|
||||
rdmsrq(MSR_IA32_THERM_STATUS, msr_val);
|
||||
|
||||
Reference in New Issue
Block a user