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

[win-pv-devel] [PATCH] Sample 'RealTimeIsUniversal' at boot time...


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Date: Tue, 17 Sep 2019 15:08:36 +0100
  • Authentication-results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=paul.durrant@xxxxxxxxxx; spf=Pass smtp.mailfrom=Paul.Durrant@xxxxxxxxxx; spf=None smtp.helo=postmaster@xxxxxxxxxxxxxxx
  • Cc: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Delivery-date: Tue, 17 Sep 2019 14:08:52 +0000
  • Ironport-sdr: mrk1NGDcCnkGDeRNEcj0u87r7+RlVimm7hW4Lu+4TEUoAuvnE7i/jO24HxlfhxqQueoa7vJLZD rF7ftoNu7ecRCYWOtOIJtO0SkAuK4Kjy9BB6rislcPq38HjMpE7VYMczqAQiUeG71Io2qlL1Y7 avYL7+h61kM5YGmPgnBAwiqeKXT2ei1VlL4GKSyk5RHdsYcnFgC3HxYKBP6TAtj5JGIElZt/0v A7WktNBU2+oiHLPYnqqHNSOL3NlhGrBlJzO21PUtssHX1m18ZHqTKRgIRvdAdp+a5Zk2VnW7Xn SWY=
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

...and report via the XENBUS_SHARED_INFO GetTime method

The DWORD registry value:

HKLM\System\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

determines whether Windows programs the RTC in local time or UTC. If the
value is zero or missing (which is the default) then the RTC will be
programmed in local time, otherwise it will be programmed in UTC.

Since the emulated RTC and the Xen wall-clock are kept in sync, it is
necessary to know which mode Windows is operating in to correctly interpret
the wall-clock value. This patch checks the registry value on boot (it is
necessary to reboot after modifying it for it to take effect) and reports
the RTC operating mode along-side the Xen wall-clock in a updated
GetTime method in version 3 of the XENBUS_SHARED_INFO interface.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 include/revision.h              |  3 +-
 include/shared_info_interface.h | 36 +++++++++++++++---
 include/xen.h                   |  6 +++
 src/xen/system.c                | 66 ++++++++++++++++++++++++++++++++
 src/xenbus/shared_info.c        | 84 +++++++++++++++++++++++++++++++----------
 5 files changed, 169 insertions(+), 26 deletions(-)

diff --git a/include/revision.h b/include/revision.h
index 28ee461..b214152 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -55,6 +55,7 @@
     DEFINE_REVISION(0x09000002,  1,  2,  7,  1,  2,  1,  1,  2,  1,  1,  1), \
     DEFINE_REVISION(0x09000003,  1,  2,  8,  1,  2,  1,  1,  2,  1,  1,  1), \
     DEFINE_REVISION(0x09000004,  1,  2,  8,  1,  2,  1,  1,  3,  1,  1,  1), \
-    DEFINE_REVISION(0x09000005,  1,  2,  8,  1,  2,  1,  2,  4,  1,  1,  1)
+    DEFINE_REVISION(0x09000005,  1,  2,  8,  1,  2,  1,  2,  4,  1,  1,  1), \
+    DEFINE_REVISION(0x09000006,  1,  3,  8,  1,  2,  1,  2,  4,  1,  1,  1)
 
 #endif  // _REVISION_H
diff --git a/include/shared_info_interface.h b/include/shared_info_interface.h
index a0613ce..f99bcb6 100644
--- a/include/shared_info_interface.h
+++ b/include/shared_info_interface.h
@@ -113,15 +113,23 @@ typedef BOOLEAN
     IN  ULONG       Port
     );
 
+typedef LARGE_INTEGER
+(*XENBUS_SHARED_INFO_GET_TIME_V2)(
+    IN  PINTERFACE  Interface
+    );
+
 /*! \typedef XENBUS_SHARED_INFO_GET_TIME
-    \brief Return the wallclock time from the shared info
+    \brief Retrieve the wallclock time from the shared info
 
     \param Interface The interface header
-    \return The wallclock time in units of 100ns
+    \param Time The wallclock time
+    \param Local Set, on return, if the wallclock is in local time
 */  
-typedef LARGE_INTEGER
+typedef VOID
 (*XENBUS_SHARED_INFO_GET_TIME)(
-    IN  PINTERFACE  Interface
+    IN  PINTERFACE      Interface,
+    OUT PLARGE_INTEGER  Time,
+    OUT PBOOLEAN        Local
     );
 
 // {7E73C34F-1640-4649-A8F3-263BC930A004}
