[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/idle: update to include further package/core residency MSRs



commit ca57e4c9b8cb02ac8ea0fb474219163fba12bf6f
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Mar 18 11:52:34 2014 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Mar 18 11:52:34 2014 +0100

    x86/idle: update to include further package/core residency MSRs
    
    With the number of these growing it becomes increasingly desirable to
    not repeatedly alter the sysctl interface to accommodate them. Replace
    the explicit listing of numbered states by arrays, unused fields of
    which will remain untouched by the hypercall.
    
    The adjusted sysctl interface at once fixes an unrelated shortcoming
    of the original one: The "nr" field, specifying the size of the
    "triggers" and "residencies" arrays, has to be an input (along with
    being an output), which the previous implementation didn't obey to.
    
    Note that the bouncing direction in the libxc interface at once gets
    corrected to OUT (was BOTH).
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
    Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 tools/libxc/xc_pm.c          |   50 ++++++++++++---------
 tools/libxc/xenctrl.h        |   13 ++---
 tools/misc/xenpm.c           |   95 ++++++++++++++++++++++++----------------
 xen/arch/x86/acpi/cpu_idle.c |  100 +++++++++++++++++++++++++++++++++---------
 xen/include/public/sysctl.h  |   13 ++---
 5 files changed, 175 insertions(+), 96 deletions(-)

diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index f7ac40c..e4e0fb9 100644
--- a/tools/libxc/xc_pm.c
+++ b/tools/libxc/xc_pm.c
@@ -123,45 +123,53 @@ int xc_pm_get_max_cx(xc_interface *xch, int cpuid, int 
*max_cx)
 int xc_pm_get_cxstat(xc_interface *xch, int cpuid, struct xc_cx_stat *cxpt)
 {
     DECLARE_SYSCTL;
-    DECLARE_NAMED_HYPERCALL_BOUNCE(triggers, cxpt->triggers, 0, 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
-    DECLARE_NAMED_HYPERCALL_BOUNCE(residencies, cxpt->residencies, 0, 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
-    int max_cx, ret;
+    DECLARE_NAMED_HYPERCALL_BOUNCE(triggers, cxpt->triggers,
+                                   cxpt->nr * sizeof(*cxpt->triggers),
+                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    DECLARE_NAMED_HYPERCALL_BOUNCE(residencies, cxpt->residencies,
+                                   cxpt->nr * sizeof(*cxpt->residencies),
+                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    DECLARE_NAMED_HYPERCALL_BOUNCE(pc, cxpt->pc,
+                                   cxpt->nr_pc * sizeof(*cxpt->pc),
+                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    DECLARE_NAMED_HYPERCALL_BOUNCE(cc, cxpt->cc,
+                                   cxpt->nr_cc * sizeof(*cxpt->cc),
+                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    int ret = -1;
 
-    if( !cxpt->triggers || !cxpt->residencies )
-        return -EINVAL;
-
-    if ( (ret = xc_pm_get_max_cx(xch, cpuid, &max_cx)) )
-        goto unlock_0;
-
-    HYPERCALL_BOUNCE_SET_SIZE(triggers, max_cx * sizeof(uint64_t));
-    HYPERCALL_BOUNCE_SET_SIZE(residencies, max_cx * sizeof(uint64_t));
-
-    ret = -1;
     if ( xc_hypercall_bounce_pre(xch, triggers) )
         goto unlock_0;
     if ( xc_hypercall_bounce_pre(xch, residencies) )
         goto unlock_1;
+    if ( xc_hypercall_bounce_pre(xch, pc) )
+        goto unlock_2;
+    if ( xc_hypercall_bounce_pre(xch, cc) )
+        goto unlock_3;
 
     sysctl.cmd = XEN_SYSCTL_get_pmstat;
     sysctl.u.get_pmstat.type = PMSTAT_get_cxstat;
     sysctl.u.get_pmstat.cpuid = cpuid;
+    sysctl.u.get_pmstat.u.getcx.nr = cxpt->nr;
+    sysctl.u.get_pmstat.u.getcx.nr_pc = cxpt->nr_pc;
+    sysctl.u.get_pmstat.u.getcx.nr_cc = cxpt->nr_cc;
     set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.triggers, triggers);
     set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.residencies, residencies);
+    set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.pc, pc);
+    set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.cc, cc);
 
     if ( (ret = xc_sysctl(xch, &sysctl)) )
-        goto unlock_2;
+        goto unlock_4;
 
     cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr;
     cxpt->last = sysctl.u.get_pmstat.u.getcx.last;
     cxpt->idle_time = sysctl.u.get_pmstat.u.getcx.idle_time;
-    cxpt->pc2 = sysctl.u.get_pmstat.u.getcx.pc2;
-    cxpt->pc3 = sysctl.u.get_pmstat.u.getcx.pc3;
-    cxpt->pc6 = sysctl.u.get_pmstat.u.getcx.pc6;
-    cxpt->pc7 = sysctl.u.get_pmstat.u.getcx.pc7;
-    cxpt->cc3 = sysctl.u.get_pmstat.u.getcx.cc3;
-    cxpt->cc6 = sysctl.u.get_pmstat.u.getcx.cc6;
-    cxpt->cc7 = sysctl.u.get_pmstat.u.getcx.cc7;
+    cxpt->nr_pc = sysctl.u.get_pmstat.u.getcx.nr_pc;
+    cxpt->nr_cc = sysctl.u.get_pmstat.u.getcx.nr_cc;
 
+unlock_4:
+    xc_hypercall_bounce_post(xch, cc);
+unlock_3:
+    xc_hypercall_bounce_post(xch, pc);
 unlock_2:
     xc_hypercall_bounce_post(xch, residencies);
 unlock_1:
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 13f816b..e3a32f2 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -1935,18 +1935,15 @@ int xc_pm_get_pxstat(xc_interface *xch, int cpuid, 
struct xc_px_stat *pxpt);
 int xc_pm_reset_pxstat(xc_interface *xch, int cpuid);
 
 struct xc_cx_stat {
-    uint32_t nr;    /* entry nr in triggers & residencies, including C0 */
+    uint32_t nr;           /* entry nr in triggers[]/residencies[], incl C0 */
     uint32_t last;         /* last Cx state */
     uint64_t idle_time;    /* idle time from boot */
     uint64_t *triggers;    /* Cx trigger counts */
     uint64_t *residencies; /* Cx residencies */
-    uint64_t pc2;
-    uint64_t pc3;
-    uint64_t pc6;
-    uint64_t pc7;
-    uint64_t cc3;
-    uint64_t cc6;
-    uint64_t cc7;
+    uint32_t nr_pc;        /* entry nr in pc[] */
+    uint32_t nr_cc;        /* entry nr in cc[] */
+    uint64_t *pc;          /* 1-biased indexing (i.e. excl C0) */
+    uint64_t *cc;          /* 1-biased indexing (i.e. excl C0) */
 };
 typedef struct xc_cx_stat xc_cx_stat_t;
 
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index 2e57f1f..e43924c 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -29,6 +29,9 @@
 #include <inttypes.h>
 #include <sys/time.h>
 
+#define MAX_PKG_RESIDENCIES 12
+#define MAX_CORE_RESIDENCIES 8
+
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 static xc_interface *xc_handle;
@@ -102,7 +105,7 @@ static void parse_cpuid_and_int(int argc, char *argv[],
 
 static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
 {
-    int i;
+    unsigned int i;
 
     printf("cpu id               : %d\n", cpuid);
     printf("total C-states       : %d\n", cxstat->nr);
@@ -115,17 +118,14 @@ static void print_cxstat(int cpuid, struct xc_cx_stat 
*cxstat)
         printf("                       residency  [%20"PRIu64" ms]\n",
                cxstat->residencies[i]/1000000UL);
     }
-    printf("pc2                  : [%20"PRIu64" ms]\n"
-           "pc3                  : [%20"PRIu64" ms]\n"
-           "pc6                  : [%20"PRIu64" ms]\n"
-           "pc7                  : [%20"PRIu64" ms]\n",
-            cxstat->pc2/1000000UL, cxstat->pc3/1000000UL,
-            cxstat->pc6/1000000UL, cxstat->pc7/1000000UL);
-    printf("cc3                  : [%20"PRIu64" ms]\n"
-           "cc6                  : [%20"PRIu64" ms]\n"
-           "cc7                  : [%20"PRIu64" ms]\n",
-            cxstat->cc3/1000000UL, cxstat->cc6/1000000UL,
-            cxstat->cc7/1000000UL);
+    for ( i = 0; i < MAX_PKG_RESIDENCIES && i < cxstat->nr_pc; ++i )
+        if ( cxstat->pc[i] )
+           printf("pc%d                  : [%20"PRIu64" ms]\n", i + 1,
+                  cxstat->pc[i] / 1000000UL);
+    for ( i = 0; i < MAX_CORE_RESIDENCIES && i < cxstat->nr_cc; ++i )
+        if ( cxstat->cc[i] )
+           printf("cc%d                  : [%20"PRIu64" ms]\n", i + 1,
+                  cxstat->cc[i] / 1000000UL);
     printf("\n");
 }
 
@@ -145,24 +145,36 @@ static int get_cxstat_by_cpuid(xc_interface *xc_handle, 
int cpuid, struct xc_cx_
     if ( !max_cx_num )
         return -ENODEV;
 
-    cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
-    if ( !cxstat->triggers )
-        return -ENOMEM;
-    cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
-    if ( !cxstat->residencies )
+    cxstat->triggers = calloc(max_cx_num, sizeof(*cxstat->triggers));
+    cxstat->residencies = calloc(max_cx_num, sizeof(*cxstat->residencies));
+    cxstat->pc = calloc(MAX_PKG_RESIDENCIES, sizeof(*cxstat->pc));
+    cxstat->cc = calloc(MAX_CORE_RESIDENCIES, sizeof(*cxstat->cc));
+    if ( !cxstat->triggers || !cxstat->residencies ||
+         !cxstat->pc || !cxstat->cc )
     {
+        free(cxstat->cc);
+        free(cxstat->pc);
+        free(cxstat->residencies);
         free(cxstat->triggers);
         return -ENOMEM;
     }
 
+    cxstat->nr = max_cx_num;
+    cxstat->nr_pc = MAX_PKG_RESIDENCIES;
+    cxstat->nr_cc = MAX_CORE_RESIDENCIES;
+
     ret = xc_pm_get_cxstat(xc_handle, cpuid, cxstat);
     if( ret )
     {
         ret = -errno;
         free(cxstat->triggers);
         free(cxstat->residencies);
+        free(cxstat->pc);
+        free(cxstat->cc);
         cxstat->triggers = NULL;
         cxstat->residencies = NULL;
+        cxstat->pc = NULL;
+        cxstat->cc = NULL;
     }
 
     return ret;
@@ -198,6 +210,8 @@ static int show_cxstat_by_cpuid(xc_interface *xc_handle, 
int cpuid)
 
     free(cxstatinfo.triggers);
     free(cxstatinfo.residencies);
+    free(cxstatinfo.pc);
+    free(cxstatinfo.cc);
     return 0;
 }
 
@@ -482,25 +496,26 @@ static void signal_int_handler(int signo)
             /* print out CC? and PC? */
             for ( i = 0; i < socket_nr; i++ )
             {
+                unsigned int n;
                 uint64_t res;
+
                 for ( j = 0; j <= info.max_cpu_index; j++ )
                 {
                     if ( cpu_to_socket[j] == socket_ids[i] )
                         break;
                 }
                 printf("\nSocket %d\n", socket_ids[i]);
-                res = cxstat_end[j].pc2 - cxstat_start[j].pc2;
-                printf("\tPC2\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL,
-                       100UL * res / (double)sum_cx[j]);
-                res = cxstat_end[j].pc3 - cxstat_start[j].pc3;
-                printf("\tPC3\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
-                       100UL * res / (double)sum_cx[j]);
-                res = cxstat_end[j].pc6 - cxstat_start[j].pc6;
-                printf("\tPC6\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
-                       100UL * res / (double)sum_cx[j]);
-                res = cxstat_end[j].pc7 - cxstat_start[j].pc7;
-                printf("\tPC7\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
-                       100UL * res / (double)sum_cx[j]);
+                for ( n = 0; n < MAX_PKG_RESIDENCIES; ++n )
+                {
+                    if ( n >= cxstat_end[j].nr_pc )
+                        continue;
+                    res = cxstat_end[j].pc[n];
+                    if ( n < cxstat_start[j].nr_pc )
+                        res -= cxstat_start[j].pc[n];
+                    printf("\tPC%u\t%"PRIu64" ms\t%.2f%%\n",
+                           n + 1, res / 1000000UL,
+                           100UL * res / (double)sum_cx[j]);
+                }
                 for ( k = 0; k < core_nr; k++ )
                 {
                     for ( j = 0; j <= info.max_cpu_index; j++ )
@@ -510,15 +525,17 @@ static void signal_int_handler(int signo)
                             break;
                     }
                     printf("\t Core %d CPU %d\n", core_ids[k], j);
-                    res = cxstat_end[j].cc3 - cxstat_start[j].cc3;
-                    printf("\t\tCC3\t%"PRIu64" ms\t%.2f%%\n",  res / 
1000000UL, 
-                           100UL * res / (double)sum_cx[j]);
-                    res = cxstat_end[j].cc6 - cxstat_start[j].cc6;
-                    printf("\t\tCC6\t%"PRIu64" ms\t%.2f%%\n",  res / 
1000000UL, 
-                           100UL * res / (double)sum_cx[j]);
-                    res = cxstat_end[j].cc7 - cxstat_start[j].cc7;
-                    printf("\t\tCC7\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL,
-                           100UL * res / (double)sum_cx[j]);
+                    for ( n = 0; n < MAX_CORE_RESIDENCIES; ++n )
+                    {
+                        if ( n >= cxstat_end[j].nr_cc )
+                            continue;
+                        res = cxstat_end[j].cc[n];
+                        if ( n < cxstat_start[j].nr_cc )
+                            res -= cxstat_start[j].cc[n];
+                        printf("\t\tCC%u\t%"PRIu64" ms\t%.2f%%\n",
+                               n + 1, res / 1000000UL,
+                               100UL * res / (double)sum_cx[j]);
+                    }
                 }
             }
         }
@@ -529,6 +546,8 @@ static void signal_int_handler(int signo)
     {
         free(cxstat[i].triggers);
         free(cxstat[i].residencies);
+        free(cxstat[i].pc);
+        free(cxstat[i].cc);
         free(pxstat[i].trans_pt);
         free(pxstat[i].pt);
     }
diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index 6aaa7ab..d2119e2 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -62,13 +62,17 @@
 
 #define GET_HW_RES_IN_NS(msr, val) \
     do { rdmsrl(msr, val); val = tsc_ticks2ns(val); } while( 0 )
-#define GET_PC2_RES(val)  GET_HW_RES_IN_NS(0x60D, val) /* SNB only */
+#define GET_PC2_RES(val)  GET_HW_RES_IN_NS(0x60D, val) /* SNB onwards */
 #define GET_PC3_RES(val)  GET_HW_RES_IN_NS(0x3F8, val)
 #define GET_PC6_RES(val)  GET_HW_RES_IN_NS(0x3F9, val)
 #define GET_PC7_RES(val)  GET_HW_RES_IN_NS(0x3FA, val)
+#define GET_PC8_RES(val)  GET_HW_RES_IN_NS(0x630, val) /* some Haswells only */
+#define GET_PC9_RES(val)  GET_HW_RES_IN_NS(0x631, val) /* some Haswells only */
+#define GET_PC10_RES(val) GET_HW_RES_IN_NS(0x632, val) /* some Haswells only */
+#define GET_CC1_RES(val)  GET_HW_RES_IN_NS(0x660, val) /* Silvermont only */
 #define GET_CC3_RES(val)  GET_HW_RES_IN_NS(0x3FC, val)
 #define GET_CC6_RES(val)  GET_HW_RES_IN_NS(0x3FD, val)
-#define GET_CC7_RES(val)  GET_HW_RES_IN_NS(0x3FE, val) /* SNB only */
+#define GET_CC7_RES(val)  GET_HW_RES_IN_NS(0x3FE, val) /* SNB onwards */
 
 static void lapic_timer_nop(void) { }
 void (*__read_mostly lapic_timer_off)(void);
@@ -111,8 +115,13 @@ struct hw_residencies
 {
     uint64_t pc2;
     uint64_t pc3;
+    uint64_t pc4;
     uint64_t pc6;
     uint64_t pc7;
+    uint64_t pc8;
+    uint64_t pc9;
+    uint64_t pc10;
+    uint64_t cc1;
     uint64_t cc3;
     uint64_t cc6;
     uint64_t cc7;
@@ -128,6 +137,12 @@ static void do_get_hw_residencies(void *arg)
 
     switch ( c->x86_model )
     {
+    /* 4th generation Intel Core (Haswell) */
+    case 0x45:
+        GET_PC8_RES(hw_res->pc8);
+        GET_PC9_RES(hw_res->pc9);
+        GET_PC10_RES(hw_res->pc10);
+        /* fall through */
     /* Sandy bridge */
     case 0x2A:
     case 0x2D:
@@ -137,7 +152,6 @@ static void do_get_hw_residencies(void *arg)
     /* Haswell */
     case 0x3C:
     case 0x3F:
-    case 0x45:
     case 0x46:
     /* future */
     case 0x3D:
@@ -160,6 +174,22 @@ static void do_get_hw_residencies(void *arg)
         GET_CC3_RES(hw_res->cc3);
         GET_CC6_RES(hw_res->cc6);
         break;
+    /* various Atoms */
+    case 0x27:
+        GET_PC3_RES(hw_res->pc2); /* abusing GET_PC3_RES */
+        GET_PC6_RES(hw_res->pc4); /* abusing GET_PC6_RES */
+        GET_PC7_RES(hw_res->pc6); /* abusing GET_PC7_RES */
+        break;
+    /* Silvermont */
+    case 0x37:
+    case 0x4A:
+    case 0x4D:
+    case 0x5A:
+    case 0x5D:
+        GET_PC7_RES(hw_res->pc6); /* abusing GET_PC7_RES */
+        GET_CC1_RES(hw_res->cc1);
+        GET_CC6_RES(hw_res->cc6);
+        break;
     }
 }
 
@@ -179,10 +209,16 @@ static void print_hw_residencies(uint32_t cpu)
 
     get_hw_residencies(cpu, &hw_res);
 
-    printk("PC2[%"PRId64"] PC3[%"PRId64"] PC6[%"PRId64"] PC7[%"PRId64"]\n",
-           hw_res.pc2, hw_res.pc3, hw_res.pc6, hw_res.pc7);
-    printk("CC3[%"PRId64"] CC6[%"PRId64"] CC7[%"PRId64"]\n",
-           hw_res.cc3, hw_res.cc6,hw_res.cc7);
+    printk("PC2[%"PRIu64"] PC%d[%"PRIu64"] PC6[%"PRIu64"] PC7[%"PRIu64"]\n",
+           hw_res.pc2,
+           hw_res.pc4 ? 4 : 3, hw_res.pc4 ?: hw_res.pc3,
+           hw_res.pc6, hw_res.pc7);
+    if ( hw_res.pc8 | hw_res.pc9 | hw_res.pc10 )
+        printk("PC8[%"PRIu64"] PC9[%"PRIu64"] PC10[%"PRIu64"]\n",
+               hw_res.pc8, hw_res.pc9, hw_res.pc10);
+    printk("CC%d[%"PRIu64"] CC6[%"PRIu64"] CC7[%"PRIu64"]\n",
+           hw_res.cc1 ? 1 : 3, hw_res.cc1 ?: hw_res.cc3,
+           hw_res.cc6, hw_res.cc7);
 }
 
 static char* acpi_cstate_method_name[] =
@@ -1100,19 +1136,21 @@ int pmstat_get_cx_stat(uint32_t cpuid, struct 
pm_cx_stat *stat)
     struct acpi_processor_power *power = processor_powers[cpuid];
     uint64_t idle_usage = 0, idle_res = 0;
     uint64_t usage[ACPI_PROCESSOR_MAX_POWER], res[ACPI_PROCESSOR_MAX_POWER];
-    int i;
-    struct hw_residencies hw_res;
+    unsigned int i, nr, nr_pc = 0, nr_cc = 0;
 
     if ( power == NULL )
     {
         stat->last = 0;
         stat->nr = 0;
         stat->idle_time = 0;
+        stat->nr_pc = 0;
+        stat->nr_cc = 0;
         return 0;
     }
 
     stat->last = power->last_state ? power->last_state->idx : 0;
     stat->idle_time = get_cpu_idle_time(cpuid);
+    nr = min(stat->nr, power->count);
 
     /* mimic the stat when detail info hasn't been registered by dom0 */
     if ( pm_idle_save == NULL )
@@ -1121,14 +1159,14 @@ int pmstat_get_cx_stat(uint32_t cpuid, struct 
pm_cx_stat *stat)
 
         usage[1] = idle_usage = 1;
         res[1] = idle_res = stat->idle_time;
-
-        memset(&hw_res, 0, sizeof(hw_res));
     }
     else
     {
+        struct hw_residencies hw_res;
+
         stat->nr = power->count;
 
-        for ( i = 1; i < power->count; i++ )
+        for ( i = 1; i < nr; i++ )
         {
             spin_lock_irq(&power->stat_lock);
             usage[i] = power->states[i].usage;
@@ -1140,22 +1178,42 @@ int pmstat_get_cx_stat(uint32_t cpuid, struct 
pm_cx_stat *stat)
         }
 
         get_hw_residencies(cpuid, &hw_res);
+
+#define PUT_xC(what, n) do { \
+        if ( stat->nr_##what >= n && \
+             copy_to_guest_offset(stat->what, n - 1, &hw_res.what##n, 1) ) \
+            return -EFAULT; \
+        if ( hw_res.what##n ) \
+            nr_##what = n; \
+    } while ( 0 )
+#define PUT_PC(n) PUT_xC(pc, n)
+        PUT_PC(2);
+        PUT_PC(3);
+        PUT_PC(4);
+        PUT_PC(6);
+        PUT_PC(7);
+        PUT_PC(8);
+        PUT_PC(9);
+        PUT_PC(10);
+#undef PUT_PC
+#define PUT_CC(n) PUT_xC(cc, n)
+        PUT_CC(1);
+        PUT_CC(3);
+        PUT_CC(6);
+        PUT_CC(7);
+#undef PUT_CC
+#undef PUT_xC
     }
 
     usage[0] = idle_usage;
     res[0] = NOW() - idle_res;
 
-    if ( copy_to_guest(stat->triggers, usage, stat->nr) ||
-         copy_to_guest(stat->residencies, res, stat->nr) )
+    if ( copy_to_guest(stat->triggers, usage, nr) ||
+         copy_to_guest(stat->residencies, res, nr) )
         return -EFAULT;
 
-    stat->pc2 = hw_res.pc2;
-    stat->pc3 = hw_res.pc3;
-    stat->pc6 = hw_res.pc6;
-    stat->pc7 = hw_res.pc7;
-    stat->cc3 = hw_res.cc3;
-    stat->cc6 = hw_res.cc6;
-    stat->cc7 = hw_res.cc7;
+    stat->nr_pc = nr_pc;
+    stat->nr_cc = nr_cc;
 
     return 0;
 }
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 8437d31..8ae6870 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -34,7 +34,7 @@
 #include "xen.h"
 #include "domctl.h"
 
-#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000A
+#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000B
 
 /*
  * Read console content from Xen buffer ring.
@@ -226,13 +226,10 @@ struct pm_cx_stat {
     uint64_aligned_t idle_time;                 /* idle time from boot */
     XEN_GUEST_HANDLE_64(uint64) triggers;    /* Cx trigger counts */
     XEN_GUEST_HANDLE_64(uint64) residencies; /* Cx residencies */
-    uint64_aligned_t pc2;
-    uint64_aligned_t pc3;
-    uint64_aligned_t pc6;
-    uint64_aligned_t pc7;
-    uint64_aligned_t cc3;
-    uint64_aligned_t cc6;
-    uint64_aligned_t cc7;
+    uint32_t nr_pc;                          /* entry nr in pc[] */
+    uint32_t nr_cc;                          /* entry nr in cc[] */
+    XEN_GUEST_HANDLE_64(uint64) pc;          /* 1-biased indexing */
+    XEN_GUEST_HANDLE_64(uint64) cc;          /* 1-biased indexing */
 };
 
 struct xen_sysctl_get_pmstat {
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.