\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
*/
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
#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
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
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);
static NTSTATUS
EvtchnOpenUnbound(
+ IN PXENBUS_EVTCHN_CONTEXT Context,
IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN ULONG Count,
IN va_list Arguments
)
{
ULONG LocalPort;
NTSTATUS status;
+ UNREFERENCED_PARAMETER(Context);
+
+ ASSERT3U(Count, ==, 2);
RemoteDomain = va_arg(Arguments, USHORT);
Mask = va_arg(Arguments, BOOLEAN);
static NTSTATUS
EvtchnOpenInterDomain(
+ IN PXENBUS_EVTCHN_CONTEXT Context,
IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN ULONG Count,
IN va_list Arguments
)
{
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);
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);
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:
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,
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;