@@ -141,10 +149,26 @@ struct _XENBUS_SHARED_INFO_INTERFACE_V2 {
     XENBUS_SHARED_INFO_EVTCHN_ACK       SharedInfoEvtchnAck;
     XENBUS_SHARED_INFO_EVTCHN_MASK      SharedInfoEvtchnMask;
     XENBUS_SHARED_INFO_EVTCHN_UNMASK    SharedInfoEvtchnUnmask;
+    XENBUS_SHARED_INFO_GET_TIME_V2      SharedInfoGetTimeVersion2;
+};
+
+/*! \struct _XENBUS_SHARED_INFO_INTERFACE_V3
+    \brief SHARED_INFO interface version 3
+    \ingroup interfaces
+*/
+struct _XENBUS_SHARED_INFO_INTERFACE_V3 {
+    INTERFACE                           Interface;
+    XENBUS_SHARED_INFO_ACQUIRE          SharedInfoAcquire;
+    XENBUS_SHARED_INFO_RELEASE          SharedInfoRelease;
+    XENBUS_SHARED_INFO_UPCALL_PENDING   SharedInfoUpcallPending;
+    XENBUS_SHARED_INFO_EVTCHN_POLL      SharedInfoEvtchnPoll;
+    XENBUS_SHARED_INFO_EVTCHN_ACK       SharedInfoEvtchnAck;
+    XENBUS_SHARED_INFO_EVTCHN_MASK      SharedInfoEvtchnMask;
+    XENBUS_SHARED_INFO_EVTCHN_UNMASK    SharedInfoEvtchnUnmask;
     XENBUS_SHARED_INFO_GET_TIME         SharedInfoGetTime;
 };
 
