WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Allow guests to register secondary vcpu_t

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Allow guests to register secondary vcpu_time_info
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 19 Oct 2009 04:00:28 -0700
Delivery-date: Mon, 19 Oct 2009 04:01:24 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1255949916 -3600
# Node ID ad2fd7b94bd32e4256640a908ca3c8b40f505021
# Parent  5f28661bb2bbfd903b79d52e2aeabc4e4cb1f4d8
Allow guests to register secondary vcpu_time_info

Allow a guest to register a second location for the VCPU time info
structure for each vcpu.  This is intended to allow the guest kernel
to map this information into a usermode accessible page, so that
usermode can efficiently calculate system time from the TSC without
having to make a syscall.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c        |   19 +++++++
 xen/arch/x86/time.c          |  107 ++++++++++++++++++++++++++++---------------
 xen/include/asm-x86/domain.h |    4 +
 xen/include/asm-x86/time.h   |    2 
 xen/include/public/vcpu.h    |   28 +++++++++++
 5 files changed, 125 insertions(+), 35 deletions(-)

diff -r 5f28661bb2bb -r ad2fd7b94bd3 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Mon Oct 19 10:57:58 2009 +0100
+++ b/xen/arch/x86/domain.c     Mon Oct 19 11:58:36 2009 +0100
@@ -962,6 +962,25 @@ arch_do_vcpu_op(
         break;
     }
 
+    case VCPUOP_register_vcpu_time_memory_area:
+    {
+        struct vcpu_register_time_memory_area area;
+
+        rc = -EFAULT;
+        if ( copy_from_guest(&area, arg, 1) )
+            break;
+
+        if ( !guest_handle_okay(area.addr.h, 1) )
+            break;
+
+        rc = 0;
+        v->arch.time_info_guest = area.addr.h;
+
+        force_update_vcpu_system_time(v);
+
+        break;
+    }
+
     case VCPUOP_get_physid:
     {
         struct vcpu_get_physid cpu_id;
diff -r 5f28661bb2bb -r ad2fd7b94bd3 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Mon Oct 19 10:57:58 2009 +0100
+++ b/xen/arch/x86/time.c       Mon Oct 19 11:58:36 2009 +0100
@@ -22,6 +22,7 @@
 #include <xen/irq.h>
 #include <xen/softirq.h>
 #include <xen/keyhandler.h>
+#include <xen/guest_access.h>
 #include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/mpspec.h>
@@ -807,23 +808,15 @@ s_time_t get_s_time(void)
     return now;
 }
 
-static inline void version_update_begin(u32 *version)
-{
-    /* Explicitly OR with 1 just in case version number gets out of sync. */
-    *version = (*version + 1) | 1;
-    wmb();
-}
-
-static inline void version_update_end(u32 *version)
-{
-    wmb();
-    (*version)++;
-}
-
-void update_vcpu_system_time(struct vcpu *v)
+/* Explicitly OR with 1 just in case version number gets out of sync. */
+#define version_update_begin(v) (((v)+1)|1)
+#define version_update_end(v)   ((v)+1)
+
+static void __update_vcpu_system_time(struct vcpu *v, int force)
 {
     struct cpu_time       *t;
-    struct vcpu_time_info *u;
+    struct vcpu_time_info *u, _u;
+    XEN_GUEST_HANDLE(vcpu_time_info_t) user_u;
 
     if ( v->vcpu_info == NULL )
         return;
@@ -831,35 +824,79 @@ void update_vcpu_system_time(struct vcpu
     t = &this_cpu(cpu_time);
     u = &vcpu_info(v, time);
 
+    /* Don't bother unless timestamps have changed or we are forced. */
+    if ( !force && (u->tsc_timestamp == (v->domain->arch.vtsc
+                                         ? t->stime_local_stamp
+                                         : t->local_tsc_stamp)) )
+        return;
+
+    memset(&_u, 0, sizeof(_u));
+
     if ( v->domain->arch.vtsc )
     {
-        if ( u->tsc_timestamp == t->stime_local_stamp )
-            return;
-        version_update_begin(&u->version);
-        u->tsc_timestamp     = t->stime_local_stamp;
-        u->system_time       = t->stime_local_stamp;
-        u->tsc_to_system_mul = 0x80000000u;
-        u->tsc_shift         = 1;
-        version_update_end(&u->version);
-    }
-    else if ( u->tsc_timestamp != t->local_tsc_stamp )
-    {
-        version_update_begin(&u->version);
-        u->tsc_timestamp     = t->local_tsc_stamp;
-        u->system_time       = t->stime_local_stamp;
-        u->tsc_to_system_mul = t->tsc_scale.mul_frac;
-        u->tsc_shift         = (s8)t->tsc_scale.shift;
-        version_update_end(&u->version);
-    }
+        _u.tsc_timestamp     = t->stime_local_stamp;
+        _u.system_time       = t->stime_local_stamp;
+        _u.tsc_to_system_mul = 0x80000000u;
+        _u.tsc_shift         = 1;
+    }
+    else
+    {
+        _u.tsc_timestamp     = t->local_tsc_stamp;
+        _u.system_time       = t->stime_local_stamp;
+        _u.tsc_to_system_mul = t->tsc_scale.mul_frac;
+        _u.tsc_shift         = (s8)t->tsc_scale.shift;
+    }
+
+    /* 1. Update guest kernel version. */
+    _u.version = u->version = version_update_begin(u->version);
+    wmb();
+    /* 2. Update all other guest kernel fields. */
+    *u = _u;
+    wmb();
+    /* 3. Update guest kernel version. */
+    u->version = version_update_end(u->version);
+
+    user_u = v->arch.time_info_guest;
+    if ( !guest_handle_is_null(user_u) )
+    {
+        /* 1. Update userspace version. */
+        __copy_field_to_guest(user_u, &_u, version);
+        wmb();
+        /* 2. Update all other userspavce fields. */
+        __copy_to_guest(user_u, &_u, 1);
+        wmb();
+        /* 3. Update userspace version. */
+        _u.version = version_update_end(_u.version);
+        __copy_field_to_guest(user_u, &_u, version);
+    }
+}
+
+void update_vcpu_system_time(struct vcpu *v)
+{
+    __update_vcpu_system_time(v, 0);
+}
+
+void force_update_vcpu_system_time(struct vcpu *v)
+{
+    __update_vcpu_system_time(v, 1);
 }
 
 void update_domain_wallclock_time(struct domain *d)
 {
+    uint32_t *wc_version;
+
     spin_lock(&wc_lock);
-    version_update_begin(&shared_info(d, wc_version));
+
+    wc_version = &shared_info(d, wc_version);
+    *wc_version = version_update_begin(*wc_version);
+    wmb();
+
     shared_info(d, wc_sec)  = wc_sec + d->time_offset_seconds;
     shared_info(d, wc_nsec) = wc_nsec;
-    version_update_end(&shared_info(d, wc_version));
+
+    wmb();
+    *wc_version = version_update_end(*wc_version);
+
     spin_unlock(&wc_lock);
 }
 
