ULONG MapHandles[1];
} XENBUS_GNTTAB_MAP_ENTRY, *PXENBUS_GNTTAB_MAP_ENTRY;
+typedef struct _XENBUS_GNTTAB_FRAME {
+ PMDL Mdl;
+ grant_entry_v1_t *Entry;
+} XENBUS_GNTTAB_FRAME, *PXENBUS_GNTTAB_FRAME;
+
struct _XENBUS_GNTTAB_CONTEXT {
PXENBUS_FDO Fdo;
KSPIN_LOCK Lock;
LONG References;
ULONG MaximumFrameCount;
- PMDL Mdl;
+ PXENBUS_GNTTAB_FRAME Frame;
LONG FrameIndex;
- grant_entry_v1_t *Table;
XENBUS_RANGE_SET_INTERFACE RangeSetInterface;
PXENBUS_RANGE_SET RangeSet;
XENBUS_CACHE_INTERFACE CacheInterface;
)
{
ULONG Index;
+ PXENBUS_GNTTAB_FRAME Frame;
+ PFN_NUMBER Pfn;
PHYSICAL_ADDRESS Address;
LONGLONG Start;
LONGLONG End;
if (Index == Context->MaximumFrameCount)
goto fail1;
- Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
- Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
+ Frame = &Context->Frame[Index];
+ Frame->Mdl = FdoHoleAllocate(Context->Fdo, 1);
- status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT),
- XENMAPSPACE_grant_table,
- Index);
- if (!NT_SUCCESS(status))
+ status = STATUS_NO_MEMORY;
+ if (Frame->Mdl == NULL)
goto fail2;
+ Frame->Entry = Frame->Mdl->StartVa;
+
+ Pfn = MmGetMdlPfnArray(Frame->Mdl)[0];
+
+ status = MemoryAddToPhysmap(Pfn, XENMAPSPACE_grant_table, Index);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ Address.QuadPart = Pfn << PAGE_SHIFT;
+
LogPrintf(LOG_LEVEL_INFO,
"GNTTAB: MAP XENMAPSPACE_grant_table[%d] @ %08x.%08x\n",
Index,
Start,
End + 1 - Start);
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail4;
Info("added references [%08llx - %08llx]\n", Start, End);
return STATUS_SUCCESS;
+fail4:
+ Error("fail4\n");
+
+ (VOID) MemoryRemoveFromPhysmap(Pfn);
+
fail3:
Error("fail3\n");
- (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT));
+ Frame->Entry = NULL;
+
+ FdoHoleFree(Context->Fdo, Frame->Mdl);
+ Frame->Mdl = NULL;
fail2:
Error("fail2\n");
NTSTATUS status;
for (Index = 0; Index <= Context->FrameIndex; Index++) {
- PHYSICAL_ADDRESS Address;
+ PXENBUS_GNTTAB_FRAME Frame = &Context->Frame[Index];
+ PFN_NUMBER Pfn;
+ PHYSICAL_ADDRESS Address;
- Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
- Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
+ Pfn = MmGetMdlPfnArray(Frame->Mdl)[0];
- status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT),
- XENMAPSPACE_grant_table,
- Index);
+ status = MemoryAddToPhysmap(Pfn, XENMAPSPACE_grant_table, Index);
ASSERT(NT_SUCCESS(status));
+ Address.QuadPart = Pfn << PAGE_SHIFT;
+
LogPrintf(LOG_LEVEL_INFO,
"GNTTAB: MAP XENMAPSPACE_grant_table[%d] @ %08x.%08x\n",
Index,
LONG Index;
for (Index = Context->FrameIndex; Index >= 0; --Index) {
- PHYSICAL_ADDRESS Address;
+ PXENBUS_GNTTAB_FRAME Frame = &Context->Frame[Index];
+ PFN_NUMBER Pfn;
- Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
- Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
+ Pfn = MmGetMdlPfnArray(Frame->Mdl)[0];
- (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT));
+ (VOID) MemoryRemoveFromPhysmap(Pfn);
LogPrintf(LOG_LEVEL_INFO,
"GNTTAB: UNMAP XENMAPSPACE_grant_table[%d]\n",
IN PXENBUS_GNTTAB_CONTEXT Context
)
{
+ LONG Index;
NTSTATUS status;
- GnttabUnmap(Context);
-
- if (Context->FrameIndex >= 0) {
- LONGLONG Start;
- LONGLONG End;
+ for (Index = Context->FrameIndex; Index >= 0; --Index) {
+ PXENBUS_GNTTAB_FRAME Frame = &Context->Frame[Index];
+ LONGLONG Start;
+ LONGLONG End;
+ PFN_NUMBER Pfn;
- Start = XENBUS_GNTTAB_RESERVED_ENTRY_COUNT;
- End = ((Context->FrameIndex + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME) - 1;
+ Start = __max(XENBUS_GNTTAB_RESERVED_ENTRY_COUNT,
+ Index * XENBUS_GNTTAB_ENTRY_PER_FRAME);
+ End = ((Index + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME) - 1;
status = XENBUS_RANGE_SET(Get,
&Context->RangeSetInterface,
ASSERT(NT_SUCCESS(status));
Info("removed refrences [%08llx - %08llx]\n", Start, End);
+
+ Pfn = MmGetMdlPfnArray(Frame->Mdl)[0];
+
+ (VOID) MemoryRemoveFromPhysmap(Pfn);
+
+ Frame->Entry = NULL;
+
+ FdoHoleFree(Context->Fdo, Frame->Mdl);
+ Frame->Mdl = NULL;
}
Context->FrameIndex = -1;
)
{
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
+ PXENBUS_GNTTAB_FRAME Frame;
+ ULONG Index;
NTSTATUS status;
*Entry = XENBUS_CACHE(Get,
if (*Entry == NULL)
goto fail1;
+ ASSERT3U((*Entry)->Reference, >=, XENBUS_GNTTAB_RESERVED_ENTRY_COUNT);
+ ASSERT3U((*Entry)->Reference, <, (Context->FrameIndex + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME);
+
(*Entry)->Entry.flags = (ReadOnly) ? GTF_readonly : 0;
(*Entry)->Entry.domid = Domain;
(*Entry)->Entry.frame = (uint32_t)Pfn;
ASSERT3U((*Entry)->Entry.frame, ==, Pfn);
- Context->Table[(*Entry)->Reference] = (*Entry)->Entry;
+ Frame = &Context->Frame[(*Entry)->Reference / XENBUS_GNTTAB_ENTRY_PER_FRAME];
+ Index = (*Entry)->Reference % XENBUS_GNTTAB_ENTRY_PER_FRAME;
+
+ Frame->Entry[Index] = (*Entry)->Entry;
KeMemoryBarrier();
- Context->Table[(*Entry)->Reference].flags |= GTF_permit_access;
+ Frame->Entry[Index].flags |= GTF_permit_access;
KeMemoryBarrier();
return STATUS_SUCCESS;
)
{
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
+ PXENBUS_GNTTAB_FRAME Frame;
+ ULONG Index;
volatile SHORT *flags;
ULONG Attempt;
NTSTATUS status;
ASSERT3U(Entry->Reference, >=, XENBUS_GNTTAB_RESERVED_ENTRY_COUNT);
ASSERT3U(Entry->Reference, <, (Context->FrameIndex + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME);
- flags = (volatile SHORT *)&Context->Table[Entry->Reference].flags;
+ Frame = &Context->Frame[Entry->Reference / XENBUS_GNTTAB_ENTRY_PER_FRAME];
+ Index = Entry->Reference % XENBUS_GNTTAB_ENTRY_PER_FRAME;
+
+ flags = (volatile SHORT *)&Frame->Entry[Index].flags;
Attempt = 0;
while (Attempt++ < 100) {
if (Attempt == 100)
goto fail1;
- RtlZeroMemory(&Context->Table[Entry->Reference],
- sizeof (grant_entry_v1_t));
- RtlZeroMemory(&Entry->Entry,
- sizeof (grant_entry_v1_t));
+ RtlZeroMemory(&Frame->Entry[Index], sizeof (grant_entry_v1_t));
+ RtlZeroMemory(&Entry->Entry, sizeof (grant_entry_v1_t));
XENBUS_CACHE(Put,
&Context->CacheInterface,
)
{
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
+ PXENBUS_GNTTAB_FRAME Frame;
+ ULONG Index;
NTSTATUS status;
status = STATUS_INVALID_PARAMETER;
if (Reference >= (Context->FrameIndex + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME)
goto fail1;
+ Frame = &Context->Frame[Reference / XENBUS_GNTTAB_ENTRY_PER_FRAME];
+ Index = Reference % XENBUS_GNTTAB_ENTRY_PER_FRAME;
+
if (Pfn != NULL)
- *Pfn = Context->Table[Reference].frame;
+ *Pfn = Frame->Entry[Index].frame;
if (ReadOnly != NULL)
- *ReadOnly = (Context->Table[Reference].flags & GTF_readonly) ? TRUE : FALSE;
+ *ReadOnly = (Frame->Entry[Index].flags & GTF_readonly) ? TRUE : FALSE;
return STATUS_SUCCESS;
)
{
PXENBUS_GNTTAB_CONTEXT Context = Argument;
- PHYSICAL_ADDRESS Address;
+ LONG Index;
UNREFERENCED_PARAMETER(Crashing);
- Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
+ for (Index = 0; Index <= Context->FrameIndex; Index++) {
+ PXENBUS_GNTTAB_FRAME Frame = &Context->Frame[Index];
+ PHYSICAL_ADDRESS Address;
- XENBUS_DEBUG(Printf,
- &Context->DebugInterface,
- "Address = %08x.%08x\n",
- Address.HighPart,
- Address.LowPart);
+ Address.QuadPart = MmGetMdlPfnArray(Frame->Mdl)[0] << PAGE_SHIFT;
- XENBUS_DEBUG(Printf,
- &Context->DebugInterface,
- "FrameIndex = %d\n",
- Context->FrameIndex);
+ XENBUS_DEBUG(Printf,
+ &Context->DebugInterface,
+ "[%u] Address = %08x.%08x\n",
+ Address.HighPart,
+ Address.LowPart);
+ }
}
NTSTATUS
)
{
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
- PXENBUS_FDO Fdo = Context->Fdo;
KIRQL Irql;
NTSTATUS status;
"GNTTAB: MAX FRAMES = %u\n",
Context->MaximumFrameCount);
- Context->Mdl = FdoHoleAllocate(Fdo, Context->MaximumFrameCount);
+ Context->Frame = __GnttabAllocate(Context->MaximumFrameCount * sizeof (XENBUS_GNTTAB_FRAME));
status = STATUS_NO_MEMORY;
- if (Context->Mdl == NULL)
+ if (Context->Frame == NULL)
goto fail2;
- Context->Table = Context->Mdl->StartVa;
Context->FrameIndex = -1;
status = XENBUS_RANGE_SET(Acquire, &Context->RangeSetInterface);
Context->RangeSet);
Context->RangeSet = NULL;
-
fail4:
Error("fail4\n");
Error("fail3\n");
Context->FrameIndex = 0;
- Context->Table = NULL;
- FdoHoleFree(Fdo, Context->Mdl);
- Context->Mdl = NULL;
+ __GnttabFree(Context->Frame);
+ Context->Frame = NULL;
fail2:
Error("fail2\n");
)
{
PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
- PXENBUS_FDO Fdo = Context->Fdo;
KIRQL Irql;
KeAcquireSpinLock(&Context->Lock, &Irql);
XENBUS_RANGE_SET(Release, &Context->RangeSetInterface);
Context->FrameIndex = 0;
- Context->Table = NULL;
- FdoHoleFree(Fdo, Context->Mdl);
- Context->Mdl = NULL;
+ __GnttabFree(Context->Frame);
+ Context->Frame = NULL;
Context->MaximumFrameCount = 0;