NTSTATUS GnttabInitialize( IN PXENBUS_FDO Fdo, OUT PXENBUS_GNTTAB_CONTEXT *Context ) { NTSTATUS status; Trace("====>\n"); *Context = __GnttabAllocate(sizeof (XENBUS_GNTTAB_CONTEXT)); status = STATUS_NO_MEMORY; if (*Context == NULL) goto fail1; status = RangeSetGetInterface(FdoGetRangeSetContext(Fdo), XENBUS_RANGE_SET_INTERFACE_VERSION_MAX, (PINTERFACE)&(*Context)->RangeSetInterface, sizeof ((*Context)->RangeSetInterface)); ASSERT(NT_SUCCESS(status)); ASSERT((*Context)->RangeSetInterface.Interface.Context != NULL); status = CacheGetInterface(FdoGetCacheContext(Fdo), XENBUS_CACHE_INTERFACE_VERSION_MAX, (PINTERFACE)&(*Context)->CacheInterface, sizeof ((*Context)->CacheInterface)); ASSERT(NT_SUCCESS(status)); ASSERT((*Context)->CacheInterface.Interface.Context != NULL); status = SuspendGetInterface(FdoGetSuspendContext(Fdo), XENBUS_SUSPEND_INTERFACE_VERSION_MAX, (PINTERFACE)&(*Context)->SuspendInterface, sizeof ((*Context)->SuspendInterface)); ASSERT(NT_SUCCESS(status)); ASSERT((*Context)->SuspendInterface.Interface.Context != NULL); status = DebugGetInterface(FdoGetDebugContext(Fdo), XENBUS_DEBUG_INTERFACE_VERSION_MAX, (PINTERFACE)&(*Context)->DebugInterface, sizeof ((*Context)->DebugInterface)); ASSERT(NT_SUCCESS(status)); ASSERT((*Context)->DebugInterface.Interface.Context != NULL); InitializeListHead(&(*Context)->List); KeInitializeSpinLock(&(*Context)->Lock); status = HashTableCreate(&(*Context)->MapTable); if (!NT_SUCCESS(status)) goto fail2; (*Context)->Fdo = Fdo; Trace("<====\n"); return STATUS_SUCCESS; fail2: Error("fail2\n"); fail1: Error("fail1 (%08x)\n", status); return status; }
static NTSTATUS GnttabCreateCache( IN PINTERFACE Interface, IN const CHAR *Name, IN ULONG Reservation, IN VOID (*AcquireLock)(PVOID), IN VOID (*ReleaseLock)(PVOID), IN PVOID Argument, OUT PXENBUS_GNTTAB_CACHE *Cache ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; KIRQL Irql; NTSTATUS status; *Cache = __GnttabAllocate(sizeof (XENBUS_GNTTAB_CACHE)); status = STATUS_NO_MEMORY; if (*Cache == NULL) goto fail1; (*Cache)->Context = Context; status = RtlStringCbPrintfA((*Cache)->Name, sizeof ((*Cache)->Name), "%s_gnttab", Name); if (!NT_SUCCESS(status)) goto fail2; (*Cache)->AcquireLock = AcquireLock; (*Cache)->ReleaseLock = ReleaseLock; (*Cache)->Argument = Argument; status = XENBUS_CACHE(Create, &Context->CacheInterface, (*Cache)->Name, sizeof (XENBUS_GNTTAB_ENTRY), Reservation, GnttabEntryCtor, GnttabEntryDtor, GnttabAcquireLock, GnttabReleaseLock, *Cache, &(*Cache)->Cache); if (!NT_SUCCESS(status)) goto fail3; KeAcquireSpinLock(&Context->Lock, &Irql); InsertTailList(&Context->List, &(*Cache)->ListEntry); KeReleaseSpinLock(&Context->Lock, Irql); return STATUS_SUCCESS; fail3: Error("fail3\n"); (*Cache)->Argument = NULL; (*Cache)->ReleaseLock = NULL; (*Cache)->AcquireLock = NULL; RtlZeroMemory((*Cache)->Name, sizeof ((*Cache)->Name)); fail2: Error("fail2\n"); (*Cache)->Context = NULL; ASSERT(IsZeroMemory(*Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(*Cache); fail1: Error("fail1 (%08x)\n", status); return status; }
static NTSTATUS GnttabMapForeignPages( IN PINTERFACE Interface, IN USHORT Domain, IN ULONG NumberPages, IN PULONG References, IN BOOLEAN ReadOnly, OUT PHYSICAL_ADDRESS *Address ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; LONG PageIndex; PHYSICAL_ADDRESS PageAddress; PXENBUS_GNTTAB_MAP_ENTRY MapEntry; NTSTATUS status; status = FdoAllocateIoSpace(Context->Fdo, NumberPages * PAGE_SIZE, Address); if (!NT_SUCCESS(status)) goto fail1; MapEntry = __GnttabAllocate(FIELD_OFFSET(XENBUS_GNTTAB_MAP_ENTRY, MapHandles) + (NumberPages * sizeof (ULONG))); status = STATUS_NO_MEMORY; if (MapEntry == NULL) goto fail2; PageAddress.QuadPart = Address->QuadPart; MapEntry->NumberPages = NumberPages; for (PageIndex = 0; PageIndex < (LONG)NumberPages; PageIndex++) { status = GrantTableMapForeignPage(Domain, References[PageIndex], PageAddress, ReadOnly, &MapEntry->MapHandles[PageIndex]); if (!NT_SUCCESS(status)) goto fail3; PageAddress.QuadPart += PAGE_SIZE; } status = HashTableAdd(Context->MapTable, (ULONG_PTR)Address->QuadPart, (ULONG_PTR)MapEntry); if (!NT_SUCCESS(status)) goto fail4; return STATUS_SUCCESS; fail4: Error("fail4\n"); fail3: Error("fail3\n"); while (--PageIndex >= 0) { PageAddress.QuadPart -= PAGE_SIZE; (VOID) GrantTableUnmapForeignPage(MapEntry->MapHandles[PageIndex], PageAddress); } __GnttabFree(MapEntry); fail2: Error("fail2\n"); FdoFreeIoSpace(Context->Fdo, *Address, NumberPages * PAGE_SIZE); fail1: Error("fail1: (%08x)\n", status); return status; }
static NTSTATUS GnttabCreateCache( IN PXENBUS_GNTTAB_CONTEXT Context, IN const CHAR *Name, IN ULONG Reservation, IN VOID (*AcquireLock)(PVOID), IN VOID (*ReleaseLock)(PVOID), IN PVOID Argument, OUT PXENBUS_GNTTAB_CACHE *Cache ) { NTSTATUS status; *Cache = __GnttabAllocate(sizeof (XENBUS_GNTTAB_CACHE)); status = STATUS_NO_MEMORY; if (*Cache == NULL) goto fail1; (*Cache)->Context = Context; status = RtlStringCbPrintfA((*Cache)->Name, sizeof ((*Cache)->Name), "%s_gnttab", Name); if (!NT_SUCCESS(status)) goto fail2; (*Cache)->AcquireLock = AcquireLock; (*Cache)->ReleaseLock = ReleaseLock; (*Cache)->Argument = Argument; status = CACHE(Create, Context->CacheInterface, (*Cache)->Name, sizeof (XENBUS_GNTTAB_DESCRIPTOR), Reservation, GnttabDescriptorCtor, GnttabDescriptorDtor, GnttabAcquireLock, GnttabReleaseLock, *Cache, &(*Cache)->Cache); if (!NT_SUCCESS(status)) goto fail3; return STATUS_SUCCESS; fail3: Error("fail3\n"); (*Cache)->Argument = NULL; (*Cache)->ReleaseLock = NULL; (*Cache)->AcquireLock = NULL; RtlZeroMemory((*Cache)->Name, sizeof ((*Cache)->Name)); fail2: Error("fail2\n"); (*Cache)->Context = NULL; ASSERT(IsZeroMemory(*Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(*Cache); fail1: Error("fail1 (%08x)\n", status); return status; }