diff -r 5f28661bb2bb -r ad2fd7b94bd3 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Mon Oct 19 10:57:58 2009 +0100
+++ b/xen/include/asm-x86/domain.h      Mon Oct 19 11:58:36 2009 +0100
@@ -6,6 +6,7 @@
 #include <asm/hvm/vcpu.h>
 #include <asm/hvm/domain.h>
 #include <asm/e820.h>
+#include <public/vcpu.h>
 
 #define has_32bit_shinfo(d)    ((d)->arch.has_32bit_shinfo)
 #define is_pv_32bit_domain(d)  ((d)->arch.is_32bit_pv)
@@ -418,6 +419,9 @@ struct arch_vcpu
     uint32_t gdbsx_vcpu_event;
 #endif 
 
+    /* A secondary copy of the vcpu time info. */
+    XEN_GUEST_HANDLE(vcpu_time_info_t) time_info_guest;
+
 } __cacheline_aligned;
 
 /* Shorthands to improve code legibility. */
diff -r 5f28661bb2bb -r ad2fd7b94bd3 xen/include/asm-x86/time.h
--- a/xen/include/asm-x86/time.h        Mon Oct 19 10:57:58 2009 +0100
+++ b/xen/include/asm-x86/time.h        Mon Oct 19 11:58:36 2009 +0100
@@ -43,4 +43,6 @@ uint64_t ns_to_acpi_pm_tick(uint64_t ns)
 
 void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs);
 
+void force_update_vcpu_system_time(struct vcpu *v);
+
 #endif /* __X86_TIME_H__ */
diff -r 5f28661bb2bb -r ad2fd7b94bd3 xen/include/public/vcpu.h
--- a/xen/include/public/vcpu.h Mon Oct 19 10:57:58 2009 +0100
+++ b/xen/include/public/vcpu.h Mon Oct 19 11:58:36 2009 +0100
@@ -202,6 +202,34 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_
 #define xen_vcpu_physid_to_x86_acpiid(physid) \
     ((((uint32_t)((physid)>>32)) >= 0xff) ? 0xff : ((uint8_t)((physid)>>32)))
 
+/* 
+ * Register a memory location to get a secondary copy of the vcpu time
+ * parameters.  The master copy still exists as part of the vcpu shared
+ * memory area, and this secondary copy is updated whenever the master copy
+ * is updated (and using the same versioning scheme for synchronisation).
+ *
+ * The intent is that this copy may be mapped (RO) into userspace so
+ * that usermode can compute system time using the time info and the
+ * tsc.  Usermode will see an array of vcpu_time_info structures, one
+ * for each vcpu, and choose the right one by an existing mechanism
+ * which allows it to get the current vcpu number (such as via a
+ * segment limit).  It can then apply the normal algorithm to compute
+ * system time from the tsc.
+ *
+ * @extra_arg == pointer to vcpu_register_time_info_memory_area structure.
+ */
+#define VCPUOP_register_vcpu_time_memory_area   13
+DEFINE_XEN_GUEST_HANDLE(vcpu_time_info_t);
+struct vcpu_register_time_memory_area {
+    union {
+        XEN_GUEST_HANDLE(vcpu_time_info_t) h;
+        struct vcpu_time_info *v;
+        uint64_t p;
+    } addr;
+};
+typedef struct vcpu_register_time_memory_area vcpu_register_time_memory_area_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_register_time_memory_area_t);
+
 #endif /* __XEN_PUBLIC_VCPU_H__ */
 
 /*

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Allow guests to register secondary vcpu_time_info, Xen patchbot-unstable <=