]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Fix fall-back to two-level EVTCHN ABI
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 2 Jul 2015 09:23:26 +0000 (10:23 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 2 Jul 2015 09:30:40 +0000 (10:30 +0100)
When the EVTCHN code attempts to acquire the FIFO ABI it may fail to do
so because the version of Xen may not support it. In this case the code
was issuing an EventChannelReset() which has the unfortunate side effect of
killing any toolstack-created channels, such as the xenstored channel.

This patch moves the existent EvtchnFifoReset function into the base
evtchn source module (since it's not ABI specific) and uses that function
as the only mechanism of issuing an EventChannelReset() since it contains
code to preserve event channel bindings. (Prior to the move it only
preserved the xenstore channel but this patch adds code to preserve the
console event channel too, if it exists).

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenbus/evtchn.c
src/xenbus/evtchn.h
src/xenbus/evtchn_fifo.c

index fa5a980bfc294d32cc360b364d95f9e22a15cc87..051ec1f3cdef3a84811e9ed5b5b8df24806d80c6 100644 (file)
@@ -906,6 +906,120 @@ EvtchnInterruptCallback(
     return DoneSomething;
 }
 
+VOID
+EvtchnReset(
+    VOID
+    )
+{
+    ULONGLONG                   Value;
+    XENBUS_EVTCHN_CHANNEL       Store;
+    XENBUS_EVTCHN_CHANNEL       Console;
+    NTSTATUS                    status;
+
+    //
+    // When we reset the event channel ABI we will lose our
+    // binding to the any event channel which was set up
+    // by the toolstack during domain build.
+    // We need to get the binding back, so we must query the
+    // remote domain and port, and then re-bind after the
+    // reset.
+    //
+
+    RtlZeroMemory(&Store, sizeof (Store));
+    RtlZeroMemory(&Console, sizeof (Console));
+
+    status = HvmGetParam(HVM_PARAM_STORE_EVTCHN, &Value);
+    if (NT_SUCCESS(status))
+        Store.LocalPort = (ULONG)Value;
+
+    status = HvmGetParam(HVM_PARAM_CONSOLE_EVTCHN, &Value);
+    if (NT_SUCCESS(status))
+        Console.LocalPort = (ULONG)Value;
+
+    if (Store.LocalPort != 0) {
+        domid_t         RemoteDomain;
+        evtchn_port_t   RemotePort;
+
+        status = EventChannelQueryInterDomain(Store.LocalPort,
+                                              &RemoteDomain,
+                                              &RemotePort);
+        ASSERT(NT_SUCCESS(status));
+
+        Store.Parameters.InterDomain.RemoteDomain = RemoteDomain;
+        Store.Parameters.InterDomain.RemotePort = RemotePort;
+
+        LogPrintf(LOG_LEVEL_INFO, "EVTCHN_RESET: STORE (%u) -> (%u:%u)\n",
+                  Store.LocalPort,
+                  RemoteDomain,
+                  RemotePort);
+    }
+
+    if (Console.LocalPort != 0) {
+        domid_t         RemoteDomain;
+        evtchn_port_t   RemotePort;
+
+        status = EventChannelQueryInterDomain(Console.LocalPort,
+                                              &RemoteDomain,
+                                              &RemotePort);
+        ASSERT(NT_SUCCESS(status));
+
+        Console.Parameters.InterDomain.RemoteDomain = RemoteDomain;
+        Console.Parameters.InterDomain.RemotePort = RemotePort;
+
+        LogPrintf(LOG_LEVEL_INFO, "EVTCHN_RESET: CONSOLE (%u) -> (%u:%u)\n",
+                  Console.LocalPort,
+                  RemoteDomain,
+                  RemotePort);
+    }
+
+    (VOID) EventChannelReset();
+    LogPrintf(LOG_LEVEL_INFO, "EVTCHN_RESET: RESET\n");
+
+    if (Store.LocalPort != 0) {
+        domid_t         RemoteDomain;
+        evtchn_port_t   RemotePort;
+
+        RemoteDomain = Store.Parameters.InterDomain.RemoteDomain;
+        RemotePort = Store.Parameters.InterDomain.RemotePort;
+
+        status = EventChannelBindInterDomain(RemoteDomain,
+                                             RemotePort,
+                                             &Store.LocalPort);
+        ASSERT(NT_SUCCESS(status));
+
+        status = HvmSetParam(HVM_PARAM_STORE_EVTCHN, Store.LocalPort);
+        ASSERT(NT_SUCCESS(status));
+
+        LogPrintf(LOG_LEVEL_INFO, "EVTCHN_RESET: STORE (%u:%u) -> %u\n",
+                  RemoteDomain,
+                  RemotePort,
+                  Store.LocalPort);
+    }
+
+    if (Console.LocalPort != 0) {
+        domid_t         RemoteDomain;
+        evtchn_port_t   RemotePort;
+
+        RemoteDomain = Console.Parameters.InterDomain.RemoteDomain;
+        RemotePort = Console.Parameters.InterDomain.RemotePort;
+
+        status = EventChannelBindInterDomain(RemoteDomain,
+                                             RemotePort,
+                                             &Console.LocalPort);
+        ASSERT(NT_SUCCESS(status));
+
+        status = HvmSetParam(HVM_PARAM_CONSOLE_EVTCHN, Console.LocalPort);
+        ASSERT(NT_SUCCESS(status));
+
+        LogPrintf(LOG_LEVEL_INFO, "EVTCHN_RESET: CONSOLE (%u:%u) -> %u\n",
+                  RemoteDomain,
+                  RemotePort,
+                  Console.LocalPort);
+    }
+}
+
+
+
 static NTSTATUS
 EvtchnAbiAcquire(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
index 38a1f39c4501e916cfa02db445c771b961f81f12..69b557e06fb38e038a0f178103d4a5b70f7e7793 100644 (file)
@@ -59,6 +59,11 @@ EvtchnTeardown(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
     );
 
+VOID
+EvtchnReset(
+    VOID
+    );
+
 extern BOOLEAN
 EvtchnInterrupt(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
index 5996b828e123ad631161997447ac1e46213e0e83..98ea0fa0dec5a110bd6408a9335c8e3802230d63 100644 (file)
@@ -469,52 +469,6 @@ EvtchnFifoPortDisable(
     EvtchnFifoPortMask(_Context, Port);
 }
 
-static VOID
-EvtchnFifoReset(
-    IN  PXENBUS_EVTCHN_FIFO_CONTEXT Context
-    )
-{
-    ULONGLONG                       Value;
-    ULONG                           LocalPort;
-    ULONG                           RemotePort;
-    USHORT                          RemoteDomain;
-    NTSTATUS                        status;
-
-    UNREFERENCED_PARAMETER(Context);
-
-    status = HvmGetParam(HVM_PARAM_STORE_EVTCHN, &Value);
-    ASSERT(NT_SUCCESS(status));
-
-    LocalPort = (LONG)Value;
-
-    //
-    // When we reset the event channel ABI we will lose our
-    // binding to the STORE event channel, which was set up
-    // by the toolstack during domain build.
-    // We need to get the binding back, so we must query the
-    // remote domain and port, and then re-bind after the
-    // reset.
-    //
-
-    status = EventChannelQueryInterDomain(LocalPort,
-                                          &RemoteDomain,
-                                          &RemotePort);
-    ASSERT(NT_SUCCESS(status));
-
-    LogPrintf(LOG_LEVEL_INFO, "EVTCHN_FIFO: RESET\n");
-    (VOID) EventChannelReset();
-
-    status = EventChannelBindInterDomain(RemoteDomain,
-                                         RemotePort,
-                                         &LocalPort);
-    ASSERT(NT_SUCCESS(status));
-
-    Value = LocalPort;
-
-    status = HvmSetParam(HVM_PARAM_STORE_EVTCHN, Value);
-    ASSERT(NT_SUCCESS(status));
-}
-
 static NTSTATUS
 EvtchnFifoAcquire(
     IN  PXENBUS_EVTCHN_ABI_CONTEXT  _Context
@@ -578,7 +532,7 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    (VOID) EventChannelReset();
+    EvtchnReset();
 
     while (--Index >= 0) {
         unsigned int    vcpu_id;
@@ -614,7 +568,7 @@ EvtchnFifoRelease(
 
     Trace("====>\n");
 
-    EvtchnFifoReset(Context);
+    EvtchnReset();
 
     EvtchnFifoContract(Context);