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

[win-pv-devel] [PATCH 4/4] Fix fall-back to two-level EVTCHN ABI



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@xxxxxxxxxx>
---
 src/xenbus/evtchn.c      | 114 +++++++++++++++++++++++++++++++++++++++++++++++
 src/xenbus/evtchn.h      |   5 +++
 src/xenbus/evtchn_fifo.c |  50 +--------------------
 3 files changed, 121 insertions(+), 48 deletions(-)

diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c
index fa5a980..051ec1f 100644
--- a/src/xenbus/evtchn.c
+++ b/src/xenbus/evtchn.c
@@ -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
diff --git a/src/xenbus/evtchn.h b/src/xenbus/evtchn.h
index 38a1f39..69b557e 100644
--- a/src/xenbus/evtchn.h
+++ b/src/xenbus/evtchn.h
@@ -59,6 +59,11 @@ EvtchnTeardown(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
     );
 
+VOID
+EvtchnReset(
+    VOID
+    );
+
 extern BOOLEAN
 EvtchnInterrupt(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
diff --git a/src/xenbus/evtchn_fifo.c b/src/xenbus/evtchn_fifo.c
index 5996b82..98ea0fa 100644
--- a/src/xenbus/evtchn_fifo.c
+++ b/src/xenbus/evtchn_fifo.c
@@ -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);
 
-- 
2.1.1


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


 


Rackspace

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