コード例 #1
0
DECLSPEC_NOINLINE
NTSTATUS
IoctlEvtchnNotify(
    __in  PXENIFACE_FDO     Fdo,
    __in  PVOID             Buffer,
    __in  ULONG             InLen,
    __in  ULONG             OutLen,
    __in  PFILE_OBJECT      FileObject
    )
{
    NTSTATUS status;
    PXENIFACE_EVTCHN_NOTIFY_IN In = Buffer;

    status = STATUS_INVALID_BUFFER_SIZE;
    if (InLen != sizeof(XENIFACE_EVTCHN_NOTIFY_IN) ||
        OutLen != 0) {
        goto fail1;
    }

#if DBG
    XenIfaceDebugPrint(INFO, "> LocalPort %d, FO %p\n", In->LocalPort, FileObject);
#endif

    return EvtchnNotify(Fdo, In->LocalPort, FileObject);

fail1:
    XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status);
    return status;
}
コード例 #2
0
DECLSPEC_NOINLINE
NTSTATUS
IoctlEvtchnUnmask(
    __in  PXENIFACE_FDO     Fdo,
    __in  PVOID             Buffer,
    __in  ULONG             InLen,
    __in  ULONG             OutLen,
    __in  PFILE_OBJECT      FileObject
    )
{
    NTSTATUS status;
    PXENIFACE_EVTCHN_UNMASK_IN In = Buffer;
    PXENIFACE_EVTCHN_CONTEXT Context;
    KIRQL Irql;

    status = STATUS_INVALID_BUFFER_SIZE;
    if (InLen != sizeof(XENIFACE_EVTCHN_UNMASK_IN) ||
        OutLen != 0) {
        goto fail1;
    }

    XenIfaceDebugPrint(TRACE, "> LocalPort %d, FO %p\n", In->LocalPort, FileObject);

    KeAcquireSpinLock(&Fdo->EvtchnLock, &Irql);

    Context = EvtchnFindChannel(Fdo, In->LocalPort, FileObject);

    status = STATUS_INVALID_PARAMETER;
    if (Context == NULL)
        goto fail2;

    XENBUS_EVTCHN(Unmask,
                  &Fdo->EvtchnInterface,
                  Context->Channel,
                  FALSE);

    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);

    return STATUS_SUCCESS;

fail2:
    XenIfaceDebugPrint(ERROR, "Fail2\n");
    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);

fail1:
    XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status);
    return status;
}
コード例 #3
0
_IRQL_requires_same_
static DECLSPEC_NOINLINE
BOOLEAN
EvtchnInterruptHandler(
    __in      PKINTERRUPT Interrupt,
    __in_opt  PVOID Argument
    )
{
    PXENIFACE_EVTCHN_CONTEXT Context = Argument;
    PROCESSOR_NUMBER ProcNumber;
    ULONG ProcIndex;

    UNREFERENCED_PARAMETER(Interrupt);

    ASSERT(Context != NULL);

    KeGetCurrentProcessorNumberEx(&ProcNumber);
    ProcIndex = KeGetProcessorIndexFromNumber(&ProcNumber);

    if (!KeInsertQueueDpc(&Context->Dpc, NULL, NULL)) {
        XenIfaceDebugPrint(TRACE, "NOT INSERTED: Context %p, Port %lu, FO %p, Cpu %lu\n",
                           Context, Context->LocalPort, Context->FileObject, ProcIndex);
    }

    return TRUE;
}
コード例 #4
0
DECLSPEC_NOINLINE
NTSTATUS
EvtchnNotify(
    __in      PXENIFACE_FDO Fdo,
    __in      ULONG         LocalPort,
    __in_opt  PFILE_OBJECT  FileObject
    )
{
    NTSTATUS status;
    PXENIFACE_EVTCHN_CONTEXT Context;
    KIRQL Irql;

    KeAcquireSpinLock(&Fdo->EvtchnLock, &Irql);

    Context = EvtchnFindChannel(Fdo, LocalPort, FileObject);

    status = STATUS_NOT_FOUND;
    if (Context == NULL)
        goto fail1;

    XENBUS_EVTCHN(Send,
                  &Fdo->EvtchnInterface,
                  Context->Channel);

    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);

    return STATUS_SUCCESS;

fail1:
    XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status);
    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);
    return status;
}
コード例 #5
0
DECLSPEC_NOINLINE
NTSTATUS
IoctlEvtchnClose(
    __in  PXENIFACE_FDO     Fdo,
    __in  PVOID             Buffer,
    __in  ULONG             InLen,
    __in  ULONG             OutLen,
    __in  PFILE_OBJECT      FileObject
    )
{
    NTSTATUS status;
    PXENIFACE_EVTCHN_CLOSE_IN In = Buffer;
    PXENIFACE_EVTCHN_CONTEXT Context;
    KIRQL Irql;

    status = STATUS_INVALID_BUFFER_SIZE;
    if (InLen != sizeof(XENIFACE_EVTCHN_CLOSE_IN) ||
        OutLen != 0) {
        goto fail1;
    }

    XenIfaceDebugPrint(TRACE, "> LocalPort %lu, FO %p\n", In->LocalPort, FileObject);

    KeAcquireSpinLock(&Fdo->EvtchnLock, &Irql);
    status = STATUS_NOT_FOUND;
    Context = EvtchnFindChannel(Fdo, In->LocalPort, FileObject);
    if (Context == NULL)
        goto fail2;

    RemoveEntryList(&Context->Entry);
    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);
    EvtchnFree(Fdo, Context);

    return STATUS_SUCCESS;

