[PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely delivery of _PSD

Penny Zheng posted 15 patches 11 months, 1 week ago
There is a newer version of this series
[PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely delivery of _PSD
Posted by Penny Zheng 11 months, 1 week ago
_PSD(P-State Dependency) provides performance control, no matter legacy
P-state or CPPC, logical processor dependency information to OSPM.

In order to re-use it for CPPC, this commit extracts the delivery of _PSD info
from set_px_pminfo() and wrap it with a new sub-hypercall XEN_PM_PSD.

Signed-off-by: Penny Zheng <Penny.Zheng@amd.com>
---
v2 -> v3:
- new commit
---
 xen/arch/x86/acpi/cpufreq/acpi.c          |   2 +-
 xen/arch/x86/acpi/cpufreq/powernow.c      |   2 +-
 xen/arch/x86/platform_hypercall.c         |  11 ++
 xen/arch/x86/x86_64/cpufreq.c             |   2 +
 xen/drivers/cpufreq/cpufreq.c             | 122 +++++++++++++---------
 xen/drivers/cpufreq/cpufreq_ondemand.c    |   2 +-
 xen/include/acpi/cpufreq/processor_perf.h |   4 +-
 xen/include/public/platform.h             |  17 +--
 xen/include/xen/pmstat.h                  |   2 +
 xen/include/xlat.lst                      |   2 +-
 10 files changed, 103 insertions(+), 63 deletions(-)

diff --git a/xen/arch/x86/acpi/cpufreq/acpi.c b/xen/arch/x86/acpi/cpufreq/acpi.c
index 0c25376406..0cf94ab2d6 100644
--- a/xen/arch/x86/acpi/cpufreq/acpi.c
+++ b/xen/arch/x86/acpi/cpufreq/acpi.c
@@ -393,7 +393,7 @@ static int cf_check acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
     data->acpi_data = &processor_pminfo[cpu]->perf;
 
     perf = data->acpi_data;
-    policy->shared_type = perf->shared_type;
+    policy->shared_type = processor_pminfo[cpu]->shared_type;
 
     switch (perf->control_register.space_id) {
     case ACPI_ADR_SPACE_SYSTEM_IO:
diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c
index 69364e1855..69ad403fc1 100644
--- a/xen/arch/x86/acpi/cpufreq/powernow.c
+++ b/xen/arch/x86/acpi/cpufreq/powernow.c
@@ -218,7 +218,7 @@ static int cf_check powernow_cpufreq_cpu_init(struct cpufreq_policy *policy)
     data->acpi_data = &processor_pminfo[cpu]->perf;
 
     info.perf = perf = data->acpi_data;
-    policy->shared_type = perf->shared_type;
+    policy->shared_type = processor_pminfo[cpu]->shared_type;
 
     if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
         policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 90abd3197f..b0d98b5840 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -571,6 +571,17 @@ ret_t do_platform_op(
             ret = acpi_set_pdc_bits(op->u.set_pminfo.id, pdc);
             break;
         }
+        case XEN_PM_PSD:
+            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+            {
+                ret = -EOPNOTSUPP;
+                break;
+            }
+
+            ret = set_psd_pminfo(op->u.set_pminfo.id,
+                                 op->u.set_pminfo.shared_type,
+                                 &op->u.set_pminfo.u.domain_info);
+            break;
 
         default:
             ret = -EINVAL;
diff --git a/xen/arch/x86/x86_64/cpufreq.c b/xen/arch/x86/x86_64/cpufreq.c
index e4f3d5b436..d1b93b8eef 100644
--- a/xen/arch/x86/x86_64/cpufreq.c
+++ b/xen/arch/x86/x86_64/cpufreq.c
@@ -28,6 +28,8 @@
 
 CHECK_processor_px;
 
+CHECK_psd_package;
+
 DEFINE_XEN_GUEST_HANDLE(compat_processor_px_t);
 
 int compat_set_px_pminfo(uint32_t acpi_id,
diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index 4a103c6de9..638476ca15 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -36,6 +36,7 @@
 #include <xen/string.h>
 #include <xen/timer.h>
 #include <xen/xmalloc.h>
+#include <xen/xvmalloc.h>
 #include <xen/guest_access.h>
 #include <xen/domain.h>
 #include <xen/cpu.h>
@@ -201,15 +202,15 @@ int cpufreq_add_cpu(unsigned int cpu)
     struct cpufreq_dom *cpufreq_dom = NULL;
     struct cpufreq_policy new_policy;
     struct cpufreq_policy *policy;
-    struct processor_performance *perf;
+    struct processor_pminfo *pmpt;
 
     /* to protect the case when Px was not controlled by xen */
     if ( !processor_pminfo[cpu] || !cpu_online(cpu) )
         return -EINVAL;
 
-    perf = &processor_pminfo[cpu]->perf;
+    pmpt = processor_pminfo[cpu];
 
-    if ( !(perf->init & XEN_PX_INIT) )
+    if ( !(pmpt->perf.init & XEN_PX_INIT) )
         return -EINVAL;
 
     if (!cpufreq_driver.init)
@@ -218,10 +219,10 @@ int cpufreq_add_cpu(unsigned int cpu)
     if (per_cpu(cpufreq_cpu_policy, cpu))
         return 0;
 
-    if (perf->shared_type == CPUFREQ_SHARED_TYPE_HW)
+    if (pmpt->shared_type == CPUFREQ_SHARED_TYPE_HW)
         hw_all = 1;
 
-    dom = perf->domain_info.domain;
+    dom = pmpt->domain_info.domain;
 
     list_for_each(pos, &cpufreq_dom_list_head) {
         cpufreq_dom = list_entry(pos, struct cpufreq_dom, node);
@@ -246,18 +247,18 @@ int cpufreq_add_cpu(unsigned int cpu)
     } else {
         /* domain sanity check under whatever coordination type */
         firstcpu = cpumask_first(cpufreq_dom->map);
-        if ((perf->domain_info.coord_type !=
-            processor_pminfo[firstcpu]->perf.domain_info.coord_type) ||
-            (perf->domain_info.num_processors !=
-            processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
+        if ((pmpt->domain_info.coord_type !=
+            processor_pminfo[firstcpu]->domain_info.coord_type) ||
+            (pmpt->domain_info.num_processors !=
+            processor_pminfo[firstcpu]->domain_info.num_processors)) {
 
             printk(KERN_WARNING "cpufreq fail to add CPU%d:"
                    "incorrect _PSD(%"PRIu64":%"PRIu64"), "
                    "expect(%"PRIu64"/%"PRIu64")\n",
-                   cpu, perf->domain_info.coord_type,
-                   perf->domain_info.num_processors,
-                   processor_pminfo[firstcpu]->perf.domain_info.coord_type,
-                   processor_pminfo[firstcpu]->perf.domain_info.num_processors
+                   cpu, pmpt->domain_info.coord_type,
+                   pmpt->domain_info.num_processors,
+                   processor_pminfo[firstcpu]->domain_info.coord_type,
+                   processor_pminfo[firstcpu]->domain_info.num_processors
                 );
             return -EINVAL;
         }
@@ -305,7 +306,7 @@ int cpufreq_add_cpu(unsigned int cpu)
         goto err1;
 
     if (hw_all || (cpumask_weight(cpufreq_dom->map) ==
-                   perf->domain_info.num_processors)) {
+                   pmpt->domain_info.num_processors)) {
         memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
         policy->governor = NULL;
 
@@ -359,24 +360,24 @@ int cpufreq_del_cpu(unsigned int cpu)
     struct list_head *pos;
     struct cpufreq_dom *cpufreq_dom = NULL;
     struct cpufreq_policy *policy;
-    struct processor_performance *perf;
+    struct processor_pminfo *pmpt;
 
     /* to protect the case when Px was not controlled by xen */
     if ( !processor_pminfo[cpu] || !cpu_online(cpu) )
         return -EINVAL;
 
-    perf = &processor_pminfo[cpu]->perf;
+    pmpt = processor_pminfo[cpu];
 
-    if ( !(perf->init & XEN_PX_INIT) )
+    if ( !(pmpt->perf.init & XEN_PX_INIT) )
         return -EINVAL;
 
     if (!per_cpu(cpufreq_cpu_policy, cpu))
         return 0;
 
-    if (perf->shared_type == CPUFREQ_SHARED_TYPE_HW)
+    if (pmpt->shared_type == CPUFREQ_SHARED_TYPE_HW)
         hw_all = 1;
 
-    dom = perf->domain_info.domain;
+    dom = pmpt->domain_info.domain;
     policy = per_cpu(cpufreq_cpu_policy, cpu);
 
     list_for_each(pos, &cpufreq_dom_list_head) {
@@ -393,7 +394,7 @@ int cpufreq_del_cpu(unsigned int cpu)
     /* for HW_ALL, stop gov for each core of the _PSD domain */
     /* for SW_ALL & SW_ANY, stop gov for the 1st core of the _PSD domain */
     if (hw_all || (cpumask_weight(cpufreq_dom->map) ==
-                   perf->domain_info.num_processors))
+                   pmpt->domain_info.num_processors))
         __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
 
     cpufreq_statistic_exit(cpu);
@@ -475,19 +476,13 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf)
                acpi_id, cpu);
 
     pmpt = processor_pminfo[cpu];
+    /* Must already allocated in set_psd_pminfo */
     if ( !pmpt )
     {
-        pmpt = xzalloc(struct processor_pminfo);
-        if ( !pmpt )
-        {
-            ret = -ENOMEM;
-            goto out;
-        }
-        processor_pminfo[cpu] = pmpt;
+        ret = -EINVAL;
+        goto out;
     }
     pxpt = &pmpt->perf;
-    pmpt->acpi_id = acpi_id;
-    pmpt->id = cpu;
 
     if ( perf->flags & XEN_PX_PCT )
     {
@@ -537,25 +532,6 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf)
             print_PSS(pxpt->states,pxpt->state_count);
     }
 
-    if ( perf->flags & XEN_PX_PSD )
-    {
-        /* check domain coordination */
-        if ( perf->shared_type != CPUFREQ_SHARED_TYPE_ALL &&
-             perf->shared_type != CPUFREQ_SHARED_TYPE_ANY &&
-             perf->shared_type != CPUFREQ_SHARED_TYPE_HW )
-        {
-            ret = -EINVAL;
-            goto out;
-        }
-
-        pxpt->shared_type = perf->shared_type;
-        memcpy(&pxpt->domain_info, &perf->domain_info,
-               sizeof(struct xen_psd_package));
-
-        if ( cpufreq_verbose )
-            print_PSD(&pxpt->domain_info);
-    }
-
     if ( perf->flags & XEN_PX_PPC )
     {
         pxpt->platform_limit = perf->platform_limit;
@@ -570,7 +546,7 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf)
         }
     }
 
-    if ( perf->flags == ( XEN_PX_PCT | XEN_PX_PSS | XEN_PX_PSD | XEN_PX_PPC ) )
+    if ( perf->flags == ( XEN_PX_PCT | XEN_PX_PSS | XEN_PX_PPC ) )
     {
         pxpt->init = XEN_PX_INIT;
 
@@ -582,6 +558,54 @@ out:
     return ret;
 }
 
+int set_psd_pminfo(uint32_t acpi_id, uint32_t shared_type,
+                   const struct xen_psd_package *psd_data)
+{
+    int ret = 0, cpuid;
+    struct processor_pminfo *pm_info;
+
+    cpuid = get_cpu_id(acpi_id);
+    if ( cpuid < 0 || !psd_data )
+    {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* check domain coordination */
+    if ( shared_type != CPUFREQ_SHARED_TYPE_ALL &&
+         shared_type != CPUFREQ_SHARED_TYPE_ANY &&
+         shared_type != CPUFREQ_SHARED_TYPE_HW )
+    {
+        ret = -EINVAL;
+        goto out;
+    }
+    if ( cpufreq_verbose )
+        printk("Set CPU acpi_id(%d) cpuid(%d) _PSD State info:\n",
+               acpi_id, cpuid);
+
+    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->shared_type = shared_type;
+    pm_info->domain_info = *psd_data;
+
+    if ( cpufreq_verbose )
+        print_PSD(&pm_info->domain_info);
+
+ out:
+    return ret;
+}
+
 static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy)
 {
     if (usr_max_freq)
diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
index 06cfc88d30..5b23daaac1 100644
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
@@ -194,7 +194,7 @@ static void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
 
     set_timer(&per_cpu(dbs_timer, dbs_info->cpu), NOW()+dbs_tuners_ins.sampling_rate);
 
-    if ( processor_pminfo[dbs_info->cpu]->perf.shared_type
+    if ( processor_pminfo[dbs_info->cpu]->shared_type
             == CPUFREQ_SHARED_TYPE_HW )
     {
         dbs_info->stoppable = 1;
diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h
index 301104e16f..19f5de6b08 100644
--- a/xen/include/acpi/cpufreq/processor_perf.h
+++ b/xen/include/acpi/cpufreq/processor_perf.h
@@ -27,8 +27,6 @@ struct processor_performance {
     struct xen_pct_register status_register;
     uint32_t state_count;
     struct xen_processor_px *states;
-    struct xen_psd_package domain_info;
-    uint32_t shared_type;
 
     uint32_t init;
 };
@@ -36,6 +34,8 @@ struct processor_performance {
 struct processor_pminfo {
     uint32_t acpi_id;
     uint32_t id;
+    struct xen_psd_package domain_info;
+    uint32_t shared_type;
     struct processor_performance    perf;
 };
 
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index 2725b8d104..f5c50380cb 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -363,12 +363,12 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
 #define XEN_PM_PX   1
 #define XEN_PM_TX   2
 #define XEN_PM_PDC  3
+#define XEN_PM_PSD  4
 
 /* Px sub info type */
 #define XEN_PX_PCT   1
 #define XEN_PX_PSS   2
 #define XEN_PX_PPC   4
-#define XEN_PX_PSD   8
 
 struct xen_power_register {
     uint32_t     space_id;
@@ -439,6 +439,7 @@ struct xen_psd_package {
     uint64_t coord_type;
     uint64_t num_processors;
 };
+typedef struct xen_psd_package xen_psd_package_t;
 
 struct xen_processor_performance {
     uint32_t flags;     /* flag for Px sub info type */
@@ -447,12 +448,6 @@ struct xen_processor_performance {
     struct xen_pct_register status_register;
     uint32_t state_count;     /* total available performance states */
     XEN_GUEST_HANDLE(xen_processor_px_t) states;
-    struct xen_psd_package domain_info;
-    /* Coordination type of this processor */
-#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed coordination */
-#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs should set freq */
-#define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be set from any dependent CPU */
-    uint32_t shared_type;
 };
 typedef struct xen_processor_performance xen_processor_performance_t;
 DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
@@ -463,9 +458,15 @@ struct xenpf_set_processor_pminfo {
     uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX} */
     union {
         struct xen_processor_power          power;/* Cx: _CST/_CSD */
-        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD */
+        xen_psd_package_t                   domain_info; /* _PSD */
+        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/ */
         XEN_GUEST_HANDLE(uint32)            pdc;  /* _PDC */
     } u;
+    /* Coordination type of this processor */
+#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed coordination */
+#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs should set freq */
+#define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be set from any dependent CPU */
+    uint32_t shared_type;
 };
 typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
diff --git a/xen/include/xen/pmstat.h b/xen/include/xen/pmstat.h
index 8350403e95..fd02316ce9 100644
--- a/xen/include/xen/pmstat.h
+++ b/xen/include/xen/pmstat.h
@@ -5,6 +5,8 @@
 #include <public/platform.h> /* for struct xen_processor_power */
 #include <public/sysctl.h>   /* for struct pm_cx_stat */
 
+int set_psd_pminfo(uint32_t acpi_id, uint32_t shared_type,
+                   const struct xen_psd_package *psd_data);
 int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf);
 long set_cx_pminfo(uint32_t acpi_id, struct xen_processor_power *power);
 
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 3c7b6c6830..0d964fe0ce 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -168,7 +168,7 @@
 !	processor_performance		platform.h
 !	processor_power			platform.h
 ?	processor_px			platform.h
-!	psd_package			platform.h
+?	psd_package			platform.h
 ?	xenpf_enter_acpi_sleep		platform.h
 ?	xenpf_pcpu_version		platform.h
 ?	xenpf_pcpuinfo			platform.h
-- 
2.34.1
Re: [PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely delivery of _PSD
Posted by Jan Beulich 10 months, 3 weeks ago
On 06.03.2025 09:39, Penny Zheng wrote:
> --- a/xen/include/public/platform.h
> +++ b/xen/include/public/platform.h
> @@ -363,12 +363,12 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
>  #define XEN_PM_PX   1
>  #define XEN_PM_TX   2
>  #define XEN_PM_PDC  3
> +#define XEN_PM_PSD  4
>  
>  /* Px sub info type */
>  #define XEN_PX_PCT   1
>  #define XEN_PX_PSS   2
>  #define XEN_PX_PPC   4
> -#define XEN_PX_PSD   8
>  
>  struct xen_power_register {
>      uint32_t     space_id;
> @@ -439,6 +439,7 @@ struct xen_psd_package {
>      uint64_t coord_type;
>      uint64_t num_processors;
>  };
> +typedef struct xen_psd_package xen_psd_package_t;
>  
>  struct xen_processor_performance {
>      uint32_t flags;     /* flag for Px sub info type */
> @@ -447,12 +448,6 @@ struct xen_processor_performance {
>      struct xen_pct_register status_register;
>      uint32_t state_count;     /* total available performance states */
>      XEN_GUEST_HANDLE(xen_processor_px_t) states;
> -    struct xen_psd_package domain_info;
> -    /* Coordination type of this processor */
> -#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed coordination */
> -#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs should set freq */
> -#define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be set from any dependent CPU */
> -    uint32_t shared_type;
>  };
>  typedef struct xen_processor_performance xen_processor_performance_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
> @@ -463,9 +458,15 @@ struct xenpf_set_processor_pminfo {
>      uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX} */
>      union {
>          struct xen_processor_power          power;/* Cx: _CST/_CSD */
> -        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD */
> +        xen_psd_package_t                   domain_info; /* _PSD */
> +        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/ */
>          XEN_GUEST_HANDLE(uint32)            pdc;  /* _PDC */
>      } u;
> +    /* Coordination type of this processor */
> +#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed coordination */
> +#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs should set freq */
> +#define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be set from any dependent CPU */
> +    uint32_t shared_type;
>  };
>  typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
>  DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);

With this change to stable hypercall structures, how is an older Dom0 kernel
going to be able to properly upload the necessary data? IOW: No, you can't
alter existing stable hypercall structures like this.

Jan
RE: [PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely delivery of _PSD
Posted by Penny, Zheng 10 months, 2 weeks ago
[Public]

Hi,

> -----Original Message-----
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Monday, March 24, 2025 10:09 PM
> To: Penny, Zheng <penny.zheng@amd.com>
> Cc: Huang, Ray <Ray.Huang@amd.com>; Andrew Cooper
> <andrew.cooper3@citrix.com>; Roger Pau Monné <roger.pau@citrix.com>;
> Anthony PERARD <anthony.perard@vates.tech>; Orzel, Michal
> <Michal.Orzel@amd.com>; Julien Grall <julien@xen.org>; Stefano Stabellini
> <sstabellini@kernel.org>; xen-devel@lists.xenproject.org
> Subject: Re: [PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely
> delivery of _PSD
>
> On 06.03.2025 09:39, Penny Zheng wrote:
> > --- a/xen/include/public/platform.h
> > +++ b/xen/include/public/platform.h
> > @@ -363,12 +363,12 @@
> DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
> >  #define XEN_PM_PX   1
> >  #define XEN_PM_TX   2
> >  #define XEN_PM_PDC  3
> > +#define XEN_PM_PSD  4
> >
> >  /* Px sub info type */
> >  #define XEN_PX_PCT   1
> >  #define XEN_PX_PSS   2
> >  #define XEN_PX_PPC   4
> > -#define XEN_PX_PSD   8
> >
> >  struct xen_power_register {
> >      uint32_t     space_id;
> > @@ -439,6 +439,7 @@ struct xen_psd_package {
> >      uint64_t coord_type;
> >      uint64_t num_processors;
> >  };
> > +typedef struct xen_psd_package xen_psd_package_t;
> >
> >  struct xen_processor_performance {
> >      uint32_t flags;     /* flag for Px sub info type */
> > @@ -447,12 +448,6 @@ struct xen_processor_performance {
> >      struct xen_pct_register status_register;
> >      uint32_t state_count;     /* total available performance states */
> >      XEN_GUEST_HANDLE(xen_processor_px_t) states;
> > -    struct xen_psd_package domain_info;
> > -    /* Coordination type of this processor */
> > -#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed
> coordination */
> > -#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs
> should
> > set freq */ -#define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be set
> from any dependent CPU */
> > -    uint32_t shared_type;
> >  };
> >  typedef struct xen_processor_performance xen_processor_performance_t;
> > DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
> > @@ -463,9 +458,15 @@ struct xenpf_set_processor_pminfo {
> >      uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX} */
> >      union {
> >          struct xen_processor_power          power;/* Cx: _CST/_CSD */
> > -        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD
> */
> > +        xen_psd_package_t                   domain_info; /* _PSD */
> > +        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/ */
> >          XEN_GUEST_HANDLE(uint32)            pdc;  /* _PDC */
> >      } u;
> > +    /* Coordination type of this processor */
> > +#define XEN_CPUPERF_SHARED_TYPE_HW   1 /* HW does needed
> coordination */
> > +#define XEN_CPUPERF_SHARED_TYPE_ALL  2 /* All dependent CPUs
> should
> > +set freq */ #define XEN_CPUPERF_SHARED_TYPE_ANY  3 /* Freq can be
> set from any dependent CPU */
> > +    uint32_t shared_type;
> >  };
> >  typedef struct xenpf_set_processor_pminfo
> > xenpf_set_processor_pminfo_t;
> > DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
>
> With this change to stable hypercall structures, how is an older Dom0 kernel going
> to be able to properly upload the necessary data? IOW: No, you can't alter existing
> stable hypercall structures like this.
>

Understood.
I'll expand the newly added "struct xen_processor_cppc", to let it also include _PSD info
and shared type
```
+struct xen_processor_cppc {
+    uint8_t flags; /* flag for CPPC sub info type */
+    /*
+     * Subset _CPC fields useful for CPPC-compatible cpufreq
+     * driver's initialization
+     */
+    struct {
+        uint32_t highest_perf;
+        uint32_t nominal_perf;
+        uint32_t lowest_nonlinear_perf;
+        uint32_t lowest_perf;
+        uint32_t lowest_mhz;
+        uint32_t nominal_mhz;
+    } cpc;
+    struct xen_psd_package domain_info; /* _PSD */
+    /* Coordination type of this processor */
+    uint32_t shared_type;
+};
+typedef struct xen_processor_cppc xen_processor_cppc_t;
```

> Jan