-typedef struct _XENBUS_SHARED_INFO_INTERFACE_V2 XENBUS_SHARED_INFO_INTERFACE, 
*PXENBUS_SHARED_INFO_INTERFACE;
+typedef struct _XENBUS_SHARED_INFO_INTERFACE_V3 XENBUS_SHARED_INFO_INTERFACE, 
*PXENBUS_SHARED_INFO_INTERFACE;
 
 /*! \def XENBUS_SHARED_INFO
     \brief Macro at assist in method invocation
@@ -155,6 +179,6 @@ typedef struct _XENBUS_SHARED_INFO_INTERFACE_V2 
XENBUS_SHARED_INFO_INTERFACE, *P
 #endif  // _WINDLL
 
 #define XENBUS_SHARED_INFO_INTERFACE_VERSION_MIN    2
-#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX    2
+#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX    3
 
 #endif  // _XENBUS_SHARED_INFO_H
diff --git a/include/xen.h b/include/xen.h
index edfadc9..171fa4e 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -458,4 +458,10 @@ SystemMaximumPhysicalAddress(
     VOID
     );
 
+XEN_API
+BOOLEAN
+SystemRealTimeIsUniversal(
+    VOID
+    );
+
 #endif  // _XEN_H
diff --git a/src/xen/system.c b/src/xen/system.c
index a7b46d1..45fe3b6 100644
--- a/src/xen/system.c
+++ b/src/xen/system.c
@@ -63,6 +63,7 @@ typedef struct _SYSTEM_CONTEXT {
     PVOID               PowerStateHandle;
     PVOID               ProcessorChangeHandle;
     PHYSICAL_ADDRESS    MaximumPhysicalAddress;
+    BOOLEAN             RealTimeIsUniversal;
 } SYSTEM_CONTEXT, *PSYSTEM_CONTEXT;
 
 static SYSTEM_CONTEXT   SystemContext;
@@ -912,6 +913,51 @@ SystemDeregisterPowerStateCallback(
     Context->PowerStateHandle = NULL;
 }
 
+static NTSTATUS
+SystemGetTimeInformation(
+    VOID
+    )
+{
+    PSYSTEM_CONTEXT Context = &SystemContext;
+    UNICODE_STRING  Unicode;
+    HANDLE          Key;
+    ULONG           RealTimeIsUniversal;
+    NTSTATUS        status;
+
+    RtlInitUnicodeString(&Unicode, 
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation");
+
+    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryQueryDwordValue(Key, "RealTimeIsUniversal",
+                                     &RealTimeIsUniversal);
+    if (!NT_SUCCESS(status)) {
+        if (status != STATUS_OBJECT_NAME_NOT_FOUND)
+            goto fail2;
+
+        RealTimeIsUniversal = 0;
+    }
+
+    Context->RealTimeIsUniversal = RealTimeIsUniversal ? TRUE : FALSE;
+
+    Info("%s\n", Context->RealTimeIsUniversal ? "TRUE" : "FALSE");
+
+    RegistryCloseKey(Key);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(Key);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
 NTSTATUS
 SystemInitialize(
     VOID
@@ -951,8 +997,17 @@ SystemInitialize(
     if (!NT_SUCCESS(status))
         goto fail7;
 
+    status = SystemGetTimeInformation();
+    if (!NT_SUCCESS(status))
+        goto fail8;
+
     return STATUS_SUCCESS;
 
+fail8:
+    Error("fail8\n");
+
+    SystemDeregisterPowerStateCallback();
+
 fail7:
     Error("fail7\n");
 
@@ -1038,6 +1093,17 @@ SystemMaximumPhysicalAddress(
     return Context->MaximumPhysicalAddress;
 }
 
+XEN_API
+BOOLEAN
+SystemRealTimeIsUniversal(
+    VOID
+    )
+{
+    PSYSTEM_CONTEXT Context = &SystemContext;
+
+    return Context->RealTimeIsUniversal;
+}
+
 VOID
 SystemTeardown(
     VOID
diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c
index adae7ff..a95318c 100644
--- a/src/xenbus/shared_info.c
+++ b/src/xenbus/shared_info.c
@@ -309,11 +309,15 @@ SharedInfoEvtchnUnmask(
     return SharedInfoTestBit(&Shared->evtchn_pending[SelectorBit], PortBit);
 }
 
-static LARGE_INTEGER
+static VOID
 SharedInfoGetTime(
-    IN  PINTERFACE              Interface
+    IN  PINTERFACE              Interface,
+    OUT PLARGE_INTEGER          Time,
+    OUT PBOOLEAN                Local
     )
 {
+#define NS_PER_S 1000000000ull
+
     PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context;
     shared_info_t               *Shared;
     ULONG                       WcVersion;
@@ -325,8 +329,7 @@ SharedInfoGetTime(
     ULONGLONG                   SystemTime;
     ULONG                       TscSystemMul;
     CHAR                        TscShift;
-    LARGE_INTEGER               Now;
-    TIME_FIELDS                 Time;
+    TIME_FIELDS                 TimeFields;
     KIRQL                       Irql;
 
     // Make sure we don't suspend
@@ -379,30 +382,44 @@ SharedInfoGetTime(
           NanoSeconds);
 
     Trace("TIME SINCE BOOT: Seconds = %llu NanoSeconds = %llu\n",
-          SystemTime / 1000000000ull,
-          SystemTime % 1000000000ull);
+          SystemTime / NS_PER_S,
+          SystemTime % NS_PER_S);
 
     // Convert wallclock from Unix epoch (1970) to Windows epoch (1601)
     Seconds += 11644473600ull;
 
     // Add in time since host boot
-    Seconds += SystemTime / 1000000000ull;
-    NanoSeconds += SystemTime % 1000000000ull;
+    Seconds += SystemTime / NS_PER_S;
+    NanoSeconds += SystemTime % NS_PER_S;
 
-    // Convert to system time format
-    Now.QuadPart = (Seconds * 10000000ull) + (NanoSeconds / 100ull);
+    Time->QuadPart = ((Seconds * NS_PER_S) + NanoSeconds) / 100;
 
-    RtlTimeToTimeFields(&Now, &Time);
+    RtlTimeToTimeFields(Time, &TimeFields);
 
     Trace("TOD: %04u/%02u/%02u %02u:%02u:%02u\n",
-          Time.Year,
-          Time.Month,
-          Time.Day,
-          Time.Hour,
-          Time.Minute,
-          Time.Second);
-
-    return Now;
+          TimeFields.Year,
+          TimeFields.Month,
+          TimeFields.Day,
+          TimeFields.Hour,
+          TimeFields.Minute,
+          TimeFields.Second);
+
+    if ( Local )
+        *Local = !SystemRealTimeIsUniversal();
+
+#undef NS_PER_S
+}
+
+static LARGE_INTEGER
+SharedInfoGetTimeVersion2(
+    IN  PINTERFACE  Interface
+    )
+{
+    LARGE_INTEGER   Time;
+
+    SharedInfoGetTime(Interface, &Time, NULL);
+
+    return Time;
 }
 
 static VOID
@@ -672,6 +689,18 @@ static struct _XENBUS_SHARED_INFO_INTERFACE_V2 
SharedInfoInterfaceVersion2 = {
     SharedInfoEvtchnAck,
     SharedInfoEvtchnMask,
     SharedInfoEvtchnUnmask,
+    SharedInfoGetTimeVersion2
+};
+
+static struct _XENBUS_SHARED_INFO_INTERFACE_V3 SharedInfoInterfaceVersion3 = {
+    { sizeof (struct _XENBUS_SHARED_INFO_INTERFACE_V3), 3, NULL, NULL, NULL },
+    SharedInfoAcquire,
+    SharedInfoRelease,
+    SharedInfoUpcallPending,
+    SharedInfoEvtchnPoll,
+    SharedInfoEvtchnAck,
+    SharedInfoEvtchnMask,
+    SharedInfoEvtchnUnmask,
     SharedInfoGetTime
 };
                      
@@ -749,6 +778,23 @@ SharedInfoGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 3: {
+        struct _XENBUS_SHARED_INFO_INTERFACE_V3 *SharedInfoInterface;
+
+        SharedInfoInterface = (struct _XENBUS_SHARED_INFO_INTERFACE_V3 
*)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENBUS_SHARED_INFO_INTERFACE_V3))
+            break;
+
+        *SharedInfoInterface = SharedInfoInterfaceVersion3;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

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