|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 1/2] Add foreign page mapping functions to the GNTTAB interface
GNTTAB interface now includes functions to map and unmap memory pages
granted by a foreign domain. The page(s) are mapped under an address
allocated from the PCI BAR space.
Signed-off-by: RafaÅ WojdyÅa <omeg@xxxxxxxxxxxxxxxxxxxxxx>
---
include/gnttab_interface.h | 62 +++++++++++++++++++++++-
include/xen.h | 19 ++++++++
src/xen/grant_table.c | 85 +++++++++++++++++++++++++++++++++
src/xenbus/gnttab.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 278 insertions(+), 2 deletions(-)
diff --git a/include/gnttab_interface.h b/include/gnttab_interface.h
index d29440a..0016888 100644
--- a/include/gnttab_interface.h
+++ b/include/gnttab_interface.h
@@ -163,6 +163,47 @@ typedef VOID
IN PXENBUS_GNTTAB_CACHE Cache
);
+/*! \typedef XENBUS_GNTTAB_MAP_FOREIGN_PAGES
+ \brief Map foreign memory pages into the system address space
+
+ \param Interface The interface header
+ \param Domain The domid of the foreign domain that granted the pages
+ \param NumberPages Number of pages to map
+ \param References Array of grant reference numbers shared by the foreign
domain
+ \param ReadOnly If TRUE, pages are mapped with read-only access
+ \param Address The physical address that the foreign pages are mapped under
+ (allocated from the PCI IO space)
+ \param Handles An array of tracking numbers that represent the mapping
+ of each individual page
+ */
+
+typedef NTSTATUS
+(*XENBUS_GNTTAB_MAP_FOREIGN_PAGES)(
+ IN PINTERFACE Interface,
+ IN USHORT Domain,
+ IN ULONG NumberPages,
+ IN PULONG References,
+ IN BOOLEAN ReadOnly,
+ OUT PHYSICAL_ADDRESS *Address,
+ OUT ULONG *Handles
+ );
+
+/*! \typedef XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES
+ \brief Unmap foreign memory pages from the system address space
+
+ \param Interface The interface header
+ \param NumberPages Number of pages to unmap
+ \param Address The physical address that the foreign pages are mapped under
+ \param Handles An array of tracking numbers that represent the mapping
+ */
+typedef NTSTATUS
+(*XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES)(
+ IN PINTERFACE Interface,
+ IN ULONG NumberPages,
+ IN PHYSICAL_ADDRESS Address,
+ IN PULONG Handles
+ );
+
// {763679C5-E5C2-4A6D-8B88-6BB02EC42D8E}
DEFINE_GUID(GUID_XENBUS_GNTTAB_INTERFACE,
0x763679c5, 0xe5c2, 0x4a6d, 0x8b, 0x88, 0x6b, 0xb0, 0x2e, 0xc4, 0x2d, 0x8e);
@@ -182,7 +223,24 @@ struct _XENBUS_GNTTAB_INTERFACE_V1 {
XENBUS_GNTTAB_DESTROY_CACHE GnttabDestroyCache;
};
-typedef struct _XENBUS_GNTTAB_INTERFACE_V1 XENBUS_GNTTAB_INTERFACE,
*PXENBUS_GNTTAB_INTERFACE;
+/*! \struct _XENBUS_GNTTAB_INTERFACE_V2
+ \brief GNTTAB interface version 2 (added map/unmap foreign pages)
+ \ingroup interfaces
+ */
+struct _XENBUS_GNTTAB_INTERFACE_V2 {
+ INTERFACE Interface;
+ XENBUS_GNTTAB_ACQUIRE GnttabAcquire;
+ XENBUS_GNTTAB_RELEASE GnttabRelease;
+ XENBUS_GNTTAB_CREATE_CACHE GnttabCreateCache;
+ XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
+ XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
+ XENBUS_GNTTAB_GET_REFERENCE GnttabGetReference;
+ XENBUS_GNTTAB_DESTROY_CACHE GnttabDestroyCache;
+ XENBUS_GNTTAB_MAP_FOREIGN_PAGES GnttabMapForeignPages;
+ XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES GnttabUnmapForeignPages;
+};
+
+typedef struct _XENBUS_GNTTAB_INTERFACE_V2 XENBUS_GNTTAB_INTERFACE,
*PXENBUS_GNTTAB_INTERFACE;
/*! \def XENBUS_GNTTAB
\brief Macro at assist in method invocation
@@ -193,7 +251,7 @@ typedef struct _XENBUS_GNTTAB_INTERFACE_V1
XENBUS_GNTTAB_INTERFACE, *PXENBUS_GNT
#endif // _WINDLL
#define XENBUS_GNTTAB_INTERFACE_VERSION_MIN 1
-#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 1
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 2
#endif // _XENBUS_GNTTAB_INTERFACE_H
diff --git a/include/xen.h b/include/xen.h
index 6007582..23c7ac0 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -258,6 +258,25 @@ GrantTableCopy(
IN ULONG Count
);
+__checkReturn
+XEN_API
+NTSTATUS
+GrantTableMapForeignPage(
+ IN USHORT Domain,
+ IN ULONG GrantRef,
+ IN PHYSICAL_ADDRESS Address,
+ IN BOOLEAN ReadOnly,
+ OUT ULONG *Handle
+ );
+
+__checkReturn
+XEN_API
+NTSTATUS
+GrantTableUnmapForeignPage(
+ IN ULONG Handle,
+ IN PHYSICAL_ADDRESS Address
+ );
+
// SCHED
__checkReturn
diff --git a/src/xen/grant_table.c b/src/xen/grant_table.c
index 6facb3f..6450062 100644
--- a/src/xen/grant_table.c
+++ b/src/xen/grant_table.c
@@ -131,3 +131,88 @@ fail1:
return status;
}
+
+__checkReturn
+XEN_API
+NTSTATUS
+GrantTableMapForeignPage(
+ IN USHORT Domain,
+ IN ULONG GrantRef,
+ IN PHYSICAL_ADDRESS Address,
+ IN BOOLEAN ReadOnly,
+ OUT ULONG *Handle
+ )
+{
+ struct gnttab_map_grant_ref op;
+ LONG_PTR rc;
+ NTSTATUS status;
+
+ RtlZeroMemory(&op, sizeof(op));
+ op.dom = Domain;
+ op.ref = GrantRef;
+ op.flags = GNTMAP_host_map;
+ if (ReadOnly)
+ op.flags |= GNTMAP_readonly;
+ op.host_addr = Address.QuadPart;
+
+ rc = GrantTableOp(GNTTABOP_map_grant_ref, &op, 1);
+
+ if (rc < 0) {
+ ERRNO_TO_STATUS(-rc, status);
+ goto fail1;
+ }
+
+ if (op.status != GNTST_okay) {
+ status = STATUS_UNSUCCESSFUL;
+ goto fail2;
+ }
+
+ *Handle = op.handle;
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2: op.status = %d\n", op.status);
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+__checkReturn
+XEN_API
+NTSTATUS
+GrantTableUnmapForeignPage(
+ IN ULONG Handle,
+ IN PHYSICAL_ADDRESS Address
+ )
+{
+ struct gnttab_unmap_grant_ref op;
+ LONG_PTR rc;
+ NTSTATUS status;
+
+ RtlZeroMemory(&op, sizeof(op));
+ op.handle = Handle;
+ op.host_addr = Address.QuadPart;
+
+ rc = GrantTableOp(GNTTABOP_unmap_grant_ref, &op, 1);
+
+ if (rc < 0) {
+ ERRNO_TO_STATUS(-rc, status);
+ goto fail1;
+ }
+
+ if (op.status != GNTST_okay) {
+ status = STATUS_UNSUCCESSFUL;
+ goto fail2;
+ }
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("op.status = %d\n", op.status);
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
diff --git a/src/xenbus/gnttab.c b/src/xenbus/gnttab.c
index 165e38f..24d45af 100644
--- a/src/xenbus/gnttab.c
+++ b/src/xenbus/gnttab.c
@@ -534,6 +534,90 @@ GnttabGetReference(
return (ULONG)Entry->Reference;
}
+static NTSTATUS
+GnttabMapForeignPages(
+ IN PINTERFACE Interface,
+ IN USHORT Domain,
+ IN ULONG NumberPages,
+ IN PULONG References,
+ IN BOOLEAN ReadOnly,
+ OUT PHYSICAL_ADDRESS *Address,
+ OUT ULONG *Handles
+ )
+{
+ NTSTATUS status;
+ PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
+ ULONG PageIndex;
+ PHYSICAL_ADDRESS PageAddress;
+
+ status = FdoAllocateIoSpace(Context->Fdo, NumberPages * PAGE_SIZE,
Address);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ PageAddress.QuadPart = Address->QuadPart;
+
+ for (PageIndex = 0; PageIndex < NumberPages; PageIndex++) {
+ status = GrantTableMapForeignPage(Domain,
+ References[PageIndex],
+ PageAddress,
+ ReadOnly,
+ &(Handles[PageIndex]));
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ PageAddress.QuadPart += PAGE_SIZE;
+ }
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2: PageIndex %lu, PageAddress %p, Handle %lu\n", PageIndex,
PageAddress.QuadPart, Handles[PageIndex]);
+
+ while (PageIndex > 0) {
+ --PageIndex;
+ PageAddress.QuadPart -= PAGE_SIZE;
+ ASSERT(NT_SUCCESS(GrantTableUnmapForeignPage(Handles[PageIndex],
PageAddress)));
+ }
+
+ FdoFreeIoSpace(Context->Fdo, *Address, NumberPages * PAGE_SIZE);
+
+fail1:
+ Error("fail1: (%08x)\n", status);
+ return status;
+}
+
+static NTSTATUS
+GnttabUnmapForeignPages(
+ IN PINTERFACE Interface,
+ IN ULONG NumberPages,
+ IN PHYSICAL_ADDRESS Address,
+ IN PULONG Handles
+ )
+{
+ NTSTATUS status;
+ PXENBUS_GNTTAB_CONTEXT Context = Interface->Context;
+ ULONG PageIndex;
+ PHYSICAL_ADDRESS PageAddress;
+
+ PageAddress.QuadPart = Address.QuadPart;
+
+ for (PageIndex = 0; PageIndex < NumberPages; PageIndex++) {
+ status = GrantTableUnmapForeignPage(Handles[PageIndex], PageAddress);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ PageAddress.QuadPart += PAGE_SIZE;
+ }
+
+ FdoFreeIoSpace(Context->Fdo, Address, NumberPages * PAGE_SIZE);
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1: (%08x), leaking memory at %p, size 0x%lx. PageIndex = %lu,
PageAddress = %p, Handle = %lu\n",
+ status, Address.QuadPart, NumberPages * PAGE_SIZE, PageIndex,
PageAddress.QuadPart, Handles[PageIndex]);
+ return status;
+}
+
static VOID
GnttabSuspendCallbackEarly(
IN PVOID Argument
@@ -789,6 +873,19 @@ static struct _XENBUS_GNTTAB_INTERFACE_V1
GnttabInterfaceVersion1 = {
GnttabDestroyCache
};
+static struct _XENBUS_GNTTAB_INTERFACE_V2 GnttabInterfaceVersion2 = {
+ { sizeof(struct _XENBUS_GNTTAB_INTERFACE_V2), 2, NULL, NULL, NULL },
+ GnttabAcquire,
+ GnttabRelease,
+ GnttabCreateCache,
+ GnttabPermitForeignAccess,
+ GnttabRevokeForeignAccess,
+ GnttabGetReference,
+ GnttabDestroyCache,
+ GnttabMapForeignPages,
+ GnttabUnmapForeignPages
+};
+
NTSTATUS
GnttabInitialize(
IN PXENBUS_FDO Fdo,
@@ -878,6 +975,23 @@ GnttabGetInterface(
status = STATUS_SUCCESS;
break;
}
+ case 2: {
+ struct _XENBUS_GNTTAB_INTERFACE_V2 *GnttabInterface;
+
+ GnttabInterface = (struct _XENBUS_GNTTAB_INTERFACE_V2 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof(struct _XENBUS_GNTTAB_INTERFACE_V2))
+ break;
+
+ *GnttabInterface = GnttabInterfaceVersion2;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |