On 28.08.2025 12:02, Penny Zheng wrote: > In order to provide backward compatibility with existing governors > that represent performance as frequency, like ondemand, the _CPC > table can optionally provide processor frequency range values, Lowest > frequency and Nominal frequency, to let OS use Lowest Frequency/ > Performance and Nominal Frequency/Performance as anchor points to > create linear mapping of CPPC performance to CPU frequency. > > As Xen is uncapable of parsing the ACPI dynamic table, we'd like to > introduce a new sub-hypercall "XEN_PM_CPPC" to propagate required CPPC > data from dom0 kernel to Xen. > In the according handler set_cppc_pminfo(), we do _CPC and _PSD > sanitization check, as both _PSD and _CPC info are necessary for correctly > initializing cpufreq cores in CPPC mode. > Users shall be warned that if we failed at this point, > no fallback scheme, like legacy P-state could be switched to. > > A new flag "XEN_CPPC_INIT" is also introduced for cpufreq core initialised in > CPPC mode. Then all .init flag checking shall be updated to > consider "XEN_CPPC_INIT" too. > > We want to bypass construction of px statistic info in > cpufreq_statistic_init() > for CPPC mode, while not bypassing cpufreq_statistic_lock initialization for a > good reason. The same check is unnecessary for cpufreq_statistic_exit(), > since it has already been covered by px statistic variable > "cpufreq_statistic_data" check > > Signed-off-by: Penny Zheng <penny.zh...@amd.com>
Acked-by: Jan Beulich <jbeul...@suse.com> with two cosmetic issues taken care of (which I'll do while committing): > @@ -693,6 +699,120 @@ int acpi_set_pdc_bits(unsigned int acpi_id, > XEN_GUEST_HANDLE(uint32) pdc) > return ret; > } > > +static void print_CPPC(const struct xen_processor_cppc *cppc_data) > +{ > + printk("\t_CPC: highest_perf=%u, lowest_perf=%u, " > + "nominal_perf=%u, lowest_nonlinear_perf=%u, " > + "nominal_mhz=%uMHz, lowest_mhz=%uMHz\n", > + cppc_data->cpc.highest_perf, cppc_data->cpc.lowest_perf, > + cppc_data->cpc.nominal_perf, cppc_data->cpc.lowest_nonlinear_perf, > + cppc_data->cpc.nominal_mhz, cppc_data->cpc.lowest_mhz); > +} > + > +int set_cppc_pminfo(unsigned int acpi_id, > + const struct xen_processor_cppc *cppc_data) > +{ > + int ret = 0, cpuid; > + struct processor_pminfo *pm_info; > + > + cpuid = get_cpu_id(acpi_id); > + if ( cpuid < 0 ) > + { > + ret = -EINVAL; > + goto out; > + } > + > + if ( cppc_data->pad[0] || cppc_data->pad[1] || cppc_data->pad[2] ) > + { > + ret = -EINVAL; > + goto out; > + } > + > + if ( cpufreq_verbose ) > + printk("Set CPU%d (ACPI ID %u) CPPC state info:\n", > + cpuid, acpi_id); > + > + pm_info = processor_pminfo[cpuid]; > + if ( !pm_info ) > + { > + pm_info = xvzalloc(struct processor_pminfo); > + if ( !pm_info ) > + { > + ret = -ENOMEM; > + goto out; > + } > + processor_pminfo[cpuid] = pm_info; > + } > + pm_info->acpi_id = acpi_id; > + pm_info->id = cpuid; > + pm_info->cppc_data = *cppc_data; > + > + if ( (cppc_data->flags & XEN_CPPC_PSD) && > + !check_psd_pminfo(cppc_data->shared_type) ) Nit: Indentation is off by 1. > + { > + ret = -EINVAL; > + goto out; Indentation is still wrong here. Jan