[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 |