fail2:
    XenIfaceDebugPrint(ERROR, "Fail2\n");
    KeReleaseSpinLock(&Fdo->EvtchnLock, Irql);

fail1:
    XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status);
    return status;
}
コード例 #6
0
_IRQL_requires_same_
static DECLSPEC_NOINLINE
BOOLEAN
EvtchnInterruptHandler(
    __in      PKINTERRUPT Interrupt,
    __in_opt  PVOID Argument
    )
{
    PXENIFACE_EVTCHN_CONTEXT Context = Argument;

    UNREFERENCED_PARAMETER(Interrupt);
    ASSERT(Context != NULL);

    if (!KeInsertQueueDpc(&Context->Dpc, NULL, NULL)) {
        XenIfaceDebugPrint(TRACE, "NOT INSERTED: Context %p, Port %lu, FO %p\n",
                           Context, Context->LocalPort, Context->FileObject);
    }

    return TRUE;
}
コード例 #7
0
VOID
EvtchnFree(
    __in     PXENIFACE_FDO Fdo,
    __inout  PXENIFACE_EVTCHN_CONTEXT Context
    )
{
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    XenIfaceDebugPrint(TRACE, "Context %p, LocalPort %d, FO %p\n",
                       Context, Context->LocalPort, Context->FileObject);

    XENBUS_EVTCHN(Close,
                  &Fdo->EvtchnInterface,
                  Context->Channel);

    // There may still be a pending event at this time.
    // Wait for our DPCs to complete.
    KeFlushQueuedDpcs();

    ObDereferenceObject(Context->Event);
    RtlZeroMemory(Context, sizeof(XENIFACE_EVTCHN_CONTEXT));
    ExFreePoolWithTag(Context, XENIFACE_POOL_TAG);
}
コード例 #8
0
DECLSPEC_NOINLINE
NTSTATUS
IoctlEvtchnBindInterdomain(
    __in  PXENIFACE_FDO     Fdo,
    __in  PVOID             Buffer,
    __in  ULONG             InLen,
    __in  ULONG             OutLen,
    __in  PFILE_OBJECT      FileObject,
    __out PULONG_PTR        Info
    )
{
    NTSTATUS status;
    PXENIFACE_EVTCHN_BIND_INTERDOMAIN_IN In = Buffer;
    PXENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT Out = Buffer;
    PXENIFACE_EVTCHN_CONTEXT Context;

    status = STATUS_INVALID_BUFFER_SIZE;
    if (InLen != sizeof(XENIFACE_EVTCHN_BIND_INTERDOMAIN_IN) ||
        OutLen != sizeof(XENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT)) {
        goto fail1;
    }

    status = STATUS_NO_MEMORY;
    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENIFACE_EVTCHN_CONTEXT), XENIFACE_POOL_TAG);
    if (Context == NULL)
        goto fail2;

    RtlZeroMemory(Context, sizeof(XENIFACE_EVTCHN_CONTEXT));
    Context->FileObject = FileObject;

    XenIfaceDebugPrint(TRACE, "> RemoteDomain %d, RemotePort %lu, Mask %d, FO %p\n",
                       In->RemoteDomain, In->RemotePort, In->Mask, FileObject);

    status = ObReferenceObjectByHandle(In->Event,
                                       EVENT_MODIFY_STATE,
                                       *ExEventObjectType,
                                       UserMode,
                                       &Context->Event,
                                       NULL);
    if (!NT_SUCCESS(status))
        goto fail3;

    KeInitializeDpc(&Context->Dpc, EvtchnNotificationDpc, Context);

    status = STATUS_UNSUCCESSFUL;
    Context->Channel = XENBUS_EVTCHN(Open,
                                     &Fdo->EvtchnInterface,
                                     XENBUS_EVTCHN_TYPE_INTER_DOMAIN,
                                     EvtchnInterruptHandler,
                                     Context,
                                     In->RemoteDomain,
                                     In->RemotePort,
                                     TRUE);
    if (Context->Channel == NULL)
        goto fail4;

    Context->LocalPort = XENBUS_EVTCHN(GetPort,
                                       &Fdo->EvtchnInterface,
                                       Context->Channel);

    Context->Fdo = Fdo;

    ExInterlockedInsertTailList(&Fdo->EvtchnList, &Context->Entry, &Fdo->EvtchnLock);

    Out->LocalPort = Context->LocalPort;
    *Info = sizeof(XENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT);

    if (!In->Mask) {
        XENBUS_EVTCHN(Unmask,
                      &Fdo->EvtchnInterface,
                      Context->Channel,
                      FALSE);
    }

    XenIfaceDebugPrint(TRACE, "< LocalPort %lu, Context %p\n", Context->LocalPort, Context);

    return STATUS_SUCCESS;

fail4:
    XenIfaceDebugPrint(ERROR, "Fail4\n");
    ObDereferenceObject(Context->Event);

fail3:
    XenIfaceDebugPrint(ERROR, "Fail3\n");
    RtlZeroMemory(Context, sizeof(XENIFACE_EVTCHN_CONTEXT));
    ExFreePoolWithTag(Context, XENIFACE_POOL_TAG);

fail2:
    XenIfaceDebugPrint(ERROR, "Fail2\n");

fail1:
    XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status);
    return status;
}