|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |