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