[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/3] Get rid of the single contiguous memory hole
From: Paul Durrant <pdurrant@xxxxxxxxxx> A standard grant table with 64 pages only uses half the allocated 2 MiB of space and, empirically, getting more than 2 MiB of physically contiguous memory doesn't seem to work very often. By changing FdoAllocateHole() and FdoFreeHole() to use an MDL we can do discrete contiguous allocations on-demand, which is all that is actually required by callers. It's straightforward to adapt __AllocatePages() for this purpose by having it pass the MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS flag to MmAllocatePagesForMdlEx(). NOTE: This means that the generic XENBUS_HOLE becomes XENBUS_PCI_HOLE. Also re-work the function naming so FdoAllocateHole() becomes FdoHoleAllocate() and other names are similarly restructured. It makes the code marginally neater. Take the opprtunity to also put zeroing of FrameIndex in the XENBUS_GNTTAB Context in the right place in the GnttabAcquire() error path, and adjust GnttabRelease() accordingly. Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- src/common/util.h | 17 +- src/xenbus/fdo.c | 594 +++++++++++++++++---------------------- src/xenbus/fdo.h | 17 +- src/xenbus/gnttab.c | 79 +++--- src/xenbus/shared_info.c | 48 +++- 5 files changed, 357 insertions(+), 398 deletions(-) diff --git a/src/common/util.h b/src/common/util.h index 326ff0b98d9f..b020e5bed096 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -180,28 +180,37 @@ __FreePoolWithTag( static FORCEINLINE PMDL __AllocatePages( - IN ULONG Count + IN ULONG Count, + IN BOOLEAN Contiguous ) { PHYSICAL_ADDRESS LowAddress; PHYSICAL_ADDRESS HighAddress; LARGE_INTEGER SkipBytes; SIZE_T TotalBytes; + ULONG Flags; PMDL Mdl; PUCHAR MdlMappedSystemVa; NTSTATUS status; LowAddress.QuadPart = 0ull; HighAddress.QuadPart = ~0ull; - SkipBytes.QuadPart = 0ull; TotalBytes = (SIZE_T)PAGE_SIZE * Count; + if (Contiguous) { + SkipBytes.QuadPart = TotalBytes; + Flags = MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS; + } else { + SkipBytes.QuadPart = 0ull; + Flags = MM_ALLOCATE_FULLY_REQUIRED; + } + Mdl = MmAllocatePagesForMdlEx(LowAddress, HighAddress, SkipBytes, TotalBytes, MmCached, - MM_ALLOCATE_FULLY_REQUIRED); + Flags); status = STATUS_NO_MEMORY; if (Mdl == NULL) @@ -245,7 +254,7 @@ fail1: return NULL; } -#define __AllocatePage() __AllocatePages(1) +#define __AllocatePage() __AllocatePages(1, FALSE) static FORCEINLINE VOID __FreePages( diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index 99a4605f590c..976a7a35b12b 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -91,12 +91,12 @@ typedef struct _XENBUS_VIRQ { ULONG Count; } XENBUS_VIRQ, *PXENBUS_VIRQ; -typedef struct _XENBUS_HOLE { - PXENBUS_RANGE_SET RangeSet; - ULONG Count; - PVOID VirtualAddress; - PHYSICAL_ADDRESS PhysicalAddress; -} XENBUS_HOLE, *PXENBUS_HOLE; +typedef struct _XENBUS_PCI_HOLE { + PXENBUS_RANGE_SET RangeSet; + ULONG Count; + PVOID VirtualAddress; + PHYSICAL_ADDRESS PhysicalAddress; +} XENBUS_PCI_HOLE, *PXENBUS_PCI_HOLE; struct _XENBUS_FDO { PXENBUS_DX Dx; @@ -156,8 +156,8 @@ struct _XENBUS_FDO { XENBUS_RANGE_SET_INTERFACE RangeSetInterface; XENBUS_BALLOON_INTERFACE BalloonInterface; - PMDL Mdl; - XENBUS_HOLE Hole; + ULONG UseMemoryHole; + XENBUS_PCI_HOLE PciHole; LIST_ENTRY InterruptList; LIST_ENTRY VirqList; @@ -3218,82 +3218,24 @@ FdoSuspendCallbackLate( ASSERT(NT_SUCCESS(status)); } -static FORCEINLINE NTSTATUS -__FdoCreateMemoryHole( - IN PXENBUS_FDO Fdo - ) -{ - PXENBUS_HOLE Hole = &Fdo->Hole; - PMDL Mdl; - PFN_NUMBER Pfn; - NTSTATUS status; - - Mdl = Fdo->Mdl; - Hole->VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); - - Pfn = MmGetMdlPfnArray(Mdl)[0]; - Hole->PhysicalAddress.QuadPart = (ULONGLONG)Pfn << PAGE_SHIFT; - - Hole->Count = BYTES_TO_PAGES(Mdl->ByteCount); - ASSERT3U(Hole->Count, ==, 1u << PAGE_ORDER_2M); - - status = STATUS_UNSUCCESSFUL; - if (MemoryDecreaseReservation(PAGE_ORDER_2M, 1, &Pfn) != 1) - goto fail1; - - return STATUS_SUCCESS; - -fail1: - Error("fail1 (%08x)\n", status); - - Hole->Count = 0; - Hole->PhysicalAddress.QuadPart = 0; - Hole->VirtualAddress = NULL; - - return status; -} - -static FORCEINLINE VOID -__FdoDestroyMemoryHole( - IN PXENBUS_FDO Fdo - ) -{ - PXENBUS_HOLE Hole = &Fdo->Hole; - PMDL Mdl; - PFN_NUMBER Pfn; - ULONG Index; - - Mdl = Fdo->Mdl; - Pfn = MmGetMdlPfnArray(Mdl)[0]; - - ASSERT3U(Hole->Count, ==, 1u << PAGE_ORDER_2M); - if (MemoryPopulatePhysmap(PAGE_ORDER_2M, 1, &Pfn) == 1) - goto done; - - for (Index = 0; Index < Hole->Count; Index++) { - if (MemoryPopulatePhysmap(PAGE_ORDER_4K, 1, &Pfn) != 1) - BUG("FAILED TO RE-POPULATE HOLE"); - - Pfn++; - } - -done: - Hole->Count = 0; - Hole->PhysicalAddress.QuadPart = 0; - Hole->VirtualAddress = NULL; -} - -static FORCEINLINE NTSTATUS -__FdoCreatePciHole( +static NTSTATUS +FdoPciHoleCreate( IN PXENBUS_FDO Fdo ) { - PXENBUS_HOLE Hole = &Fdo->Hole; + PXENBUS_PCI_HOLE Hole = &Fdo->PciHole; ULONG Index; PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated; - SIZE_T Size; + PFN_NUMBER Pfn; NTSTATUS status; + status = XENBUS_RANGE_SET(Create, + &Fdo->RangeSetInterface, + "PCI", + &Hole->RangeSet); + if (!NT_SUCCESS(status)) + goto fail1; + for (Index = 0; Index < Fdo->TranslatedResourceList->Count; Index++) { Translated = &Fdo->TranslatedResourceList->PartialDescriptors[Index]; @@ -3302,125 +3244,106 @@ __FdoCreatePciHole( } status = STATUS_OBJECT_NAME_NOT_FOUND; - goto fail1; + goto fail2; found: - Hole->PhysicalAddress = Translated->u.Memory.Start; - Size = Translated->u.Memory.Length; - Hole->Count = (ULONG)(Size >> PAGE_SHIFT); - - Hole->VirtualAddress = MmMapIoSpace(Hole->PhysicalAddress, - Size, + Hole->VirtualAddress = MmMapIoSpace(Translated->u.Memory.Start, + Translated->u.Memory.Length, MmCached); status = STATUS_UNSUCCESSFUL; if (Hole->VirtualAddress == NULL) - goto fail2; + goto fail3; + + Hole->PhysicalAddress = Translated->u.Memory.Start; + Hole->Count = (ULONG)(Translated->u.Memory.Length >> PAGE_SHIFT); + + status = XENBUS_RANGE_SET(Put, + &Fdo->RangeSetInterface, + Hole->RangeSet, + 0, + Hole->Count); + if (!NT_SUCCESS(status)) + goto fail4; + + Pfn = (PFN_NUMBER)(Hole->PhysicalAddress.QuadPart >> PAGE_SHIFT); + Info("%08x - %08x\n", + Pfn, + Pfn + Hole->Count - 1); return STATUS_SUCCESS; -fail2: - Error("fail2\n"); +fail4: + Error("fail4\n"); + + MmUnmapIoSpace(Hole->VirtualAddress, Hole->Count << PAGE_SHIFT); Hole->VirtualAddress = NULL; Hole->Count = 0; Hole->PhysicalAddress.QuadPart = 0; -fail1: - Error("fail1 (%08x)\n", status); +fail3: + Error("fail3\n"); - return status; -} +fail2: + Error("fail2\n"); -static FORCEINLINE VOID -__FdoDestroyPciHole( - IN PXENBUS_FDO Fdo - ) -{ - PXENBUS_HOLE Hole = &Fdo->Hole; - SIZE_T Size; + XENBUS_RANGE_SET(Destroy, + &Fdo->RangeSetInterface, + Hole->RangeSet); + Hole->RangeSet = NULL; - Size = (ULONGLONG)Hole->Count << PAGE_SHIFT; - MmUnmapIoSpace(Hole->VirtualAddress, Size); +fail1: + Error("fail1 (%08x)\n", status); - Hole->VirtualAddress = NULL; - Hole->Count = 0; - Hole->PhysicalAddress.QuadPart = 0; + return status; } -static NTSTATUS -FdoCreateHole( +static VOID +FdoPciHoleDestroy( IN PXENBUS_FDO Fdo ) { - PXENBUS_HOLE Hole = &Fdo->Hole; - PFN_NUMBER Pfn; + PXENBUS_PCI_HOLE Hole = &Fdo->PciHole; NTSTATUS status; - status = XENBUS_RANGE_SET(Create, - &Fdo->RangeSetInterface, - "hole", - &Hole->RangeSet); - if (!NT_SUCCESS(status)) - goto fail1; - - status = (Fdo->Mdl != NULL) ? - __FdoCreateMemoryHole(Fdo) : - __FdoCreatePciHole(Fdo); - - if (!NT_SUCCESS(status)) - goto fail2; + BUG_ON(Hole->Count == 0); - status = XENBUS_RANGE_SET(Put, + status = XENBUS_RANGE_SET(Get, &Fdo->RangeSetInterface, Hole->RangeSet, 0, Hole->Count); - if (!NT_SUCCESS(status)) - goto fail3; - - Pfn = (PFN_NUMBER)(Hole->PhysicalAddress.QuadPart >> PAGE_SHIFT); - Info("(%s) %08x - %08x\n", - (Fdo->Mdl != NULL) ? "MEMORY" : "PCI", - Pfn, - Pfn + Hole->Count - 1); - - return STATUS_SUCCESS; - -fail3: - Error("fail3\n"); + ASSERT(NT_SUCCESS(status)); - if (Fdo->Mdl != NULL) - __FdoDestroyMemoryHole(Fdo); - else - __FdoDestroyPciHole(Fdo); + MmUnmapIoSpace(Hole->VirtualAddress, Hole->Count << PAGE_SHIFT); -fail2: - Error("fail2\n"); + Hole->VirtualAddress = NULL; + Hole->Count = 0; + Hole->PhysicalAddress.QuadPart = 0; XENBUS_RANGE_SET(Destroy, &Fdo->RangeSetInterface, Hole->RangeSet); Hole->RangeSet = NULL; - -fail1: - Error("fail1 (%08x)\n", status); - - return status; } -NTSTATUS -FdoAllocateHole( +static PMDL +FdoPciHoleAllocate( IN PXENBUS_FDO Fdo, - IN ULONG Count, - OUT PVOID *VirtualAddress OPTIONAL, - OUT PPHYSICAL_ADDRESS PhysicalAddress + IN ULONG Count ) { - PXENBUS_HOLE Hole = &Fdo->Hole; + PXENBUS_PCI_HOLE Hole = &Fdo->PciHole; LONGLONG Index; + PVOID VirtualAddress; + PHYSICAL_ADDRESS PhysicalAddress; + PMDL Mdl; + PPFN_NUMBER PfnArray; NTSTATUS status; + BUG_ON(Hole->Count == 0); + status = XENBUS_RANGE_SET(Pop, &Fdo->RangeSetInterface, Hole->RangeSet, @@ -3429,35 +3352,76 @@ FdoAllocateHole( if (!NT_SUCCESS(status)) goto fail1; - if (VirtualAddress != NULL) - *VirtualAddress = (PUCHAR)Hole->VirtualAddress + - (Index << PAGE_SHIFT); + VirtualAddress = (PUCHAR)Hole->VirtualAddress + (Index << PAGE_SHIFT); - PhysicalAddress->QuadPart = Hole->PhysicalAddress.QuadPart + - (Index << PAGE_SHIFT); + Mdl = IoAllocateMdl(VirtualAddress, + Count << PAGE_SHIFT, + FALSE, + FALSE, + NULL); - return STATUS_SUCCESS;; + status = STATUS_NO_MEMORY; + if (Mdl == NULL) + goto fail2; + + ASSERT3P(Mdl->StartVa, ==, VirtualAddress); + ASSERT3U(Mdl->ByteCount, ==, Count << PAGE_SHIFT); + + PhysicalAddress.QuadPart = Hole->PhysicalAddress.QuadPart + (Index << PAGE_SHIFT); + + PfnArray = MmGetMdlPfnArray(Mdl); + PfnArray[0] = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT); + + for (Index = 0; Index < (LONGLONG)Count; Index++) + PfnArray[Index] = PfnArray[0] + (ULONG)Index; + + return Mdl; + +fail2: + Error("fail2\n"); + + (VOID) XENBUS_RANGE_SET(Put, + &Fdo->RangeSetInterface, + Hole->RangeSet, + Index, + Count); fail1: Error("fail1 (%08x)\n", status); - return status; + return NULL; } -VOID -FdoFreeHole( - IN PXENBUS_FDO Fdo, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG Count +static VOID +FdoPciHoleFree( + IN PXENBUS_FDO Fdo, + IN PMDL Mdl ) { - PXENBUS_HOLE Hole = &Fdo->Hole; - LONGLONG Index; - NTSTATUS status; + PXENBUS_PCI_HOLE Hole = &Fdo->PciHole; + ULONG Count; + PPFN_NUMBER PfnArray; + LONGLONG Index; + PHYSICAL_ADDRESS PhysicalAddress; + NTSTATUS status; - Index = PhysicalAddress.QuadPart - Hole->PhysicalAddress.QuadPart; - ASSERT3U(Index & (PAGE_SIZE - 1), ==, 0); - Index >>= PAGE_SHIFT; + BUG_ON(Hole->Count == 0); + + Count = Mdl->ByteCount >> PAGE_SHIFT; + ASSERT3U(Count, <, Hole->Count); + + PfnArray = MmGetMdlPfnArray(Mdl); + + // Verify that the PFNs are contiguous + for (Index = 0; Index < (LONGLONG)Count; Index++) + BUG_ON(PfnArray[Index] != PfnArray[0] + Index); + + PhysicalAddress.QuadPart = PfnArray[0] << PAGE_SHIFT; + + Index = (PhysicalAddress.QuadPart - Hole->PhysicalAddress.QuadPart) >> PAGE_SHIFT; + + ASSERT3U(Index, <, Hole->Count); + ASSERT3U(Index + Count, <=, Hole->Count); status = XENBUS_RANGE_SET(Put, &Fdo->RangeSetInterface, @@ -3465,34 +3429,91 @@ FdoFreeHole( Index, Count); ASSERT(NT_SUCCESS(status)); + + ExFreePool(Mdl); +} + +static PMDL +FdoMemoryHoleAllocate( + IN PXENBUS_FDO Fdo, + IN ULONG Count + ) +{ + PMDL Mdl; + PPFN_NUMBER PfnArray; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Fdo); + + Mdl = __AllocatePages(Count, TRUE); + + status = STATUS_NO_MEMORY; + if (Mdl == NULL) + goto fail1; + + PfnArray = MmGetMdlPfnArray(Mdl); + + status = STATUS_UNSUCCESSFUL; + if (MemoryDecreaseReservation(PAGE_ORDER_4K, Count, PfnArray) != Count) + goto fail2; + + return Mdl; + +fail2: + Error("fail2\n"); + + __FreePages(Mdl); + +fail1: + Error("fail1 (%08x)\n", status); + + return NULL; } static VOID -FdoDestroyHole( - IN PXENBUS_FDO Fdo +FdoMemoryHoleFree( + IN PXENBUS_FDO Fdo, + IN PMDL Mdl ) { - PXENBUS_HOLE Hole = &Fdo->Hole; - NTSTATUS status; + ULONG Count; + PPFN_NUMBER PfnArray; - status = XENBUS_RANGE_SET(Get, - &Fdo->RangeSetInterface, - Hole->RangeSet, - 0, - Hole->Count); - ASSERT(NT_SUCCESS(status)); + UNREFERENCED_PARAMETER(Fdo); - if (Fdo->Mdl != NULL) - __FdoDestroyMemoryHole(Fdo); - else - __FdoDestroyPciHole(Fdo); + Count = Mdl->ByteCount >> PAGE_SHIFT; + PfnArray = MmGetMdlPfnArray(Mdl); - XENBUS_RANGE_SET(Destroy, - &Fdo->RangeSetInterface, - Hole->RangeSet); - Hole->RangeSet = NULL; + if (MemoryPopulatePhysmap(PAGE_ORDER_4K, Count, PfnArray) != Count) + BUG("FAILED TO RE-POPULATE HOLE"); + + __FreePages(Mdl); } +PMDL +FdoHoleAllocate( + IN PXENBUS_FDO Fdo, + IN ULONG Count + ) +{ + return (Fdo->UseMemoryHole != 0) ? + FdoMemoryHoleAllocate(Fdo, Count) : + FdoPciHoleAllocate(Fdo, Count); +} + +VOID +FdoHoleFree( + IN PXENBUS_FDO Fdo, + IN PMDL Mdl + ) +{ + if (Fdo->UseMemoryHole != 0) + FdoMemoryHoleFree(Fdo, Mdl); + else + FdoPciHoleFree(Fdo, Mdl); +} + + static VOID FdoDebugCallback( IN PVOID Argument, @@ -3566,10 +3587,11 @@ FdoD3ToD0( if (!NT_SUCCESS(status)) goto fail3; - // Subsequent interfaces require use of BAR space - status = FdoCreateHole(Fdo); - if (!NT_SUCCESS(status)) - goto fail4; + if (Fdo->UseMemoryHole == 0) { + status = FdoPciHoleCreate(Fdo); + if (!NT_SUCCESS(status)) + goto fail4; + } status = XENBUS_EVTCHN(Acquire, &Fdo->EvtchnInterface); if (!NT_SUCCESS(status)) @@ -3677,7 +3699,8 @@ fail6: fail5: Error("fail5\n"); - FdoDestroyHole(Fdo); + if (Fdo->UseMemoryHole == 0) + FdoPciHoleDestroy(Fdo); fail4: Error("fail4\n"); @@ -3800,7 +3823,8 @@ FdoD0ToD3( XENBUS_EVTCHN(Release, &Fdo->EvtchnInterface); - FdoDestroyHole(Fdo); + if (Fdo->UseMemoryHole == 0) + FdoPciHoleDestroy(Fdo); XENBUS_RANGE_SET(Release, &Fdo->RangeSetInterface); @@ -5605,107 +5629,6 @@ fail1: (_Size), \ (_Optional)) - -#define FDO_HOLE_SIZE (2ull << 20) - -static FORCEINLINE NTSTATUS -__FdoAllocateBuffer( - IN PXENBUS_FDO Fdo - ) -{ - HANDLE ParametersKey; - ULONG UseMemoryHole; - ULONG Count; - ULONG Size; - PHYSICAL_ADDRESS Low; - PHYSICAL_ADDRESS High; - PHYSICAL_ADDRESS Align; - PVOID Buffer; - PMDL Mdl; - NTSTATUS status; - - ParametersKey = DriverGetParametersKey(); - - status = RegistryQueryDwordValue(ParametersKey, - "UseMemoryHole", - &UseMemoryHole); - if (!NT_SUCCESS(status)) - UseMemoryHole = 1; - - ASSERT(Fdo->Mdl == NULL); - if (UseMemoryHole == 0) - goto done; - - Count = 1u << PAGE_ORDER_2M; - Size = Count << PAGE_SHIFT; - - Low.QuadPart = 0; - High = SystemMaximumPhysicalAddress(); - Align.QuadPart = Size; - - Buffer = MmAllocateContiguousNodeMemory((SIZE_T)Size, - Low, - High, - Align, - PAGE_READWRITE, - MM_ANY_NODE_OK); - - status = STATUS_NO_MEMORY; - if (Buffer == NULL) - goto fail1; - - Mdl = IoAllocateMdl(Buffer, - Size, - FALSE, - FALSE, - NULL); - - status = STATUS_NO_MEMORY; - if (Mdl == NULL) - goto fail2; - - MmBuildMdlForNonPagedPool(Mdl); - - ASSERT3U(Mdl->ByteOffset, ==, 0); - ASSERT3U(Mdl->ByteCount, ==, Size); - - Fdo->Mdl = Mdl; - -done: - return STATUS_SUCCESS; - -fail2: - Error("fail2\n"); - - MmFreeContiguousMemory(Buffer); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -static FORCEINLINE VOID -__FdoFreeBuffer( - IN PXENBUS_FDO Fdo - ) -{ - PMDL Mdl; - PVOID Buffer; - - Mdl = Fdo->Mdl; - if (Mdl == NULL) - return; - - Fdo->Mdl = NULL; - - Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); - - ExFreePool(Mdl); - - MmFreeContiguousMemory(Buffer); -} - static NTSTATUS FdoBalloonInitialize( IN PXENBUS_FDO Fdo @@ -5790,6 +5713,8 @@ FdoCreate( PXENBUS_DX Dx; PXENBUS_FDO Fdo; PCI_COMMON_HEADER Header; + HANDLE ParametersKey; + ULONG UseMemoryHole; NTSTATUS status; #pragma prefast(suppress:28197) // Possibly leaking memory 'FunctionDeviceObject' @@ -5857,53 +5782,59 @@ FdoCreate( if (!__FdoIsActive(Fdo)) goto done; - status = __FdoAllocateBuffer(Fdo); + ParametersKey = DriverGetParametersKey(); + + status = RegistryQueryDwordValue(ParametersKey, + "UseMemoryHole", + &UseMemoryHole); if (!NT_SUCCESS(status)) - goto fail9; + UseMemoryHole = 1; + + Fdo->UseMemoryHole = UseMemoryHole; status = DebugInitialize(Fdo, &Fdo->DebugContext); if (!NT_SUCCESS(status)) - goto fail10; + goto fail9; status = SuspendInitialize(Fdo, &Fdo->SuspendContext); if (!NT_SUCCESS(status)) - goto fail11; + goto fail10; status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext); if (!NT_SUCCESS(status)) - goto fail12; + goto fail11; status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext); if (!NT_SUCCESS(status)) - goto fail13; + goto fail12; status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext); if (!NT_SUCCESS(status)) - goto fail14; + goto fail13; status = CacheInitialize(Fdo, &Fdo->CacheContext); if (!NT_SUCCESS(status)) - goto fail15; + goto fail14; status = GnttabInitialize(Fdo, &Fdo->GnttabContext); if (!NT_SUCCESS(status)) - goto fail16; + goto fail15; status = StoreInitialize(Fdo, &Fdo->StoreContext); if (!NT_SUCCESS(status)) - goto fail17; + goto fail16; status = ConsoleInitialize(Fdo, &Fdo->ConsoleContext); if (!NT_SUCCESS(status)) - goto fail18; + goto fail17; status = UnplugInitialize(Fdo, &Fdo->UnplugContext); if (!NT_SUCCESS(status)) - goto fail19; + goto fail18; status = FdoBalloonInitialize(Fdo); if (!NT_SUCCESS(status)) - goto fail20; + goto fail19; status = DebugGetInterface(__FdoGetDebugContext(Fdo), XENBUS_DEBUG_INTERFACE_VERSION_MAX, @@ -5974,74 +5905,71 @@ done: return STATUS_SUCCESS; -fail20: - Error("fail20\n"); - - UnplugTeardown(Fdo->UnplugContext); - Fdo->UnplugContext = NULL; - fail19: Error("fail19\n"); - ConsoleTeardown(Fdo->ConsoleContext); - Fdo->ConsoleContext = NULL; + UnplugTeardown(Fdo->UnplugContext); + Fdo->UnplugContext = NULL; fail18: Error("fail18\n"); - StoreTeardown(Fdo->StoreContext); - Fdo->StoreContext = NULL; + ConsoleTeardown(Fdo->ConsoleContext); + Fdo->ConsoleContext = NULL; fail17: Error("fail17\n"); - GnttabTeardown(Fdo->GnttabContext); - Fdo->GnttabContext = NULL; + StoreTeardown(Fdo->StoreContext); + Fdo->StoreContext = NULL; fail16: Error("fail16\n"); - CacheTeardown(Fdo->CacheContext); - Fdo->CacheContext = NULL; + GnttabTeardown(Fdo->GnttabContext); + Fdo->GnttabContext = NULL; fail15: Error("fail15\n"); - RangeSetTeardown(Fdo->RangeSetContext); - Fdo->RangeSetContext = NULL; + CacheTeardown(Fdo->CacheContext); + Fdo->CacheContext = NULL; fail14: Error("fail14\n"); - EvtchnTeardown(Fdo->EvtchnContext); - Fdo->EvtchnContext = NULL; + RangeSetTeardown(Fdo->RangeSetContext); + Fdo->RangeSetContext = NULL; fail13: Error("fail13\n"); - SharedInfoTeardown(Fdo->SharedInfoContext); - Fdo->SharedInfoContext = NULL; + EvtchnTeardown(Fdo->EvtchnContext); + Fdo->EvtchnContext = NULL; fail12: Error("fail12\n"); - SuspendTeardown(Fdo->SuspendContext); - Fdo->SuspendContext = NULL; + SharedInfoTeardown(Fdo->SharedInfoContext); + Fdo->SharedInfoContext = NULL; fail11: Error("fail11\n"); - DebugTeardown(Fdo->DebugContext); - Fdo->DebugContext = NULL; + SuspendTeardown(Fdo->SuspendContext); + Fdo->SuspendContext = NULL; fail10: Error("fail10\n"); - __FdoFreeBuffer(Fdo); + DebugTeardown(Fdo->DebugContext); + Fdo->DebugContext = NULL; fail9: Error("fail9\n"); + Fdo->UseMemoryHole = 0; + // // We don't want to call DriverClearActive() so just // clear the FDO flag. @@ -6180,7 +6108,7 @@ FdoDestroy( DebugTeardown(Fdo->DebugContext); Fdo->DebugContext = NULL; - __FdoFreeBuffer(Fdo); + Fdo->UseMemoryHole = 0; FdoClearActive(Fdo); } diff --git a/src/xenbus/fdo.h b/src/xenbus/fdo.h index a58526ab5bb2..f2ec88c637ca 100644 --- a/src/xenbus/fdo.h +++ b/src/xenbus/fdo.h @@ -132,19 +132,16 @@ FdoGetName( IN PXENBUS_FDO Fdo ); -extern NTSTATUS -FdoAllocateHole( - IN PXENBUS_FDO Fdo, - IN ULONG Count, - OUT PVOID *VirtualAddress OPTIONAL, - OUT PPHYSICAL_ADDRESS PhysicalAddress +extern PMDL +FdoHoleAllocate( + IN PXENBUS_FDO Fdo, + IN ULONG Count ); extern VOID -FdoFreeHole( - IN PXENBUS_FDO Fdo, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG Count +FdoHoleFree( + IN PXENBUS_FDO Fdo, + IN PMDL Mdl ); // Disable erroneous SAL warnings around use of interrupt locks diff --git a/src/xenbus/gnttab.c b/src/xenbus/gnttab.c index af562608b40d..5929270a7793 100644 --- a/src/xenbus/gnttab.c +++ b/src/xenbus/gnttab.c @@ -70,7 +70,7 @@ struct _XENBUS_GNTTAB_ENTRY { }; typedef struct _XENBUS_GNTTAB_MAP_ENTRY { - ULONG NumberPages; + PMDL Mdl; ULONG MapHandles[1]; } XENBUS_GNTTAB_MAP_ENTRY, *PXENBUS_GNTTAB_MAP_ENTRY; @@ -79,7 +79,7 @@ struct _XENBUS_GNTTAB_CONTEXT { KSPIN_LOCK Lock; LONG References; ULONG MaximumFrameCount; - PHYSICAL_ADDRESS Address; + PMDL Mdl; LONG FrameIndex; grant_entry_v1_t *Table; XENBUS_RANGE_SET_INTERFACE RangeSetInterface; @@ -129,7 +129,7 @@ GnttabExpand( if (Index == Context->MaximumFrameCount) goto fail1; - Address = Context->Address; + Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT; Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT; status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT), @@ -187,7 +187,7 @@ GnttabMap( for (Index = 0; Index <= Context->FrameIndex; Index++) { PHYSICAL_ADDRESS Address; - Address = Context->Address; + Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT; Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT; status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT), @@ -213,7 +213,7 @@ GnttabUnmap( for (Index = Context->FrameIndex; Index >= 0; --Index) { PHYSICAL_ADDRESS Address; - Address = Context->Address; + Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT; Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT; (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT)); @@ -615,16 +615,16 @@ GnttabMapForeignPages( ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; + PMDL Mdl; LONG PageIndex; PHYSICAL_ADDRESS PageAddress; PXENBUS_GNTTAB_MAP_ENTRY MapEntry; NTSTATUS status; - status = FdoAllocateHole(Context->Fdo, - NumberPages, - NULL, - Address); - if (!NT_SUCCESS(status)) + Mdl = FdoHoleAllocate(Context->Fdo, NumberPages); + + status = STATUS_NO_MEMORY; + if (Mdl == NULL) goto fail1; MapEntry = __GnttabAllocate(FIELD_OFFSET(XENBUS_GNTTAB_MAP_ENTRY, @@ -635,8 +635,10 @@ GnttabMapForeignPages( if (MapEntry == NULL) goto fail2; + MapEntry->Mdl = Mdl; + + Address->QuadPart = MmGetMdlPfnArray(Mdl)[0] << PAGE_SHIFT; PageAddress.QuadPart = Address->QuadPart; - MapEntry->NumberPages = NumberPages; for (PageIndex = 0; PageIndex < (LONG)NumberPages; PageIndex++) { status = GrantTableMapForeignPage(Domain, @@ -670,12 +672,14 @@ fail3: PageAddress); } + Address->QuadPart = 0; + __GnttabFree(MapEntry); fail2: Error("fail2\n"); - FdoFreeHole(Context->Fdo, *Address, NumberPages); + FdoHoleFree(Context->Fdo, Mdl); fail1: Error("fail1: (%08x)\n", status); @@ -690,9 +694,11 @@ GnttabUnmapForeignPages( ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; - ULONG PageIndex; + ULONG NumberPages; PHYSICAL_ADDRESS PageAddress; + ULONG PageIndex; PXENBUS_GNTTAB_MAP_ENTRY MapEntry; + PMDL Mdl; NTSTATUS status; status = HashTableLookup(Context->MapTable, @@ -708,7 +714,10 @@ GnttabUnmapForeignPages( PageAddress.QuadPart = Address.QuadPart; - for (PageIndex = 0; PageIndex < MapEntry->NumberPages; PageIndex++) { + Mdl = MapEntry->Mdl; + NumberPages = Mdl->ByteCount >> PAGE_SHIFT; + + for (PageIndex = 0; PageIndex < NumberPages; PageIndex++) { status = GrantTableUnmapForeignPage(MapEntry->MapHandles[PageIndex], PageAddress); BUG_ON(!NT_SUCCESS(status)); @@ -716,12 +725,10 @@ GnttabUnmapForeignPages( PageAddress.QuadPart += PAGE_SIZE; } - FdoFreeHole(Context->Fdo, - Address, - MapEntry->NumberPages); - __GnttabFree(MapEntry); + FdoHoleFree(Context->Fdo, Mdl); + return STATUS_SUCCESS; fail2: @@ -750,14 +757,17 @@ GnttabDebugCallback( ) { PXENBUS_GNTTAB_CONTEXT Context = Argument; + PHYSICAL_ADDRESS Address; UNREFERENCED_PARAMETER(Crashing); + Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT; + XENBUS_DEBUG(Printf, &Context->DebugInterface, "Address = %08x.%08x\n", - Context->Address.HighPart, - Context->Address.LowPart); + Address.HighPart, + Address.LowPart); XENBUS_DEBUG(Printf, &Context->DebugInterface, @@ -790,13 +800,13 @@ GnttabAcquire( "GNTTAB: MAX FRAMES = %u\n", Context->MaximumFrameCount); - status = FdoAllocateHole(Fdo, - Context->MaximumFrameCount, - &Context->Table, - &Context->Address); - if (!NT_SUCCESS(status)) + Context->Mdl = FdoHoleAllocate(Fdo, Context->MaximumFrameCount); + + status = STATUS_NO_MEMORY; + if (Context->Mdl == NULL) goto fail2; + Context->Table = Context->Mdl->StartVa; Context->FrameIndex = -1; status = XENBUS_RANGE_SET(Acquire, &Context->RangeSetInterface); @@ -894,7 +904,6 @@ fail5: Context->RangeSet); Context->RangeSet = NULL; - Context->FrameIndex = 0; fail4: Error("fail4\n"); @@ -904,12 +913,12 @@ fail4: fail3: Error("fail3\n"); - FdoFreeHole(Fdo, - Context->Address, - Context->MaximumFrameCount); - Context->Address.QuadPart = 0; + Context->FrameIndex = 0; Context->Table = NULL; + FdoHoleFree(Fdo, Context->Mdl); + Context->Mdl = NULL; + fail2: Error("fail2\n"); @@ -968,16 +977,14 @@ GnttabRelease( Context->RangeSet); Context->RangeSet = NULL; - Context->FrameIndex = 0; - XENBUS_RANGE_SET(Release, &Context->RangeSetInterface); - FdoFreeHole(Fdo, - Context->Address, - Context->MaximumFrameCount); - Context->Address.QuadPart = 0; + Context->FrameIndex = 0; Context->Table = NULL; + FdoHoleFree(Fdo, Context->Mdl); + Context->Mdl = NULL; + Context->MaximumFrameCount = 0; Trace("<====\n"); diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c index f25e12a1c689..dc456ebcbf83 100644 --- a/src/xenbus/shared_info.c +++ b/src/xenbus/shared_info.c @@ -53,7 +53,7 @@ struct _XENBUS_SHARED_INFO_CONTEXT { PXENBUS_FDO Fdo; KSPIN_LOCK Lock; LONG References; - PHYSICAL_ADDRESS Address; + PMDL Mdl; shared_info_t *Shared; PXENBUS_SHARED_INFO_PROCESSOR Processor; ULONG ProcessorCount; @@ -459,17 +459,21 @@ SharedInfoMap( IN PXENBUS_SHARED_INFO_CONTEXT Context ) { + PFN_NUMBER Pfn; + PHYSICAL_ADDRESS Address; NTSTATUS status; - status = MemoryAddToPhysmap((PFN_NUMBER)(Context->Address.QuadPart >> PAGE_SHIFT), - XENMAPSPACE_shared_info, - 0); + Pfn = MmGetMdlPfnArray(Context->Mdl)[0]; + + status = MemoryAddToPhysmap(Pfn, XENMAPSPACE_shared_info, 0); ASSERT(NT_SUCCESS(status)); + Address.QuadPart = Pfn << PAGE_SHIFT; + LogPrintf(LOG_LEVEL_INFO, "SHARED_INFO: MAP XENMAPSPACE_shared_info @ %08x.%08x\n", - Context->Address.HighPart, - Context->Address.LowPart); + Address.HighPart, + Address.LowPart); } static VOID @@ -477,11 +481,14 @@ SharedInfoUnmap( IN PXENBUS_SHARED_INFO_CONTEXT Context ) { + PFN_NUMBER Pfn; + LogPrintf(LOG_LEVEL_INFO, "SHARED_INFO: UNMAP XENMAPSPACE_shared_info\n"); + Pfn = MmGetMdlPfnArray(Context->Mdl)[0]; - (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Context->Address.QuadPart >> PAGE_SHIFT)); + (VOID) MemoryRemoveFromPhysmap(Pfn); } static VOID @@ -502,12 +509,17 @@ SharedInfoDebugCallback( ) { PXENBUS_SHARED_INFO_CONTEXT Context = Argument; + PFN_NUMBER Pfn; + PHYSICAL_ADDRESS Address; + + Pfn = MmGetMdlPfnArray(Context->Mdl)[0]; + Address.QuadPart = Pfn << PAGE_SHIFT; XENBUS_DEBUG(Printf, &Context->DebugInterface, "Address = %08x.%08x\n", - Context->Address.HighPart, - Context->Address.LowPart); + Address.HighPart, + Address.LowPart); if (!Crashing) { shared_info_t *Shared; @@ -593,10 +605,14 @@ SharedInfoAcquire( Trace("====>\n"); - status = FdoAllocateHole(Fdo, 1, &Context->Shared, &Context->Address); - if (!NT_SUCCESS(status)) + Context->Mdl = FdoHoleAllocate(Fdo, 1); + + status = STATUS_NO_MEMORY; + if (Context->Mdl == NULL) goto fail1; + Context->Shared = Context->Mdl->StartVa; + SharedInfoMap(Context); SharedInfoEvtchnMaskAll(Context); @@ -715,10 +731,11 @@ fail2: SharedInfoUnmap(Context); - FdoFreeHole(Fdo, Context->Address, 1); - Context->Address.QuadPart = 0; Context->Shared = NULL; + FdoHoleFree(Fdo, Context->Mdl); + Context->Mdl = NULL; + fail1: Error("fail1 (%08x)\n", status); @@ -777,10 +794,11 @@ SharedInfoRelease ( SharedInfoUnmap(Context); - FdoFreeHole(Fdo, Context->Address, 1); - Context->Address.QuadPart = 0; Context->Shared = NULL; + FdoHoleFree(Fdo, Context->Mdl); + Context->Mdl = NULL; + Trace("<====\n"); done: -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |