XENBUS_RANGE_SET_INTERFACE RangeSetInterface;
XENBUS_BALLOON_INTERFACE BalloonInterface;
- PXENBUS_RANGE_SET IoRangeSet;
+ PUCHAR Buffer;
+ PMDL Mdl;
+ PXENBUS_RANGE_SET RangeSet;
LIST_ENTRY InterruptList;
PXENBUS_EVTCHN_CHANNEL Channel;
}
static NTSTATUS
-FdoCreateIoSpace(
- IN PXENBUS_FDO Fdo
+FdoCreateHole(
+ IN PXENBUS_FDO Fdo
)
{
- ULONG Index;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated;
- PHYSICAL_ADDRESS End;
- NTSTATUS status;
-
- for (Index = 0; Index < Fdo->TranslatedResourceList->Count; Index++) {
- Translated = &Fdo->TranslatedResourceList->PartialDescriptors[Index];
-
- if (Translated->Type == CmResourceTypeMemory)
- goto found;
- }
-
- status = STATUS_OBJECT_NAME_NOT_FOUND;
- goto fail1;
+ PMDL Mdl;
+ PFN_NUMBER Pfn;
+ LONGLONG Start;
+ ULONG Count;
+ NTSTATUS status;
-found:
status = XENBUS_RANGE_SET(Create,
&Fdo->RangeSetInterface,
- "io_space",
- &Fdo->IoRangeSet);
+ "hole",
+ &Fdo->RangeSet);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail1;
+
+ Mdl = Fdo->Mdl;
+
+ Pfn = MmGetMdlPfnArray(Mdl)[0];
+
+ Start = Pfn;
+ Count = BYTES_TO_PAGES(Mdl->ByteCount);
status = XENBUS_RANGE_SET(Put,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet,
- Translated->u.Memory.Start.QuadPart,
- Translated->u.Memory.Length);
+ Fdo->RangeSet,
+ Start,
+ Count);
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail2;
- End.QuadPart = Translated->u.Memory.Start.QuadPart + Translated->u.Memory.Length - 1;
+ status = STATUS_UNSUCCESSFUL;
+ if (MemoryDecreaseReservation(PAGE_ORDER_2M, 1, &Pfn) != 1)
+ goto fail3;
- Info("%08x.%08x - %08x.%08x\n",
- Translated->u.Memory.Start.HighPart,
- Translated->u.Memory.Start.LowPart,
- End.HighPart,
- End.LowPart);
+ Trace("%08x - %08x\n", Start, Start + Count - 1);
return STATUS_SUCCESS;
fail3:
Error("fail3\n");
- XENBUS_RANGE_SET(Destroy,
+ XENBUS_RANGE_SET(Get,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet);
- Fdo->IoRangeSet = NULL;
+ Fdo->RangeSet,
+ Start,
+ Count);
fail2:
Error("fail2\n");
+ XENBUS_RANGE_SET(Destroy,
+ &Fdo->RangeSetInterface,
+ Fdo->RangeSet);
+ Fdo->RangeSet = NULL;
+
fail1:
Error("fail1 (%08x)\n", status);
}
NTSTATUS
-FdoAllocateIoSpace(
+FdoAllocateHole(
IN PXENBUS_FDO Fdo,
- IN ULONG Size,
- OUT PPHYSICAL_ADDRESS Address
+ IN ULONG Count,
+ OUT PVOID *VirtualAddress OPTIONAL,
+ OUT PPHYSICAL_ADDRESS PhysicalAddress
)
{
+ LONGLONG Start;
NTSTATUS status;
- ASSERT3U(Size & (PAGE_SIZE - 1), ==, 0);
-
status = XENBUS_RANGE_SET(Pop,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet,
- Size,
- &Address->QuadPart);
+ Fdo->RangeSet,
+ Count,
+ &Start);
if (!NT_SUCCESS(status))
goto fail1;
- ASSERT3U(Address->QuadPart & (PAGE_SIZE - 1), ==, 0);
+ Trace("%08x - %08x\n", Start, Start + Count - 1);
+
+ if (VirtualAddress != NULL) {
+ PUCHAR StartVa = Fdo->Buffer;
+ PMDL Mdl = Fdo->Mdl;
+ ULONG Index;
+ ULONG ByteOffset;
+
+ Index = (ULONG)((PFN_NUMBER)Start - MmGetMdlPfnArray(Mdl)[0]);
+ ByteOffset = Index * PAGE_SIZE;
+ ASSERT3U(ByteOffset, <=, Mdl->ByteCount);
+
+ *VirtualAddress = StartVa + ByteOffset;
+ }
+
+ PhysicalAddress->QuadPart = Start << PAGE_SHIFT;
return STATUS_SUCCESS;;
}
VOID
-FdoFreeIoSpace(
+FdoFreeHole(
IN PXENBUS_FDO Fdo,
- IN PHYSICAL_ADDRESS Address,
- IN ULONG Size
+ IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN ULONG Count
)
{
+ LONGLONG Start;
NTSTATUS status;
- ASSERT3U(Address.QuadPart & (PAGE_SIZE - 1), ==, 0);
- ASSERT3U(Size & (PAGE_SIZE - 1), ==, 0);
+ ASSERT3U(PhysicalAddress.QuadPart & (PAGE_SIZE - 1), ==, 0);
+ Start = PhysicalAddress.QuadPart >> PAGE_SHIFT;
+
+ Trace("%08x - %08x\n", Start, Start + Count - 1);
status = XENBUS_RANGE_SET(Put,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet,
- Address.QuadPart,
- Size);
+ Fdo->RangeSet,
+ Start,
+ Count);
ASSERT(NT_SUCCESS(status));
}
static VOID
-FdoDestroyIoSpace(
- IN PXENBUS_FDO Fdo
+FdoDestroyHole(
+ IN PXENBUS_FDO Fdo
)
{
- ULONG Index;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated;
- NTSTATUS status;
+ PMDL Mdl;
+ PFN_NUMBER Pfn;
+ LONGLONG Start;
+ ULONG Count;
+ NTSTATUS status;
- for (Index = 0; Index < Fdo->TranslatedResourceList->Count; Index++) {
- Translated = &Fdo->TranslatedResourceList->PartialDescriptors[Index];
+ Mdl = Fdo->Mdl;
- if (Translated->Type == CmResourceTypeMemory)
- goto found;
- }
+ Pfn = MmGetMdlPfnArray(Mdl)[0];
- ASSERT(FALSE);
- return;
+ Start = Pfn;
+ Count = BYTES_TO_PAGES(Mdl->ByteCount);
+
+ Trace("%08x - %08x\n", Start, Start + Count - 1);
+
+ if (MemoryPopulatePhysmap(PAGE_ORDER_2M, 1, &Pfn) != 1)
+ BUG("FAILED TO RE-POPULATE HOLE");
-found:
status = XENBUS_RANGE_SET(Get,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet,
- Translated->u.Memory.Start.QuadPart,
- Translated->u.Memory.Length);
+ Fdo->RangeSet,
+ Start,
+ Count);
ASSERT(NT_SUCCESS(status));
XENBUS_RANGE_SET(Destroy,
&Fdo->RangeSetInterface,
- Fdo->IoRangeSet);
- Fdo->IoRangeSet = NULL;
+ Fdo->RangeSet);
+ Fdo->RangeSet = NULL;
}
// This function must not touch pageable code or data
goto fail3;
// Subsequent interfaces require use of BAR space
- status = FdoCreateIoSpace(Fdo);
+ status = FdoCreateHole(Fdo);
if (!NT_SUCCESS(status))
goto fail4;
fail5:
Error("fail5\n");
- FdoDestroyIoSpace(Fdo);
+ FdoDestroyHole(Fdo);
fail4:
Error("fail4\n");
XENBUS_EVTCHN(Release, &Fdo->EvtchnInterface);
- FdoDestroyIoSpace(Fdo);
+ FdoDestroyHole(Fdo);
XENBUS_RANGE_SET(Release, &Fdo->RangeSetInterface);
(_Size), \
(_Optional))
+
+#define FDO_HOLE_SIZE (2ull << 20)
+
+static FORCEINLINE NTSTATUS
+__FdoAllocateBuffer(
+ IN PXENBUS_FDO Fdo
+ )
+{
+ ULONG Size;
+ PHYSICAL_ADDRESS Low;
+ PHYSICAL_ADDRESS High;
+ PHYSICAL_ADDRESS Align;
+ PVOID Buffer;
+ PMDL Mdl;
+ NTSTATUS status;
+
+ Size = 2 << 20;
+
+ 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->Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
+ Fdo->Mdl = Mdl;
+
+ 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
+ )
+{
+ ExFreePool(Fdo->Mdl);
+ Fdo->Mdl = NULL;
+
+ MmFreeContiguousMemory(Fdo->Buffer);
+ Fdo->Buffer = NULL;
+}
+
static BOOLEAN
FdoIsBalloonEnabled(
IN PXENBUS_FDO Fdo
if (!__FdoIsActive(Fdo))
goto done;
- status = DebugInitialize(Fdo, &Fdo->DebugContext);
+ status = __FdoAllocateBuffer(Fdo);
if (!NT_SUCCESS(status))
goto fail9;
- status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
+ status = DebugInitialize(Fdo, &Fdo->DebugContext);
if (!NT_SUCCESS(status))
goto fail10;
- status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
+ status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
if (!NT_SUCCESS(status))
goto fail11;
- status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
+ status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
if (!NT_SUCCESS(status))
goto fail12;
- status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
+ status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
if (!NT_SUCCESS(status))
goto fail13;
- status = CacheInitialize(Fdo, &Fdo->CacheContext);
+ status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
if (!NT_SUCCESS(status))
goto fail14;
- status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
+ status = CacheInitialize(Fdo, &Fdo->CacheContext);
if (!NT_SUCCESS(status))
goto fail15;
- status = StoreInitialize(Fdo, &Fdo->StoreContext);
+ status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
if (!NT_SUCCESS(status))
goto fail16;
- status = ConsoleInitialize(Fdo, &Fdo->ConsoleContext);
+ status = StoreInitialize(Fdo, &Fdo->StoreContext);
if (!NT_SUCCESS(status))
goto fail17;
- status = UnplugInitialize(Fdo, &Fdo->UnplugContext);
+ status = ConsoleInitialize(Fdo, &Fdo->ConsoleContext);
if (!NT_SUCCESS(status))
goto fail18;
+ status = UnplugInitialize(Fdo, &Fdo->UnplugContext);
+ if (!NT_SUCCESS(status))
+ goto fail19;
+
if (FdoIsBalloonEnabled(Fdo)) {
status = BalloonInitialize(Fdo, &Fdo->BalloonContext);
if (!NT_SUCCESS(status))
- goto fail19;
+ goto fail20;
}
status = DebugGetInterface(__FdoGetDebugContext(Fdo),
return STATUS_SUCCESS;
-fail19:
- Error("fail19\n");
+fail20:
+ Error("fail20\n");
UnplugTeardown(Fdo->UnplugContext);
Fdo->UnplugContext = NULL;
-fail18:
- Error("fail18\n");
+fail19:
+ Error("fail19\n");
ConsoleTeardown(Fdo->ConsoleContext);
Fdo->ConsoleContext = NULL;
-fail17:
- Error("fail17\n");
+fail18:
+ Error("fail18\n");
StoreTeardown(Fdo->StoreContext);
Fdo->StoreContext = NULL;
-fail16:
- Error("fail16\n");
+fail17:
+ Error("fail17\n");
GnttabTeardown(Fdo->GnttabContext);
Fdo->GnttabContext = NULL;
-fail15:
- Error("fail15\n");
+fail16:
+ Error("fail16\n");
CacheTeardown(Fdo->CacheContext);
Fdo->CacheContext = NULL;
-fail14:
- Error("fail14\n");
+fail15:
+ Error("fail15\n");
RangeSetTeardown(Fdo->RangeSetContext);
Fdo->RangeSetContext = NULL;
-fail13:
- Error("fail13\n");
+fail14:
+ Error("fail14\n");
EvtchnTeardown(Fdo->EvtchnContext);
Fdo->EvtchnContext = NULL;
-fail12:
- Error("fail12\n");
+fail13:
+ Error("fail13\n");
SharedInfoTeardown(Fdo->SharedInfoContext);
Fdo->SharedInfoContext = NULL;
-fail11:
- Error("fail11\n");
+fail12:
+ Error("fail12\n");
SuspendTeardown(Fdo->SuspendContext);
Fdo->SuspendContext = NULL;
-fail10:
- Error("fail10\n");
+fail11:
+ Error("fail11\n");
DebugTeardown(Fdo->DebugContext);
Fdo->DebugContext = NULL;
+fail10:
+ Error("fail10\n");
+
+ __FdoFreeBuffer(Fdo);
+
fail9:
Error("fail9\n");
DebugTeardown(Fdo->DebugContext);
Fdo->DebugContext = NULL;
+ __FdoFreeBuffer(Fdo);
+
FdoClearActive(Fdo);
}
PXENBUS_GNTTAB_MAP_ENTRY MapEntry;
NTSTATUS status;
- status = FdoAllocateIoSpace(Context->Fdo,
- NumberPages * PAGE_SIZE,
- Address);
+ status = FdoAllocateHole(Context->Fdo,
+ NumberPages,
+ NULL,
+ Address);
if (!NT_SUCCESS(status))
goto fail1;
fail2:
Error("fail2\n");
- FdoFreeIoSpace(Context->Fdo, *Address, NumberPages * PAGE_SIZE);
+ FdoFreeHole(Context->Fdo, *Address, NumberPages);
fail1:
Error("fail1: (%08x)\n", status);
PageAddress.QuadPart += PAGE_SIZE;
}
- FdoFreeIoSpace(Context->Fdo,
- Address,
- MapEntry->NumberPages * PAGE_SIZE);
+ FdoFreeHole(Context->Fdo,
+ Address,
+ MapEntry->NumberPages);
__GnttabFree(MapEntry);
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
PXENBUS_FDO Fdo = Context->Fdo;
KIRQL Irql;
- ULONG Size;
NTSTATUS status;
KeAcquireSpinLock(&Context->Lock, &Irql);
"GNTTAB: MAX FRAMES = %u\n",
Context->MaximumFrameCount);
- Size = Context->MaximumFrameCount * PAGE_SIZE;
-
- status = FdoAllocateIoSpace(Fdo,
- Size,
- &Context->Address);
+ status = FdoAllocateHole(Fdo,
+ Context->MaximumFrameCount,
+ &Context->Table,
+ &Context->Address);
if (!NT_SUCCESS(status))
goto fail2;
- Context->Table = (grant_entry_v1_t *)MmMapIoSpace(Context->Address,
- Size,
- MmCached);
- status = STATUS_UNSUCCESSFUL;
- if (Context->Table == NULL)
- goto fail3;
-
Context->FrameIndex = -1;
status = XENBUS_RANGE_SET(Acquire, &Context->RangeSetInterface);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail3;
status = XENBUS_RANGE_SET(Create,
&Context->RangeSetInterface,
"gnttab",
&Context->RangeSet);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail4;
status = XENBUS_CACHE(Acquire, &Context->CacheInterface);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail5;
status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail6;
status = XENBUS_SUSPEND(Register,
&Context->SuspendInterface,
Context,
&Context->SuspendCallbackEarly);
if (!NT_SUCCESS(status))
- goto fail8;
+ goto fail7;
status = XENBUS_DEBUG(Acquire, &Context->DebugInterface);
if (!NT_SUCCESS(status))
- goto fail9;
+ goto fail8;
status = XENBUS_DEBUG(Register,
&Context->DebugInterface,
Context,
&Context->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail10;
+ goto fail9;
/* Make sure at least the reserved refrences are present */
status = GnttabExpand(Context);
if (!NT_SUCCESS(status))
- goto fail11;
+ goto fail10;
Trace("<====\n");
return STATUS_SUCCESS;
-fail11:
- Error("fail11\n");
+fail10:
+ Error("fail10\n");
XENBUS_DEBUG(Deregister,
&Context->DebugInterface,
Context->DebugCallback);
Context->DebugCallback = NULL;
-fail10:
- Error("fail10\n");
+fail9:
+ Error("fail9\n");
XENBUS_DEBUG(Release, &Context->DebugInterface);
-fail9:
- Error("fail9\n");
+fail8:
+ Error("fail8\n");
XENBUS_SUSPEND(Deregister,
&Context->SuspendInterface,
Context->SuspendCallbackEarly);
Context->SuspendCallbackEarly = NULL;
-fail8:
- Error("fail8\n");
-
- XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
fail7:
Error("fail7\n");
- XENBUS_CACHE(Release, &Context->CacheInterface);
+ XENBUS_SUSPEND(Release, &Context->SuspendInterface);
fail6:
Error("fail6\n");
+ XENBUS_CACHE(Release, &Context->CacheInterface);
+
+fail5:
+ Error("fail5\n");
+
GnttabContract(Context);
ASSERT3S(Context->FrameIndex, ==, -1);
Context->FrameIndex = 0;
-fail5:
- Error("fail5\n");
-
- XENBUS_RANGE_SET(Release, &Context->RangeSetInterface);
-
fail4:
Error("fail4\n");
- MmUnmapIoSpace(Context->Table, Size);
- Context->Table = NULL;
+ XENBUS_RANGE_SET(Release, &Context->RangeSetInterface);
fail3:
Error("fail3\n");
- FdoFreeIoSpace(Fdo,
- Context->Address,
- Size);
+ FdoFreeHole(Fdo,
+ Context->Address,
+ Context->MaximumFrameCount);
Context->Address.QuadPart = 0;
+ Context->Table = NULL;
fail2:
Error("fail2\n");
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
PXENBUS_FDO Fdo = Context->Fdo;
KIRQL Irql;
- ULONG Size;
KeAcquireSpinLock(&Context->Lock, &Irql);
XENBUS_RANGE_SET(Release, &Context->RangeSetInterface);
- Size = Context->MaximumFrameCount * PAGE_SIZE;
-
- MmUnmapIoSpace(Context->Table, Size);
- Context->Table = NULL;
-
- FdoFreeIoSpace(Fdo,
- Context->Address,
- Size);
+ FdoFreeHole(Fdo,
+ Context->Address,
+ Context->MaximumFrameCount);
Context->Address.QuadPart = 0;
+ Context->Table = NULL;
Context->MaximumFrameCount = 0;
Trace("====>\n");
- status = FdoAllocateIoSpace(Fdo, PAGE_SIZE, &Context->Address);
+ status = FdoAllocateHole(Fdo, 1, &Context->Shared, &Context->Address);
if (!NT_SUCCESS(status))
goto fail1;
SharedInfoMap(Context);
-
- Context->Shared = (shared_info_t *)MmMapIoSpace(Context->Address,
- PAGE_SIZE,
- MmCached);
-
- status = STATUS_UNSUCCESSFUL;
- if (Context->Shared == NULL)
- goto fail2;
-
SharedInfoEvtchnMaskAll(Context);
status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail2;
status = XENBUS_SUSPEND(Register,
&Context->SuspendInterface,
Context,
&Context->SuspendCallbackEarly);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail3;
status = XENBUS_DEBUG(Acquire, &Context->DebugInterface);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail4;
status = XENBUS_DEBUG(Register,
&Context->DebugInterface,
Context,
&Context->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail5;
Trace("<====\n");
return STATUS_SUCCESS;
-fail6:
- Error("fail6\n");
+fail5:
+ Error("fail5\n");
XENBUS_DEBUG(Release, &Context->DebugInterface);
-fail5:
- Error("fail5\n");
+fail4:
+ Error("fail4\n");
XENBUS_SUSPEND(Deregister,
&Context->SuspendInterface,
Context->SuspendCallbackEarly);
Context->SuspendCallbackEarly = NULL;
-fail4:
- Error("fail4\n");
-
- XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
fail3:
Error("fail3\n");
- MmUnmapIoSpace(Context->Shared, PAGE_SIZE);
- Context->Shared = NULL;
+ XENBUS_SUSPEND(Release, &Context->SuspendInterface);
fail2:
Error("fail2\n");
SharedInfoUnmap(Context);
- FdoFreeIoSpace(Fdo, Context->Address, PAGE_SIZE);
+ FdoFreeHole(Fdo, Context->Address, 1);
Context->Address.QuadPart = 0;
+ Context->Shared = NULL;
fail1:
Error("fail1 (%08x)\n", status);
XENBUS_SUSPEND(Release, &Context->SuspendInterface);
- MmUnmapIoSpace(Context->Shared, PAGE_SIZE);
- Context->Shared = NULL;
-
SharedInfoUnmap(Context);
- FdoFreeIoSpace(Fdo, Context->Address, PAGE_SIZE);
+ FdoFreeHole(Fdo, Context->Address, 1);
Context->Address.QuadPart = 0;
+ Context->Shared = NULL;
Trace("<====\n");