:p
atchew
Login
Integrate this leaf with CPU policy handling, to leverage the host policy when feature bits need evaluating. 1: cpu-policy: move invocation of recalculate_misc() 2: cpu-policy: define bits of leaf 6 3: include: de-assemblify cpuid.h 4: replace APERRMPERF synthetic feature bit 5: rename ARAT feature flag 6: Intel: use host CPU policy for ARAT checking 7: cpufreq: use host CPU policy for Turbo checking 8: cpufreq: use host CPU policy in HWP driver Jan
The function is about guest exposure of features / leaves. There's no need for it to be applied on the host policy. In fact doing so gets in the way of using the host policy in certain places. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -XXX,XX +XXX,XX @@ static void __init calculate_host_policy x86_cpu_featureset_to_policy(boot_cpu_data.x86_capability, p); recalculate_xstate(p); - recalculate_misc(p); /* When vPMU is disabled, drop it from the host policy. */ if ( vpmu_mode == XENPMU_MODE_OFF ) @@ -XXX,XX +XXX,XX @@ static void __init calculate_pv_max_poli unsigned int i; *p = host_cpu_policy; + recalculate_misc(p); guest_common_max_leaves(p); @@ -XXX,XX +XXX,XX @@ static void __init calculate_hvm_max_pol const uint32_t *mask; *p = host_cpu_policy; + recalculate_misc(p); guest_common_max_leaves(p);
... as far as we presently use them in the codebase. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- Or should we make both parts proper featureset elements? At least APERFMPERF could likely be made visible to guests (in principle). --- a/xen/include/xen/lib/x86/cpu-policy.h +++ b/xen/include/xen/lib/x86/cpu-policy.h @@ -XXX,XX +XXX,XX @@ struct cpu_policy uint64_t :64, :64; /* Leaf 0x3 - PSN. */ uint64_t :64, :64; /* Leaf 0x4 - Structured Cache. */ uint64_t :64, :64; /* Leaf 0x5 - MONITOR. */ - uint64_t :64, :64; /* Leaf 0x6 - Therm/Perf. */ + + /* Leaf 0x6 - Therm/Perf. */ + struct { + uint32_t /* a */:1, + turbo:1, + arat:1, + :4, + hwp:1, + hwp_notification:1, + hwp_activity_window:1, + hwp_epp:1, + hwp_plr:1, + :1, + hdc:1, + :2, + hwp_peci:1, + :2, + hw_feedback:1, + :12; + uint32_t /* b */:32; + uint32_t /* c */ aperfmperf:1, + :31; + uint32_t /* d */:32; + } pm; + uint64_t :64, :64; /* Leaf 0x7 - Structured Features. */ uint64_t :64, :64; /* Leaf 0x8 - rsvd */ uint64_t :64, :64; /* Leaf 0x9 - DCA */
There's nothing in that header which assembly files would need. Arrange for cpufeatureset.h to be included directly by cpufeature.h in that case, allowing respective guarding to be dropped Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ #include <xen/const.h> #include <xen/macros.h> +#ifndef __ASSEMBLY__ #include <asm/cpuid.h> +#else +#include <asm/cpufeatureset.h> +#endif #define cpufeat_word(idx) ((idx) / 32) #define cpufeat_bit(idx) ((idx) % 32) --- a/xen/arch/x86/include/asm/cpuid.h +++ b/xen/arch/x86/include/asm/cpuid.h @@ -XXX,XX +XXX,XX @@ #include <asm/cpufeatureset.h> -#ifndef __ASSEMBLY__ #include <xen/types.h> #include <xen/kernel.h> #include <xen/percpu.h> @@ -XXX,XX +XXX,XX @@ struct cpuid_leaf; void guest_cpuid(const struct vcpu *v, uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res); -#endif /* __ASSEMBLY__ */ #endif /* !__X86_CPUID_H__ */ /*
Use the respective host CPU policy bit instead. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -XXX,XX +XXX,XX @@ static void generic_identify(struct cpui if ( cpu_has(c, X86_FEATURE_CLFLUSH) ) c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; - if ( (c->cpuid_level >= CPUID_PM_LEAF) && - (cpuid_ecx(CPUID_PM_LEAF) & CPUID6_ECX_APERFMPERF_CAPABILITY) ) - __set_bit(X86_FEATURE_APERFMPERF, c->x86_capability); - /* AMD-defined flags: level 0x80000001 */ if (c->extended_cpuid_level >= 0x80000001) cpuid(0x80000001, &tmp, &tmp, --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ #include <xen/macros.h> #ifndef __ASSEMBLY__ +#include <asm/cpu-policy.h> #include <asm/cpuid.h> +#include <xen/lib/x86/cpu-policy.h> #else #include <asm/cpufeatureset.h> #endif @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define CPUID6_EAX_HDC BIT(13, U) #define CPUID6_EAX_HWP_PECI BIT(16, U) #define CPUID6_EAX_HW_FEEDBACK BIT(19, U) -#define CPUID6_ECX_APERFMPERF_CAPABILITY BIT(0, U) /* CPUID level 0x00000001.edx */ #define cpu_has_fpu 1 @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_fma4 boot_cpu_has(X86_FEATURE_FMA4) #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) +/* CPUID level 0x00000006.ecx */ +#define cpu_has_aperfmperf host_cpu_policy.basic.pm.aperfmperf + /* CPUID level 0x0000000D:1.eax */ #define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT) #define cpu_has_xsavec boot_cpu_has(X86_FEATURE_XSAVEC) @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned /* Synthesized. */ #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) #define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING) -#define cpu_has_aperfmperf boot_cpu_has(X86_FEATURE_APERFMPERF) #define cpu_has_xen_lbr boot_cpu_has(X86_FEATURE_XEN_LBR) #define cpu_has_xen_shstk (IS_ENABLED(CONFIG_XEN_SHSTK) && \ boot_cpu_has(X86_FEATURE_XEN_SHSTK)) --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -XXX,XX +XXX,XX @@ XEN_CPUFEATURE(TSC_RELIABLE, X86_SY XEN_CPUFEATURE(XTOPOLOGY, X86_SYNTH( 5)) /* cpu topology enum extensions */ XEN_CPUFEATURE(CPUID_FAULTING, X86_SYNTH( 6)) /* cpuid faulting */ XEN_CPUFEATURE(XEN_FRED, X86_SYNTH( 7)) /* Xen uses FRED */ -XEN_CPUFEATURE(APERFMPERF, X86_SYNTH( 8)) /* APERFMPERF */ +/* Bit 8 unused */ XEN_CPUFEATURE(MFENCE_RDTSC, X86_SYNTH( 9)) /* MFENCE synchronizes RDTSC */ XEN_CPUFEATURE(XEN_SMEP, X86_SYNTH(10)) /* SMEP gets used by Xen itself */ XEN_CPUFEATURE(XEN_SMAP, X86_SYNTH(11)) /* SMAP gets used by Xen itself */
Add a XEN infix, to properly distinguish it from the CPUID feature flag (leaf 6 EAX bit 2). Signed-off-by: Jan Beulich <jbeulich@suse.com> --- Question is whether we still need opt_arat (and the command line option), or whether we could go directly from the CPUID bit (overriding it to on for older AMD [and Hygon?] CPUs). Or whether to have opt_arat affect the (host) CPU policy directly. --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -XXX,XX +XXX,XX @@ void (*__read_mostly lapic_timer_on)(voi bool lapic_timer_init(void) { - if ( boot_cpu_has(X86_FEATURE_ARAT) ) + if ( boot_cpu_has(X86_FEATURE_XEN_ARAT) ) { lapic_timer_off = lapic_timer_nop; lapic_timer_on = lapic_timer_nop; @@ -XXX,XX +XXX,XX @@ static void amd_cpuidle_init(struct acpi if ( !vendor_override ) { - if ( !boot_cpu_has(X86_FEATURE_ARAT) ) + if ( !boot_cpu_has(X86_FEATURE_XEN_ARAT) ) hpet_broadcast_init(); if ( !lapic_timer_init() ) --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_amd(struct cpu * running in deep C states. */ if ( opt_arat && c->x86 > 0x11 ) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); /* * Prior to Family 0x14, perf counters are not reset during warm reboot. --- a/xen/arch/x86/cpu/hygon.c +++ b/xen/arch/x86/cpu/hygon.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_hygon(struct c /* Hygon processors have APIC timer running in deep C states. */ if (opt_arat) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if (cpu_has(c, X86_FEATURE_EFRO)) { rdmsrl(MSR_K8_HWCR, value); --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_intel(struct c if ( opt_arat && ( c->cpuid_level >= 0x00000006 ) && ( cpuid_eax(0x00000006) & (1u<<2) ) ) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if ((opt_cpu_info && !(c->apicid & (c->x86_num_siblings - 1))) || c == &boot_cpu_data ) --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -XXX,XX +XXX,XX @@ static int __init mwait_idle_probe(void) icpu = id->driver_data; cpuidle_state_table = icpu->state_table; - if (boot_cpu_has(X86_FEATURE_ARAT)) + if (boot_cpu_has(X86_FEATURE_XEN_ARAT)) lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; pr_debug(PREFIX "v" MWAIT_IDLE_VERSION " model %#x\n", @@ -XXX,XX +XXX,XX @@ int __init mwait_idle_init(struct notifi return -ENODEV; err = mwait_idle_probe(); - if (!err && !boot_cpu_has(X86_FEATURE_ARAT)) { + if (!err && !boot_cpu_has(X86_FEATURE_XEN_ARAT)) { hpet_broadcast_init(); if (xen_cpuidle < 0 && !hpet_broadcast_is_available()) err = -ENODEV; --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -XXX,XX +XXX,XX @@ /* Synthetic features */ XEN_CPUFEATURE(CONSTANT_TSC, X86_SYNTH( 0)) /* TSC ticks at a constant rate */ XEN_CPUFEATURE(NONSTOP_TSC, X86_SYNTH( 1)) /* TSC does not stop in C states */ -XEN_CPUFEATURE(ARAT, X86_SYNTH( 2)) /* Always running APIC timer */ +XEN_CPUFEATURE(XEN_ARAT, X86_SYNTH( 2)) /* Xen may utilize always running APIC timer */ XEN_CPUFEATURE(ARCH_PERFMON, X86_SYNTH( 3)) /* Intel Architectural PerfMon */ XEN_CPUFEATURE(TSC_RELIABLE, X86_SYNTH( 4)) /* TSC is known to be reliable */ XEN_CPUFEATURE(XTOPOLOGY, X86_SYNTH( 5)) /* cpu topology enum extensions */ --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -XXX,XX +XXX,XX @@ static int _disable_pit_irq(bool init) * XXX dom0 may rely on RTC interrupt delivery, so only enable * hpet_broadcast if FSB mode available or if force_hpet_broadcast. */ - if ( cpuidle_using_deep_cstate() && !boot_cpu_has(X86_FEATURE_ARAT) ) + if ( cpuidle_using_deep_cstate() && !boot_cpu_has(X86_FEATURE_XEN_ARAT) ) { init ? hpet_broadcast_init() : hpet_broadcast_resume(); if ( !hpet_broadcast_is_available() )
There's no need to invoke CPUID yet another time. However, as the host CPU policy is set up only shortly after init_intel() ran on the BSP, defer the logic to a pre-SMP initcall. This can't be (a new) one in cpu/intel.c though, as that's linked after acpi/cpu_idle.c (which is where we already need the feature set). Since opt_arat is local to the cpu/ subtree, introduce a new Intel-specific helper to hold the code needed. Further, as we assume symmetry anyway, use setup_force_cpu_cap() and hence limit the checking to the boot CPU. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- The need to move where cpu_has_arat is checked would go away if we did away with opt_arat (as mentioned in the previous patch), and hence could use cpu_has_arat directly where right now XEN_ARAT is checked. --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -XXX,XX +XXX,XX @@ static int __init cf_check cpuidle_presm { void *cpu = (void *)(long)smp_processor_id(); + if ( boot_cpu_data.vendor == X86_VENDOR_INTEL ) + intel_init_arat(); + if ( !xen_cpuidle ) return 0; --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_intel(struct c __set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability); __set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability); } - if ( opt_arat && - ( c->cpuid_level >= 0x00000006 ) && - ( cpuid_eax(0x00000006) & (1u<<2) ) ) - __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if ((opt_cpu_info && !(c->apicid & (c->x86_num_siblings - 1))) || c == &boot_cpu_data ) @@ -XXX,XX +XXX,XX @@ const struct cpu_dev __initconst_cf_clob .c_early_init = early_init_intel, .c_init = init_intel, }; + +void __init intel_init_arat(void) +{ + if ( opt_arat && cpu_has_arat ) + setup_force_cpu_cap(X86_FEATURE_XEN_ARAT); +} --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_fma4 boot_cpu_has(X86_FEATURE_FMA4) #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) +/* CPUID level 0x00000006.eax */ +#define cpu_has_arat host_cpu_policy.basic.pm.arat + /* CPUID level 0x00000006.ecx */ #define cpu_has_aperfmperf host_cpu_policy.basic.pm.aperfmperf --- a/xen/arch/x86/include/asm/processor.h +++ b/xen/arch/x86/include/asm/processor.h @@ -XXX,XX +XXX,XX @@ extern void setup_force_cpu_cap(unsigned extern bool is_forced_cpu_cap(unsigned int cap); extern void print_cpu_info(unsigned int cpu); extern void init_intel_cacheinfo(struct cpuinfo_x86 *c); +extern void intel_init_arat(void); #define cpu_to_core(_cpu) (cpu_data[_cpu].cpu_core_id) #define cpu_to_socket(_cpu) (cpu_data[_cpu].phys_proc_id)
There's no need to invoke CPUID yet another time - we assume symmetry anyway. With symmetry assumed, logging per-CPU also isn't very useful. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/acpi/cpufreq/acpi.c +++ b/xen/arch/x86/acpi/cpufreq/acpi.c @@ -XXX,XX +XXX,XX @@ static unsigned int cf_check get_cur_fre void intel_feature_detect(struct cpufreq_policy *policy) { - unsigned int eax; - - eax = cpuid_eax(6); - if (eax & 0x2) { + if ( cpu_has_turbo ) + { policy->turbo = CPUFREQ_TURBO_ENABLED; - if (cpufreq_verbose) - printk(XENLOG_INFO "CPU%u: Turbo Mode detected and enabled\n", - smp_processor_id()); + if ( cpufreq_verbose ) + printk_once(XENLOG_INFO "Turbo Mode detected and enabled\n"); } } --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) /* CPUID level 0x00000006.eax */ +#define cpu_has_turbo host_cpu_policy.basic.pm.turbo #define cpu_has_arat host_cpu_policy.basic.pm.arat /* CPUID level 0x00000006.ecx */
There's no need to invoke CPUID yet another time. This way two of the static booleans can also go away. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/acpi/cpufreq/hwp.c +++ b/xen/arch/x86/acpi/cpufreq/hwp.c @@ -XXX,XX +XXX,XX @@ static bool __ro_after_init hwp_in_use; -static bool __ro_after_init feature_hwp_notification; -static bool __ro_after_init feature_hwp_activity_window; - static bool __read_mostly feature_hdc; static bool __ro_after_init opt_cpufreq_hdc = true; @@ -XXX,XX +XXX,XX @@ bool hwp_active(void) static bool __init hwp_available(void) { - unsigned int eax; - if ( boot_cpu_data.cpuid_level < CPUID_PM_LEAF ) { hwp_verbose("cpuid_level (%#x) lacks HWP support\n", @@ -XXX,XX +XXX,XX @@ static bool __init hwp_available(void) return false; } - eax = cpuid_eax(CPUID_PM_LEAF); - hwp_verbose("%d notify: %d act-window: %d energy-perf: %d pkg-level: %d peci: %d\n", - !!(eax & CPUID6_EAX_HWP), - !!(eax & CPUID6_EAX_HWP_NOTIFICATION), - !!(eax & CPUID6_EAX_HWP_ACTIVITY_WINDOW), - !!(eax & CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE), - !!(eax & CPUID6_EAX_HWP_PACKAGE_LEVEL_REQUEST), - !!(eax & CPUID6_EAX_HWP_PECI)); + host_cpu_policy.basic.pm.hwp, + host_cpu_policy.basic.pm.hwp_notification, + host_cpu_policy.basic.pm.hwp_activity_window, + host_cpu_policy.basic.pm.hwp_epp, + host_cpu_policy.basic.pm.hwp_plr, + host_cpu_policy.basic.pm.hwp_peci); - if ( !(eax & CPUID6_EAX_HWP) ) + if ( !host_cpu_policy.basic.pm.hwp ) return false; - if ( !(eax & CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE) ) + if ( !host_cpu_policy.basic.pm.hwp_epp ) { hwp_verbose("disabled: No energy/performance preference available"); return false; } - feature_hwp_notification = eax & CPUID6_EAX_HWP_NOTIFICATION; - feature_hwp_activity_window = eax & CPUID6_EAX_HWP_ACTIVITY_WINDOW; - feature_hdc = eax & CPUID6_EAX_HDC; + feature_hdc = host_cpu_policy.basic.pm.hdc; hwp_verbose("Hardware Duty Cycling (HDC) %ssupported%s\n", feature_hdc ? "" : "not ", @@ -XXX,XX +XXX,XX @@ static bool __init hwp_available(void) : ""); hwp_verbose("HW_FEEDBACK %ssupported\n", - (eax & CPUID6_EAX_HW_FEEDBACK) ? "" : "not "); + host_cpu_policy.basic.pm.hw_feedback ? "" : "not "); hwp_in_use = true; @@ -XXX,XX +XXX,XX @@ static int cf_check hwp_cpufreq_verify(s { struct hwp_drv_data *data = per_cpu(hwp_drv_data, policy->cpu); - if ( !feature_hwp_activity_window && data->activity_window ) + if ( !host_cpu_policy.basic.pm.hwp_activity_window && + data->activity_window ) { hwp_verbose("HWP activity window not supported\n"); @@ -XXX,XX +XXX,XX @@ static int cf_check hwp_cpufreq_target(s hwp_req.max_perf = data->maximum; hwp_req.desired = data->desired; hwp_req.energy_perf = data->energy_perf; - if ( feature_hwp_activity_window ) + if ( host_cpu_policy.basic.pm.hwp_activity_window ) hwp_req.activity_window = data->activity_window; if ( hwp_req.raw == data->curr_req.raw ) @@ -XXX,XX +XXX,XX @@ static void cf_check hwp_init_msrs(void } /* Ensure we don't generate interrupts */ - if ( feature_hwp_notification ) + if ( host_cpu_policy.basic.pm.hwp_notification ) wrmsr_safe(MSR_HWP_INTERRUPT, 0); if ( !(val & PM_ENABLE_HWP_ENABLE) ) @@ -XXX,XX +XXX,XX @@ int get_hwp_para(unsigned int cpu, return -ENODATA; cppc_para->features = - (feature_hwp_activity_window ? XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW : 0); + (host_cpu_policy.basic.pm.hwp_activity_window + ? XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW : 0); cppc_para->lowest = data->hw.lowest; cppc_para->lowest_nonlinear = data->hw.most_efficient; cppc_para->nominal = data->hw.guaranteed; @@ -XXX,XX +XXX,XX @@ int set_hwp_para(struct cpufreq_policy * /* Clear out activity window if lacking HW supported. */ if ( (set_cppc->set_params & XEN_SYSCTL_CPPC_SET_ACT_WINDOW) && - !feature_hwp_activity_window ) + !host_cpu_policy.basic.pm.hwp_activity_window ) { set_cppc->set_params &= ~XEN_SYSCTL_CPPC_SET_ACT_WINDOW; cleared_act_window = true; --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned } #define CPUID_PM_LEAF 6 -#define CPUID6_EAX_HWP BIT(7, U) -#define CPUID6_EAX_HWP_NOTIFICATION BIT(8, U) -#define CPUID6_EAX_HWP_ACTIVITY_WINDOW BIT(9, U) -#define CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE BIT(10, U) -#define CPUID6_EAX_HWP_PACKAGE_LEVEL_REQUEST BIT(11, U) -#define CPUID6_EAX_HDC BIT(13, U) -#define CPUID6_EAX_HWP_PECI BIT(16, U) -#define CPUID6_EAX_HW_FEEDBACK BIT(19, U) /* CPUID level 0x00000001.edx */ #define cpu_has_fpu 1
Integrate this leaf with CPU policy handling, to leverage the host policy when feature bits need evaluating. 1: cpu-policy: define bits of leaf 6 2: replace APERRMPERF synthetic feature bit 3: rename ARAT feature flag 4: Intel: use host CPU policy for ARAT checking 5: cpufreq: use host CPU policy for Turbo checking 6: cpufreq: use host CPU policy in HWP driver Jan
... as far as we presently use them in the codebase. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- Or should we make both parts proper featureset elements? At least APERFMPERF could likely be made visible to guests (in principle). --- v3: Use SDM-conforming names. (Sorry Jason, had to drop you R-b once again.) v2: Use bool and unions. --- a/xen/include/xen/lib/x86/cpu-policy.h +++ b/xen/include/xen/lib/x86/cpu-policy.h @@ -XXX,XX +XXX,XX @@ struct cpu_policy uint64_t :64, :64; /* Leaf 0x3 - PSN. */ uint64_t :64, :64; /* Leaf 0x4 - Structured Cache. */ uint64_t :64, :64; /* Leaf 0x5 - MONITOR. */ - uint64_t :64, :64; /* Leaf 0x6 - Therm/Perf. */ + + /* Leaf 0x6 - Therm/Perf. */ + union { + uint32_t _6a; + struct { + bool :1, + turbo_boost:1, + arat:1, + :1, + :1, + :1, + :1, + hwp:1, + hwp_interrupt:1, + hwp_activity_window:1, + hwp_epp:1, + hwp_request_pkg:1, + :1, + hdc:1, + :1, + :1, + hwp_peci_override:1, + :1, + :1, + hw_feedback:1; + }; + }; + union { + uint32_t _6b; + }; + union { + uint32_t _6c; + struct { + bool hw_feedback_cap:1; + }; + }; + union { + uint32_t _6d; + }; + uint64_t :64, :64; /* Leaf 0x7 - Structured Features. */ uint64_t :64, :64; /* Leaf 0x8 - rsvd */ uint64_t :64, :64; /* Leaf 0x9 - DCA */
Use the respective host CPU policy bit instead. This has the (tolerable, as we generally assume symmetry anyway) effect of using the BSP's (unleveled) setting, rather than the result of leveling (as is done by identify_cpu() on boot_cpu_data, rendering the variable name somewhat misleading). Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> --- The leveling of boot_cpu_data is problematic anyway, as that way features can in principle disappear post-boot (as CPUs are being brought online; just that we don't think anymore that we really support physical CPU hotplug). --- v3: Re-base over naming changes. v2: Extend description. --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -XXX,XX +XXX,XX @@ unsigned int get_measured_perf(unsigned return 0; policy = per_cpu(cpufreq_cpu_policy, cpu); - if ( !policy || !cpu_has_aperfmperf ) + if ( !policy || !cpu_has_hw_feedback_cap ) return 0; switch (flag) --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -XXX,XX +XXX,XX @@ static void generic_identify(struct cpui if ( cpu_has(c, X86_FEATURE_CLFLUSH) ) c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; - if ( (c->cpuid_level >= CPUID_PM_LEAF) && - (cpuid_ecx(CPUID_PM_LEAF) & CPUID6_ECX_APERFMPERF_CAPABILITY) ) - __set_bit(X86_FEATURE_APERFMPERF, c->x86_capability); - /* AMD-defined flags: level 0x80000001 */ if (c->extended_cpuid_level >= 0x80000001) cpuid(0x80000001, &tmp, &tmp, --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ #include <xen/macros.h> #ifndef __ASSEMBLER__ +#include <asm/cpu-policy.h> #include <asm/cpuid.h> +#include <xen/lib/x86/cpu-policy.h> #else #include <asm/cpufeatureset.h> #endif @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define CPUID6_EAX_HDC BIT(13, U) #define CPUID6_EAX_HWP_PECI BIT(16, U) #define CPUID6_EAX_HW_FEEDBACK BIT(19, U) -#define CPUID6_ECX_APERFMPERF_CAPABILITY BIT(0, U) /* CPUID level 0x00000001.edx */ #define cpu_has_fpu 1 @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_fma4 boot_cpu_has(X86_FEATURE_FMA4) #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) +/* CPUID level 0x00000006.ecx */ +#define cpu_has_hw_feedback_cap host_cpu_policy.basic.hw_feedback_cap + /* CPUID level 0x0000000D:1.eax */ #define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT) #define cpu_has_xsavec boot_cpu_has(X86_FEATURE_XSAVEC) @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned /* Synthesized. */ #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) #define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING) -#define cpu_has_aperfmperf boot_cpu_has(X86_FEATURE_APERFMPERF) #define cpu_has_xen_lbr boot_cpu_has(X86_FEATURE_XEN_LBR) #define cpu_has_xen_shstk (IS_ENABLED(CONFIG_XEN_SHSTK) && \ boot_cpu_has(X86_FEATURE_XEN_SHSTK)) --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -XXX,XX +XXX,XX @@ XEN_CPUFEATURE(TSC_RELIABLE, X86_SY XEN_CPUFEATURE(XTOPOLOGY, X86_SYNTH( 5)) /* cpu topology enum extensions */ XEN_CPUFEATURE(CPUID_FAULTING, X86_SYNTH( 6)) /* cpuid faulting */ XEN_CPUFEATURE(XEN_FRED, X86_SYNTH( 7)) /* Xen uses FRED */ -XEN_CPUFEATURE(APERFMPERF, X86_SYNTH( 8)) /* APERFMPERF */ +/* Bit 8 unused */ XEN_CPUFEATURE(MFENCE_RDTSC, X86_SYNTH( 9)) /* MFENCE synchronizes RDTSC */ XEN_CPUFEATURE(XEN_SMEP, X86_SYNTH(10)) /* SMEP gets used by Xen itself */ XEN_CPUFEATURE(XEN_SMAP, X86_SYNTH(11)) /* SMAP gets used by Xen itself */
Add a XEN infix, to properly distinguish it from the CPUID feature flag (leaf 6 EAX bit 2). Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> --- Question is whether we still need opt_arat (and the command line option), or whether we could go directly from the CPUID bit (overriding it to 1 for older AMD [and Hygon?] CPUs). Or whether to have opt_arat affect the (host) CPU policy directly. --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -XXX,XX +XXX,XX @@ void (*__read_mostly lapic_timer_on)(voi bool lapic_timer_init(void) { - if ( boot_cpu_has(X86_FEATURE_ARAT) ) + if ( boot_cpu_has(X86_FEATURE_XEN_ARAT) ) { lapic_timer_off = lapic_timer_nop; lapic_timer_on = lapic_timer_nop; @@ -XXX,XX +XXX,XX @@ static void amd_cpuidle_init(struct acpi if ( !vendor_override ) { - if ( !boot_cpu_has(X86_FEATURE_ARAT) ) + if ( !boot_cpu_has(X86_FEATURE_XEN_ARAT) ) hpet_broadcast_init(); if ( !lapic_timer_init() ) --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_amd(struct cpu * running in deep C states. */ if ( opt_arat && c->x86 > 0x11 ) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); /* * Prior to Family 0x14, perf counters are not reset during warm reboot. --- a/xen/arch/x86/cpu/hygon.c +++ b/xen/arch/x86/cpu/hygon.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_hygon(struct c /* Hygon processors have APIC timer running in deep C states. */ if (opt_arat) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if (cpu_has(c, X86_FEATURE_EFRO)) { rdmsrl(MSR_K8_HWCR, value); --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_intel(struct c if ( opt_arat && ( c->cpuid_level >= 0x00000006 ) && ( cpuid_eax(0x00000006) & (1u<<2) ) ) - __set_bit(X86_FEATURE_ARAT, c->x86_capability); + __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if ((opt_cpu_info && !(c->apicid & (c->x86_num_siblings - 1))) || c == &boot_cpu_data ) --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -XXX,XX +XXX,XX @@ static int __init mwait_idle_probe(void) icpu = id->driver_data; cpuidle_state_table = icpu->state_table; - if (boot_cpu_has(X86_FEATURE_ARAT)) + if (boot_cpu_has(X86_FEATURE_XEN_ARAT)) lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; pr_debug(PREFIX "v" MWAIT_IDLE_VERSION " model %#x\n", @@ -XXX,XX +XXX,XX @@ int __init mwait_idle_init(struct notifi return -ENODEV; err = mwait_idle_probe(); - if (!err && !boot_cpu_has(X86_FEATURE_ARAT)) { + if (!err && !boot_cpu_has(X86_FEATURE_XEN_ARAT)) { hpet_broadcast_init(); if (xen_cpuidle < 0 && !hpet_broadcast_is_available()) err = -ENODEV; --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -XXX,XX +XXX,XX @@ /* Synthetic features */ XEN_CPUFEATURE(CONSTANT_TSC, X86_SYNTH( 0)) /* TSC ticks at a constant rate */ XEN_CPUFEATURE(NONSTOP_TSC, X86_SYNTH( 1)) /* TSC does not stop in C states */ -XEN_CPUFEATURE(ARAT, X86_SYNTH( 2)) /* Always running APIC timer */ +XEN_CPUFEATURE(XEN_ARAT, X86_SYNTH( 2)) /* Xen may utilize always running APIC timer */ XEN_CPUFEATURE(ARCH_PERFMON, X86_SYNTH( 3)) /* Intel Architectural PerfMon */ XEN_CPUFEATURE(TSC_RELIABLE, X86_SYNTH( 4)) /* TSC is known to be reliable */ XEN_CPUFEATURE(XTOPOLOGY, X86_SYNTH( 5)) /* cpu topology enum extensions */ --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -XXX,XX +XXX,XX @@ static int _disable_pit_irq(bool init) * XXX dom0 may rely on RTC interrupt delivery, so only enable * hpet_broadcast if FSB mode available or if force_hpet_broadcast. */ - if ( cpuidle_using_deep_cstate() && !boot_cpu_has(X86_FEATURE_ARAT) ) + if ( cpuidle_using_deep_cstate() && !boot_cpu_has(X86_FEATURE_XEN_ARAT) ) { init ? hpet_broadcast_init() : hpet_broadcast_resume(); if ( !hpet_broadcast_is_available() )
There's no need to invoke CPUID yet another time. However, as the host CPU policy is set up only shortly after init_intel() ran on the BSP, defer the logic to a pre-SMP initcall. This can't be (a new) one in cpu/intel.c though, as that's linked after acpi/cpu_idle.c (which is where we already need the feature set). Since opt_arat is local to the cpu/ subtree, introduce a new Intel-specific helper to hold the code needed. Further, as we assume symmetry anyway, use setup_force_cpu_cap() and hence limit the checking to the boot CPU. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> --- The need to move where cpu_has_arat is checked would go away if we did away with opt_arat (as mentioned in the previous patch), and hence could use cpu_has_arat directly where right now XEN_ARAT is checked. --- v3: Re-base over naming changes. --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -XXX,XX +XXX,XX @@ static int __init cf_check cpuidle_presm { void *cpu = (void *)(long)smp_processor_id(); + if ( boot_cpu_data.vendor == X86_VENDOR_INTEL ) + intel_init_arat(); + if ( !xen_cpuidle ) return 0; --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -XXX,XX +XXX,XX @@ static void cf_check init_intel(struct c __set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability); __set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability); } - if ( opt_arat && - ( c->cpuid_level >= 0x00000006 ) && - ( cpuid_eax(0x00000006) & (1u<<2) ) ) - __set_bit(X86_FEATURE_XEN_ARAT, c->x86_capability); if ((opt_cpu_info && !(c->apicid & (c->x86_num_siblings - 1))) || c == &boot_cpu_data ) @@ -XXX,XX +XXX,XX @@ const struct cpu_dev __initconst_cf_clob .c_early_init = early_init_intel, .c_init = init_intel, }; + +void __init intel_init_arat(void) +{ + if ( opt_arat && cpu_has_arat ) + setup_force_cpu_cap(X86_FEATURE_XEN_ARAT); +} --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_fma4 boot_cpu_has(X86_FEATURE_FMA4) #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) +/* CPUID level 0x00000006.eax */ +#define cpu_has_arat host_cpu_policy.basic.arat + /* CPUID level 0x00000006.ecx */ #define cpu_has_hw_feedback_cap host_cpu_policy.basic.hw_feedback_cap --- a/xen/arch/x86/include/asm/processor.h +++ b/xen/arch/x86/include/asm/processor.h @@ -XXX,XX +XXX,XX @@ extern void setup_force_cpu_cap(unsigned extern bool is_forced_cpu_cap(unsigned int cap); extern void print_cpu_info(unsigned int cpu); extern void init_intel_cacheinfo(struct cpuinfo_x86 *c); +extern void intel_init_arat(void); #define cpu_to_core(_cpu) (cpu_data[_cpu].cpu_core_id) #define cpu_to_socket(_cpu) (cpu_data[_cpu].phys_proc_id)
There's no need to invoke CPUID yet another time - we assume symmetry anyway. With symmetry assumed, logging per-CPU also isn't very useful. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> --- v3: Re-base over naming changes. --- a/xen/arch/x86/acpi/cpufreq/acpi.c +++ b/xen/arch/x86/acpi/cpufreq/acpi.c @@ -XXX,XX +XXX,XX @@ static unsigned int cf_check get_cur_fre void intel_feature_detect(struct cpufreq_policy *policy) { - unsigned int eax; - - eax = cpuid_eax(6); - if (eax & 0x2) { + if ( cpu_has_turbo_boost ) + { policy->turbo = CPUFREQ_TURBO_ENABLED; - if (cpufreq_verbose) - printk(XENLOG_INFO "CPU%u: Turbo Mode detected and enabled\n", - smp_processor_id()); + if ( cpufreq_verbose ) + printk_once(XENLOG_INFO "Turbo Mode detected and enabled\n"); } } --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned #define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM) /* CPUID level 0x00000006.eax */ +#define cpu_has_turbo_boost host_cpu_policy.basic.turbo_boost #define cpu_has_arat host_cpu_policy.basic.arat /* CPUID level 0x00000006.ecx */
There's no need to invoke CPUID yet another time. This way two of the static booleans can also go away. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- v3: Undo some line wrapping. Correct padding in asm/cpufeature.h. Re-base over naming changes. v2: Introduce cpu_has_*. --- a/xen/arch/x86/acpi/cpufreq/hwp.c +++ b/xen/arch/x86/acpi/cpufreq/hwp.c @@ -XXX,XX +XXX,XX @@ static bool __ro_after_init hwp_in_use; -static bool __ro_after_init feature_hwp_notification; -static bool __ro_after_init feature_hwp_activity_window; - static bool __read_mostly feature_hdc; static bool __ro_after_init opt_cpufreq_hdc = true; @@ -XXX,XX +XXX,XX @@ bool hwp_active(void) static bool __init hwp_available(void) { - unsigned int eax; - if ( boot_cpu_data.cpuid_level < CPUID_PM_LEAF ) { hwp_verbose("cpuid_level (%#x) lacks HWP support\n", @@ -XXX,XX +XXX,XX @@ static bool __init hwp_available(void) return false; } - eax = cpuid_eax(CPUID_PM_LEAF); - hwp_verbose("%d notify: %d act-window: %d energy-perf: %d pkg-level: %d peci: %d\n", - !!(eax & CPUID6_EAX_HWP), - !!(eax & CPUID6_EAX_HWP_NOTIFICATION), - !!(eax & CPUID6_EAX_HWP_ACTIVITY_WINDOW), - !!(eax & CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE), - !!(eax & CPUID6_EAX_HWP_PACKAGE_LEVEL_REQUEST), - !!(eax & CPUID6_EAX_HWP_PECI)); + cpu_has_hwp, cpu_has_hwp_interrupt, + cpu_has_hwp_activity_window, cpu_has_hwp_epp, + cpu_has_hwp_request_pkg, cpu_has_hwp_peci_override); - if ( !(eax & CPUID6_EAX_HWP) ) + if ( !cpu_has_hwp ) return false; - if ( !(eax & CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE) ) + if ( !cpu_has_hwp_epp ) { hwp_verbose("disabled: No energy/performance preference available"); return false; } - feature_hwp_notification = eax & CPUID6_EAX_HWP_NOTIFICATION; - feature_hwp_activity_window = eax & CPUID6_EAX_HWP_ACTIVITY_WINDOW; - feature_hdc = eax & CPUID6_EAX_HDC; + feature_hdc = cpu_has_hdc; hwp_verbose("Hardware Duty Cycling (HDC) %ssupported%s\n", feature_hdc ? "" : "not ", @@ -XXX,XX +XXX,XX @@ static bool __init hwp_available(void) : ""); hwp_verbose("HW_FEEDBACK %ssupported\n", - (eax & CPUID6_EAX_HW_FEEDBACK) ? "" : "not "); + cpu_has_hw_feedback ? "" : "not "); hwp_in_use = true; @@ -XXX,XX +XXX,XX @@ static int cf_check hwp_cpufreq_verify(s { struct hwp_drv_data *data = per_cpu(hwp_drv_data, policy->cpu); - if ( !feature_hwp_activity_window && data->activity_window ) + if ( !cpu_has_hwp_activity_window && data->activity_window ) { hwp_verbose("HWP activity window not supported\n"); @@ -XXX,XX +XXX,XX @@ static int cf_check hwp_cpufreq_target(s hwp_req.max_perf = data->maximum; hwp_req.desired = data->desired; hwp_req.energy_perf = data->energy_perf; - if ( feature_hwp_activity_window ) + if ( cpu_has_hwp_activity_window ) hwp_req.activity_window = data->activity_window; if ( hwp_req.raw == data->curr_req.raw ) @@ -XXX,XX +XXX,XX @@ static void cf_check hwp_init_msrs(void } /* Ensure we don't generate interrupts */ - if ( feature_hwp_notification ) + if ( cpu_has_hwp_interrupt ) wrmsr_safe(MSR_HWP_INTERRUPT, 0); if ( !(val & PM_ENABLE_HWP_ENABLE) ) @@ -XXX,XX +XXX,XX @@ int get_hwp_para(unsigned int cpu, return -ENODATA; cppc_para->features = - (feature_hwp_activity_window ? XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW : 0); + (cpu_has_hwp_activity_window ? XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW : 0); cppc_para->lowest = data->hw.lowest; cppc_para->lowest_nonlinear = data->hw.most_efficient; cppc_para->nominal = data->hw.guaranteed; @@ -XXX,XX +XXX,XX @@ int set_hwp_para(struct cpufreq_policy * /* Clear out activity window if lacking HW supported. */ if ( (set_cppc->set_params & XEN_SYSCTL_CPPC_SET_ACT_WINDOW) && - !feature_hwp_activity_window ) + !cpu_has_hwp_activity_window ) { set_cppc->set_params &= ~XEN_SYSCTL_CPPC_SET_ACT_WINDOW; cleared_act_window = true; --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned } #define CPUID_PM_LEAF 6 -#define CPUID6_EAX_HWP BIT(7, U) -#define CPUID6_EAX_HWP_NOTIFICATION BIT(8, U) -#define CPUID6_EAX_HWP_ACTIVITY_WINDOW BIT(9, U) -#define CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE BIT(10, U) -#define CPUID6_EAX_HWP_PACKAGE_LEVEL_REQUEST BIT(11, U) -#define CPUID6_EAX_HDC BIT(13, U) -#define CPUID6_EAX_HWP_PECI BIT(16, U) -#define CPUID6_EAX_HW_FEEDBACK BIT(19, U) /* CPUID level 0x00000001.edx */ #define cpu_has_fpu 1 @@ -XXX,XX +XXX,XX @@ static inline bool boot_cpu_has(unsigned /* CPUID level 0x00000006.eax */ #define cpu_has_turbo_boost host_cpu_policy.basic.turbo_boost #define cpu_has_arat host_cpu_policy.basic.arat +#define cpu_has_hwp host_cpu_policy.basic.hwp +#define cpu_has_hwp_interrupt host_cpu_policy.basic.hwp_interrupt +#define cpu_has_hwp_activity_window host_cpu_policy.basic.hwp_activity_window +#define cpu_has_hwp_epp host_cpu_policy.basic.hwp_epp +#define cpu_has_hwp_request_pkg host_cpu_policy.basic.hwp_request_pkg +#define cpu_has_hdc host_cpu_policy.basic.hdc +#define cpu_has_hwp_peci_override host_cpu_policy.basic.hwp_peci_override +#define cpu_has_hw_feedback host_cpu_policy.basic.hw_feedback /* CPUID level 0x00000006.ecx */ #define cpu_has_hw_feedback_cap host_cpu_policy.basic.hw_feedback_cap