]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Add functions to XEN_API to facilitate use of a domain watchdog
authorPaul Durrant <pdurrant@amazon.com>
Thu, 19 Nov 2020 09:08:32 +0000 (09:08 +0000)
committerPaul Durrant <pdurrant@amazon.com>
Tue, 24 Nov 2020 09:53:20 +0000 (09:53 +0000)
The SCHEDOP_watchdog hypercall allows a domain to program a watchdog time-
out (in seconds) after which it will be shut down.

This patch adds a helper function into sched.c to make the hypercall and also
adds new SystemSetWatchdog() and SystemStopWatchdog() functions that provide
a more friendly API to the functionality.

This patch does not introduce callers of the new API. Those will be
introduced in a subsequent patch.

Signed-off-by: Paul Durrant <pdurrant@amazon.com>
include/xen.h
src/xen/sched.c
src/xen/system.c

index 3532de839176cb87dd44708b2818b3adbf92f5f0..4594db975332866178094a86e9744d0b09de18c4 100644 (file)
@@ -308,6 +308,13 @@ SchedYield(
     VOID
     );
 
+XEN_API
+NTSTATUS
+SchedWatchdog(
+    IN OUT  PULONG  Id,
+    IN      ULONG   Seconds
+    );
+
 // XEN VERSION
 
 __checkReturn
@@ -465,4 +472,16 @@ SystemRealTimeIsUniversal(
     VOID
     );
 
+XEN_API
+NTSTATUS
+SystemSetWatchdog(
+    IN  ULONG       Seconds
+    );
+
+XEN_API
+VOID
+SystemStopWatchdog(
+    VOID
+    );
+
 #endif  // _XEN_H
index 56cbcf7b3345fe603f64f731c923ac35eae9e0f0..11ca5224165040a35540d61aa44e86a5485b72ae 100644 (file)
@@ -51,7 +51,7 @@ __checkReturn
 XEN_API
 NTSTATUS
 SchedShutdownCode(
-    ULONG                   Reason
+    IN  ULONG               Reason
     )
 {
     struct sched_shutdown   op;
@@ -79,7 +79,7 @@ __checkReturn
 XEN_API
 NTSTATUS
 SchedShutdown(
-    ULONG                   Reason
+    IN  ULONG               Reason
     )
 {
     struct sched_shutdown   op;
@@ -119,3 +119,35 @@ SchedYield(
 {
     (VOID) SchedOp(SCHEDOP_yield, NULL);
 }
+
+XEN_API
+NTSTATUS
+SchedWatchdog(
+    IN OUT  PULONG          Id,
+    IN      ULONG           Seconds
+    )
+{
+    struct sched_watchdog   op;
+    LONG_PTR                rc;
+    NTSTATUS                status;
+
+    op.id = *Id;
+    op.timeout = Seconds;
+
+    rc = SchedOp(SCHEDOP_watchdog, &op);
+
+    if (rc < 0) {
+        ERRNO_TO_STATUS(-rc, status);
+        goto fail1;
+    }
+
+    if (*Id == 0)
+        *Id = (ULONG)rc;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
index 45fe3b6c31bbfb6e111bb72b68806451947b3993..5a8ba16a66607006662fd2b4a79067e30965e7ed 100644 (file)
@@ -55,6 +55,11 @@ typedef struct _SYSTEM_PROCESSOR {
     UCHAR   ProcessorID;
 } SYSTEM_PROCESSOR, *PSYSTEM_PROCESSOR;
 
+typedef struct _SYSTEM_WATCHDOG {
+    ULONG   Id;
+    ULONG   Seconds;
+} SYSTEM_WATCHDOG, *PSYSTEM_WATCHDOG;
+
 typedef struct _SYSTEM_CONTEXT {
     LONG                References;
     PACPI_MADT          Madt;
@@ -64,6 +69,7 @@ typedef struct _SYSTEM_CONTEXT {
     PVOID               ProcessorChangeHandle;
     PHYSICAL_ADDRESS    MaximumPhysicalAddress;
     BOOLEAN             RealTimeIsUniversal;
+    SYSTEM_WATCHDOG     Watchdog;
 } SYSTEM_CONTEXT, *PSYSTEM_CONTEXT;
 
 static SYSTEM_CONTEXT   SystemContext;
@@ -1104,6 +1110,62 @@ SystemRealTimeIsUniversal(
     return Context->RealTimeIsUniversal;
 }
 
+XEN_API
+NTSTATUS
+SystemSetWatchdog(
+    IN  ULONG       Seconds
+    )
+{
+    PSYSTEM_CONTEXT Context = &SystemContext;
+    ULONG           Id = Context->Watchdog.Id;
+    NTSTATUS        status;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (Seconds == 0)
+        goto fail1;
+
+    status = SchedWatchdog(&Id, Seconds);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    if (Context->Watchdog.Id == 0 || Context->Watchdog.Seconds != Seconds)
+        Info("%u: %us\n", Id, Seconds);
+
+    Context->Watchdog.Id = Id;
+    Context->Watchdog.Seconds = Seconds;
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+XEN_API
+VOID
+SystemStopWatchdog(
+    VOID
+    )
+{
+    PSYSTEM_CONTEXT Context = &SystemContext;
+    NTSTATUS        status;
+
+    if (Context->Watchdog.Id == 0)
+        return;
+
+    status = SchedWatchdog(&Context->Watchdog.Id, 0);
+    ASSERT(NT_SUCCESS(status));
+
+    Info("%u\n", Context->Watchdog.Id);
+
+    Context->Watchdog.Id = 0;
+    Context->Watchdog.Seconds = 0;
+}
+
 VOID
 SystemTeardown(
     VOID