Rather than storing a pointer (and needing to keep all struct instances in memory post-init), and rather than (like the Linux counterpart has it) keeping individual variables, simply copy the respective structure instance. By implication, subsequent updates now need doing to the copy.
Signed-off-by: Jan Beulich <[email protected]> --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -107,14 +107,14 @@ struct idle_cpu { enum c1e_promotion c1e_promotion; }; -static const struct idle_cpu *__ro_after_init icpu; +static struct idle_cpu __ro_after_init icpu; -static const struct cpuidle_state { +struct cpuidle_state { char name[16]; unsigned int flags; unsigned int exit_latency; /* in US */ unsigned int target_residency; /* in US */ -} *__ro_after_init cpuidle_state_table; +}; #define CPUIDLE_FLAG_DISABLED 0x1 /* @@ -1097,7 +1097,7 @@ static void cf_check mwait_idle(void) * leave_mm() to avoid costly and often unnecessary wakeups * for flushing the user TLB's associated with the active mm. */ - if (cpuidle_state_table[].flags & CPUIDLE_FLAG_TLB_FLUSHED) + if (icpu.state_table[].flags & CPUIDLE_FLAG_TLB_FLUSHED) leave_mm(cpu); #endif @@ -1139,7 +1139,7 @@ static void cf_check auto_demotion_disab u64 msr_bits; rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); - msr_bits &= ~(icpu->auto_demotion_disable_flags); + msr_bits &= ~icpu.auto_demotion_disable_flags; wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); } @@ -1371,10 +1371,10 @@ static void __init ivt_idle_state_table_ /* 1 and 2 socket systems use default ivt_cstates */ break; case 2: case 3: - cpuidle_state_table = ivt_cstates_4s; + icpu.state_table = ivt_cstates_4s; break; default: - cpuidle_state_table = ivt_cstates_8s; + icpu.state_table = ivt_cstates_8s; break; } } @@ -1525,14 +1525,12 @@ static void __init adl_idle_state_table_ adl_l_cstates[1].flags |= CPUIDLE_FLAG_DISABLED; /* Disable C1E by clearing the "C1E promotion" bit. */ - idle_cpu_adl.c1e_promotion = C1E_PROMOTION_DISABLE; - idle_cpu_adl_l.c1e_promotion = C1E_PROMOTION_DISABLE; + icpu.c1e_promotion = C1E_PROMOTION_DISABLE; return; } /* Make sure C1E is enabled by default */ - idle_cpu_adl.c1e_promotion = C1E_PROMOTION_ENABLE; - idle_cpu_adl_l.c1e_promotion = C1E_PROMOTION_ENABLE; + icpu.c1e_promotion = C1E_PROMOTION_ENABLE; } /* @@ -1593,6 +1591,7 @@ static int __init mwait_idle_probe(void) { unsigned int eax, ebx, ecx; const struct x86_cpu_id *id; + const struct idle_cpu *idle_cpu; const char *str; if (boot_cpu_data.vendor != X86_VENDOR_INTEL) @@ -1627,8 +1626,8 @@ static int __init mwait_idle_probe(void) pr_debug(PREFIX "MWAIT substates: %#x\n", mwait_substates); - icpu = id->driver_data; - cpuidle_state_table = icpu->state_table; + idle_cpu = id->driver_data; + icpu = *idle_cpu; if (boot_cpu_has(X86_FEATURE_XEN_ARAT)) lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; @@ -1647,7 +1646,7 @@ static int __init mwait_idle_probe(void) const char *ss; do { - const struct cpuidle_state *state = icpu->state_table; + const struct cpuidle_state *state = idle_cpu->state_table; unsigned int bit = 1; ss = strchr(str, ','); @@ -1679,10 +1678,10 @@ static int __init mwait_idle_probe(void) static void mwait_idle_cpu_tweak(unsigned int cpu, bool bsp) { - if (icpu->auto_demotion_disable_flags) + if (icpu.auto_demotion_disable_flags) on_selected_cpus(cpumask_of(cpu), auto_demotion_disable, NULL, 1); - switch (icpu->c1e_promotion) { + switch (icpu.c1e_promotion) { case C1E_PROMOTION_DISABLE: on_selected_cpus(cpumask_of(cpu), c1e_promotion_disable, NULL, 1); break; @@ -1735,11 +1734,11 @@ static int cf_check mwait_idle_cpu_init( dev->count = 1; - for (cstate = 0; cpuidle_state_table[cstate].target_residency; ++cstate) { + for (cstate = 0; icpu.state_table[cstate].target_residency; ++cstate) { unsigned int num_substates, hint, state; struct acpi_processor_cx *cx; - hint = flg2MWAIT(cpuidle_state_table[cstate].flags); + hint = flg2MWAIT(icpu.state_table[cstate].flags); state = MWAIT_HINT2CSTATE(hint) + 1; if (state > max_cstate) { @@ -1755,10 +1754,10 @@ static int cf_check mwait_idle_cpu_init( continue; /* if state marked as disabled, skip it */ - if (cpuidle_state_table[cstate].flags & + if (icpu.state_table[cstate].flags & CPUIDLE_FLAG_DISABLED) { printk(XENLOG_DEBUG PREFIX "state %s is disabled\n", - cpuidle_state_table[cstate].name); + icpu.state_table[cstate].name); continue; } @@ -1776,15 +1775,15 @@ static int cf_check mwait_idle_cpu_init( cx->type = state; cx->address = hint; cx->entry_method = ACPI_CSTATE_EM_FFH; - cx->latency = cpuidle_state_table[cstate].exit_latency; + cx->latency = icpu.state_table[cstate].exit_latency; cx->target_residency = - cpuidle_state_table[cstate].target_residency; - if ((cpuidle_state_table[cstate].flags & + icpu.state_table[cstate].target_residency; + if ((icpu.state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) && /* cstate_restore_tsc() needs to be a no-op */ boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) cx->irq_enable_early = true; - if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IBRS) + if (icpu.state_table[cstate].flags & CPUIDLE_FLAG_IBRS) cx->ibrs_disable = true; dev->count++; @@ -1825,7 +1824,7 @@ int __init mwait_idle_init(struct notifi void mwait_idle_resume(void) { - if (!icpu) + if (!icpu.state_table) return; mwait_idle_cpu_tweak(smp_processor_id(), true);
