# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1191318383 -3600
# Node ID 50edcaff5520d2b415f8a91c6f5776699c1d6e60
# Parent 8c67b2038ff2de2b7a75c1f81adb971931f54ceb
Add XENPF_getidletime.
Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/platform_hypercall.c | 47 ++++++++++++++++++++++++++++++++------
xen/include/public/platform.h | 14 ++++++++++-
2 files changed, 53 insertions(+), 8 deletions(-)
diff -r 8c67b2038ff2 -r 50edcaff5520 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Tue Oct 02 10:45:53 2007 +0100
+++ b/xen/arch/x86/platform_hypercall.c Tue Oct 02 10:46:23 2007 +0100
@@ -36,6 +36,8 @@ DEFINE_SPINLOCK(xenpf_lock);
# define copy_from_compat copy_from_guest
# undef copy_to_compat
# define copy_to_compat copy_to_guest
+# undef guest_from_compat_handle
+# define guest_from_compat_handle(x,y) ((x)=(y))
#else
extern spinlock_t xenpf_lock;
#endif
@@ -142,21 +144,14 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
case XENPF_microcode_update:
{
extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
-#ifdef COMPAT
XEN_GUEST_HANDLE(void) data;
-#endif
ret = xsm_microcode();
if ( ret )
break;
-#ifndef COMPAT
- ret = microcode_update(op->u.microcode.data,
- op->u.microcode.length);
-#else
guest_from_compat_handle(data, op->u.microcode.data);
ret = microcode_update(data, op->u.microcode.length);
-#endif
}
break;
@@ -286,6 +281,9 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
break;
case XENPF_change_freq:
+ ret = -ENOSYS;
+ if ( cpufreq_controller != FREQCTL_dom0_kernel )
+ break;
ret = -EINVAL;
if ( op->u.change_freq.flags != 0 )
break;
@@ -294,11 +292,46 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
&op->u.change_freq.freq);
break;
+ case XENPF_getidletime:
+ {
+ uint32_t i, nr_cpus;
+ uint64_t idletime;
+ struct vcpu *v;
+ XEN_GUEST_HANDLE(uint64_t) idletimes;
+
+ ret = -ENOSYS;
+ if ( cpufreq_controller != FREQCTL_dom0_kernel )
+ break;
+
+ guest_from_compat_handle(idletimes, op->u.getidletime.idletime);
+ nr_cpus = min_t(uint32_t, op->u.getidletime.max_cpus, NR_CPUS);
+
+ for ( i = 0; i < nr_cpus; i++ )
+ {
+ /* Assume no holes in idle-vcpu map. */
+ if ( (v = idle_vcpu[i]) == NULL )
+ break;
+
+ idletime = v->runstate.time[RUNSTATE_running];
+ if ( v->is_running )
+ idletime += NOW() - v->runstate.state_entry_time;
+
+ ret = -EFAULT;
+ if ( copy_to_guest_offset(idletimes, i, &idletime, 1) )
+ goto out;
+ }
+
+ op->u.getidletime.nr_cpus = i;
+ ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
+ }
+ break;
+
default:
ret = -ENOSYS;
break;
}
+ out:
spin_unlock(&xenpf_lock);
return ret;
diff -r 8c67b2038ff2 -r 50edcaff5520 xen/include/public/platform.h
--- a/xen/include/public/platform.h Tue Oct 02 10:45:53 2007 +0100
+++ b/xen/include/public/platform.h Tue Oct 02 10:46:23 2007 +0100
@@ -164,7 +164,7 @@ typedef struct xenpf_enter_acpi_sleep xe
typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t);
-#define XENPF_change_freq 52
+#define XENPF_change_freq 52
struct xenpf_change_freq {
/* IN variables */
uint32_t flags; /* Must be zero. */
@@ -173,6 +173,17 @@ struct xenpf_change_freq {
};
typedef struct xenpf_change_freq xenpf_change_freq_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t);
+
+#define XENPF_getidletime 53
+struct xenpf_getidletime {
+ /* IN variables. */
+ uint32_t max_cpus;
+ XEN_GUEST_HANDLE(uint64_t) idletime;
+ /* OUT variables. */
+ uint32_t nr_cpus;
+};
+typedef struct xenpf_getidletime xenpf_getidletime_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
struct xen_platform_op {
uint32_t cmd;
@@ -187,6 +198,7 @@ struct xen_platform_op {
struct xenpf_firmware_info firmware_info;
struct xenpf_enter_acpi_sleep enter_acpi_sleep;
struct xenpf_change_freq change_freq;
+ struct xenpf_getidletime getidletime;
uint8_t pad[128];
} u;
};
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|