[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 05/12] Update the XENBUS_EVTCHN interface...
From: Paul Durrant <pdurrant@xxxxxxxxxx> ... to allow 'vcpu_id' to be sepcified to the EvtchnOpen() method, when opening a VIRQ channel. Non-global VIRQ channels (such as VIRQ_DEBUG and VIRQ_TIMER) can be bound to a specific vCPU. To allow callers of EvtchnOpen() to do this, it is necessary for extra arguments to be passed to EvtchnOpenVirq(). This patch updates the version of XENBUS_EVTCHN from 8 to 9, despite there being no function type change (since EvtchnOpen() is a variadic method) and modifies the implemention of EvtchnOpen() to pass the number of arguments to its type-specific helpers. Hence EvtchnOpenVirq() can determine whether or not it is being supplied with vCPU infomation. Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- include/evtchn_interface.h | 25 +++++++++- include/revision.h | 3 +- include/xen.h | 5 +- src/xen/event_channel.c | 3 +- src/xenbus/evtchn.c | 99 +++++++++++++++++++++++++++++++++++--- src/xenbus/fdo.c | 15 ++++-- 6 files changed, 135 insertions(+), 15 deletions(-) diff --git a/include/evtchn_interface.h b/include/evtchn_interface.h index ade725902421..fffde05bf1da 100644 --- a/include/evtchn_interface.h +++ b/include/evtchn_interface.h @@ -100,6 +100,8 @@ typedef VOID \b VIRQ: \param Index The index number of the VIRQ + \param Group The group number of the CPU that should handle the VIRQ + \param Number The relative number of the CPU that should handle the VIRQ \return Event channel handle */ @@ -340,7 +342,26 @@ struct _XENBUS_EVTCHN_INTERFACE_V8 { XENBUS_EVTCHN_CLOSE EvtchnClose; }; -typedef struct _XENBUS_EVTCHN_INTERFACE_V8 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; +/*! \struct _XENBUS_EVTCHN_INTERFACE_V9 + \brief EVTCHN interface version 9 + \ingroup interfaces +*/ +struct _XENBUS_EVTCHN_INTERFACE_V9 { + INTERFACE Interface; + XENBUS_EVTCHN_ACQUIRE EvtchnAcquire; + XENBUS_EVTCHN_RELEASE EvtchnRelease; + XENBUS_EVTCHN_OPEN EvtchnOpen; + XENBUS_EVTCHN_BIND EvtchnBind; + XENBUS_EVTCHN_UNMASK EvtchnUnmask; + XENBUS_EVTCHN_SEND EvtchnSend; + XENBUS_EVTCHN_TRIGGER EvtchnTrigger; + XENBUS_EVTCHN_GET_COUNT EvtchnGetCount; + XENBUS_EVTCHN_WAIT EvtchnWait; + XENBUS_EVTCHN_GET_PORT EvtchnGetPort; + XENBUS_EVTCHN_CLOSE EvtchnClose; +}; + +typedef struct _XENBUS_EVTCHN_INTERFACE_V9 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; /*! \def XENBUS_EVTCHN \brief Macro at assist in method invocation @@ -351,7 +372,7 @@ typedef struct _XENBUS_EVTCHN_INTERFACE_V8 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVT #endif // _WINDLL #define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 4 -#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 8 +#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 9 #endif // _XENBUS_EVTCHN_INTERFACE_H diff --git a/include/revision.h b/include/revision.h index 01b673722374..3a6b398e93a3 100644 --- a/include/revision.h +++ b/include/revision.h @@ -57,6 +57,7 @@ DEFINE_REVISION(0x09000004, 1, 2, 8, 1, 2, 1, 1, 3, 1, 1, 1), \ DEFINE_REVISION(0x09000005, 1, 2, 8, 1, 2, 1, 2, 4, 1, 1, 1), \ DEFINE_REVISION(0x09000006, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 1), \ - DEFINE_REVISION(0x09000007, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 2) + DEFINE_REVISION(0x09000007, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 2), \ + DEFINE_REVISION(0x09000008, 1, 3, 9, 1, 2, 1, 2, 4, 1, 1, 2) #endif // _REVISION_H diff --git a/include/xen.h b/include/xen.h index c2babc0c0280..3532de839176 100644 --- a/include/xen.h +++ b/include/xen.h @@ -177,8 +177,9 @@ __checkReturn XEN_API NTSTATUS EventChannelBindVirq( - IN ULONG Virq, - OUT ULONG *LocalPort + IN ULONG Virq, + IN unsigned int vcpu_id, + OUT ULONG *LocalPort ); __checkReturn diff --git a/src/xen/event_channel.c b/src/xen/event_channel.c index c2ce6a241c8b..2bce1c1c163b 100644 --- a/src/xen/event_channel.c +++ b/src/xen/event_channel.c @@ -145,6 +145,7 @@ XEN_API NTSTATUS EventChannelBindVirq( IN ULONG Virq, + IN unsigned int vcpu_id, OUT ULONG *LocalPort ) { @@ -153,7 +154,7 @@ EventChannelBindVirq( NTSTATUS status; op.virq = Virq; - op.vcpu = 0; + op.vcpu = vcpu_id; rc = EventChannelOp(EVTCHNOP_bind_virq, &op); diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c index 8c8c1648d007..4a764c071433 100644 --- a/src/xenbus/evtchn.c +++ b/src/xenbus/evtchn.c @@ -138,13 +138,18 @@ __EvtchnFree( static NTSTATUS EvtchnOpenFixed( + IN PXENBUS_EVTCHN_CONTEXT Context, IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Count, IN va_list Arguments ) { ULONG LocalPort; BOOLEAN Mask; + UNREFERENCED_PARAMETER(Context); + + ASSERT3U(Count, ==, 2); LocalPort = va_arg(Arguments, ULONG); Mask = va_arg(Arguments, BOOLEAN); @@ -156,7 +161,9 @@ EvtchnOpenFixed( static NTSTATUS EvtchnOpenUnbound( + IN PXENBUS_EVTCHN_CONTEXT Context, IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Count, IN va_list Arguments ) { @@ -165,6 +172,9 @@ EvtchnOpenUnbound( ULONG LocalPort; NTSTATUS status; + UNREFERENCED_PARAMETER(Context); + + ASSERT3U(Count, ==, 2); RemoteDomain = va_arg(Arguments, USHORT); Mask = va_arg(Arguments, BOOLEAN); @@ -187,7 +197,9 @@ fail1: static NTSTATUS EvtchnOpenInterDomain( + IN PXENBUS_EVTCHN_CONTEXT Context, IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Count, IN va_list Arguments ) { @@ -197,6 +209,9 @@ EvtchnOpenInterDomain( ULONG LocalPort; NTSTATUS status; + UNREFERENCED_PARAMETER(Context); + + ASSERT3U(Count, ==, 3); RemoteDomain = va_arg(Arguments, USHORT); RemotePort = va_arg(Arguments, ULONG); Mask = va_arg(Arguments, BOOLEAN); @@ -223,26 +238,63 @@ fail1: static NTSTATUS EvtchnOpenVirq( + IN PXENBUS_EVTCHN_CONTEXT Context, IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Count, IN va_list Arguments ) { ULONG Index; + USHORT Group; + UCHAR Number; + PROCESSOR_NUMBER ProcNumber; + ULONG Cpu; + PXENBUS_EVTCHN_PROCESSOR Processor; + unsigned int vcpu_id; ULONG LocalPort; NTSTATUS status; Index = va_arg(Arguments, ULONG); - status = EventChannelBindVirq(Index, &LocalPort); - if (!NT_SUCCESS(status)) + if (Count == 1) { + Group = 0; + Number = 0; + } else { + ASSERT3U(Count, ==, 3); + + Group = va_arg(Arguments, USHORT); + Number = va_arg(Arguments, UCHAR); + } + + RtlZeroMemory(&ProcNumber, sizeof (PROCESSOR_NUMBER)); + ProcNumber.Group = Group; + ProcNumber.Number = Number; + + Cpu = KeGetProcessorIndexFromNumber(&ProcNumber); + + ASSERT3U(Cpu, <, Context->ProcessorCount); + Processor = &Context->Processor[Cpu]; + + status = STATUS_NOT_SUPPORTED; + if (!Processor->UpcallEnabled) goto fail1; + status = SystemVirtualCpuIndex(Cpu, &vcpu_id); + ASSERT(NT_SUCCESS(status)); + + status = EventChannelBindVirq(Index, vcpu_id, &LocalPort); + if (!NT_SUCCESS(status)) + goto fail2; + Channel->Parameters.Virq.Index = Index; Channel->LocalPort = LocalPort; return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + fail1: Error("fail1 (%08x)\n", status); @@ -292,19 +344,22 @@ EvtchnOpen( va_start(Arguments, Argument); switch (Type) { case XENBUS_EVTCHN_TYPE_FIXED: - status = EvtchnOpenFixed(Channel, Arguments); + status = EvtchnOpenFixed(Context, Channel, 2, Arguments); break; case XENBUS_EVTCHN_TYPE_UNBOUND: - status = EvtchnOpenUnbound(Channel, Arguments); + status = EvtchnOpenUnbound(Context, Channel, 2, Arguments); break; case XENBUS_EVTCHN_TYPE_INTER_DOMAIN: - status = EvtchnOpenInterDomain(Channel, Arguments); + status = EvtchnOpenInterDomain(Context, Channel, 3, Arguments); break; case XENBUS_EVTCHN_TYPE_VIRQ: - status = EvtchnOpenVirq(Channel, Arguments); + // Processor information only specified from version 9 onwards + status = EvtchnOpenVirq(Context, Channel, + (Interface->Version < 9) ? 1 : 3, + Arguments); break; default: @@ -1762,6 +1817,21 @@ static struct _XENBUS_EVTCHN_INTERFACE_V8 EvtchnInterfaceVersion8 = { EvtchnClose, }; +static struct _XENBUS_EVTCHN_INTERFACE_V9 EvtchnInterfaceVersion9 = { + { sizeof (struct _XENBUS_EVTCHN_INTERFACE_V9), 9, NULL, NULL, NULL }, + EvtchnAcquire, + EvtchnRelease, + EvtchnOpen, + EvtchnBind, + EvtchnUnmask, + EvtchnSend, + EvtchnTrigger, + EvtchnGetCount, + EvtchnWait, + EvtchnGetPort, + EvtchnClose, +}; + NTSTATUS EvtchnInitialize( IN PXENBUS_FDO Fdo, @@ -1955,6 +2025,23 @@ EvtchnGetInterface( status = STATUS_SUCCESS; break; } + case 9: { + struct _XENBUS_EVTCHN_INTERFACE_V9 *EvtchnInterface; + + EvtchnInterface = (struct _XENBUS_EVTCHN_INTERFACE_V9 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof (struct _XENBUS_EVTCHN_INTERFACE_V9)) + break; + + *EvtchnInterface = EvtchnInterfaceVersion9; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index cdcfc85d6090..852f2b85c7ee 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -2797,9 +2797,11 @@ static FORCEINLINE NTSTATUS __FdoVirqCreate( IN PXENBUS_FDO Fdo, IN ULONG Type, + IN ULONG Cpu, OUT PXENBUS_VIRQ *Virq ) { + PROCESSOR_NUMBER ProcNumber; NTSTATUS status; *Virq = __FdoAllocate(sizeof (XENBUS_VIRQ)); @@ -2810,12 +2812,18 @@ __FdoVirqCreate( (*Virq)->Fdo = Fdo; (*Virq)->Type = Type; + + status = KeGetProcessorNumberFromIndex(Cpu, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + (*Virq)->Channel = XENBUS_EVTCHN(Open, &Fdo->EvtchnInterface, XENBUS_EVTCHN_TYPE_VIRQ, FdoVirqCallback, *Virq, - Type); + Type, + ProcNumber.Group, + ProcNumber.Number); status = STATUS_UNSUCCESSFUL; if ((*Virq)->Channel == NULL) @@ -2827,7 +2835,8 @@ __FdoVirqCreate( FALSE, TRUE); - Info("%s\n", VirqName((*Virq)->Type)); + Info("%s: CPU %u:%u\n", VirqName((*Virq)->Type), + ProcNumber.Group, ProcNumber.Number); return STATUS_SUCCESS; @@ -2874,7 +2883,7 @@ FdoVirqInitialize( InitializeListHead(&Fdo->VirqList); - status = __FdoVirqCreate(Fdo, VIRQ_DEBUG, &Virq); + status = __FdoVirqCreate(Fdo, VIRQ_DEBUG, 0, &Virq); if (!NT_SUCCESS(status)) goto fail1; -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |