[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 6/6] xencontrol: use IOCTL_XENIFACE_GNTTAB_*_V2 IOCTLs



By using the _V2 IOCTLs we can remove all code used for handling
RequestIds in legacy IOCTLs.

Signed-off-by: Rafał Wojdyła <omeg@xxxxxxxxxxxxxxxxxxxxxx>
---
 include/xencontrol.h                |  28 ++++-
 src/xencontrol/xencontrol.c         | 182 ++++++++++------------------
 src/xencontrol/xencontrol_private.h |  33 -----
 3 files changed, 91 insertions(+), 152 deletions(-)

diff --git a/include/xencontrol.h b/include/xencontrol.h
index 29cd208..04ef858 100644
--- a/include/xencontrol.h
+++ b/include/xencontrol.h
@@ -161,7 +161,7 @@ XcEvtchnUnmask(
     IN  ULONG LocalPort
     );
 
-/*! \brief Grant a \a RemoteDomain permission to access local memory pages
+/*! \brief Grant a \a RemoteDomain permission to access local newly allocated 
memory pages
     \param Xc Xencontrol handle returned by XcOpen()
     \param RemoteDomain ID of a remote domain that is being granted access
     \param NumberPages Number of 4k pages to grant access to
@@ -185,6 +185,32 @@ XcGnttabPermitForeignAccess(
     OUT ULONG *References
     );
 
+/*! \brief Grant a \a RemoteDomain permission to access local memory pages
+    \param Xc Xencontrol handle returned by XcOpen()
+    \param RemoteDomain ID of a remote domain that is being granted access
+    \param Address Address of the granted memory region, allocated by the 
driver if NULL
+    \param NumberPages Number of 4k pages to grant access to
+    \param NotifyOffset Offset of a byte in the granted region that will be 
set to 0 when the grant is revoked
+    \param NotifyPort Local port number of an open event channel that will be 
notified when the grant is revoked
+    \param Flags Grant options
+    \param SharedAddress Local user mode address of the granted memory region
+    \param References An array of Xen grant numbers for every granted page
+    \return Error code
+*/
+XENCONTROL_API
+DWORD
+XcGnttabPermitForeignAccess2(
+    IN  PXENCONTROL_CONTEXT Xc,
+    IN  USHORT RemoteDomain,
+    IN  PVOID Address,
+    IN  ULONG NumberPages,
+    IN  ULONG NotifyOffset,
+    IN  ULONG NotifyPort,
+    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
+    OUT PVOID* SharedAddress,
+    OUT ULONG* References
+);
+
 /*! \brief Revoke a foreign domain access to previously granted memory region
     \param Xc Xencontrol handle returned by XcOpen()
     \param Address Local user mode address of the granted memory region
diff --git a/src/xencontrol/xencontrol.c b/src/xencontrol/xencontrol.c
index 5cd9461..fe39e87 100644
--- a/src/xencontrol/xencontrol.c
+++ b/src/xencontrol/xencontrol.c
@@ -101,9 +101,6 @@ XcOpen(
 
     Context->Logger = Logger;
     Context->LogLevel = XLL_INFO;
-    Context->RequestId = 1;
-    InitializeListHead(&Context->RequestList);
-    InitializeCriticalSection(&Context->RequestListLock);
 
     DevInfo = SetupDiGetClassDevs(&GUID_INTERFACE_XENIFACE, 0, NULL, 
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
     if (DevInfo == INVALID_HANDLE_VALUE) {
@@ -179,7 +176,6 @@ XcClose(
     )
 {
     CloseHandle(Xc->XenIface);
-    DeleteCriticalSection(&Xc->RequestListLock);
     free(Xc);
 }
 
@@ -364,115 +360,104 @@ fail:
     return GetLastError();
 }
 
-static PXENCONTROL_GNTTAB_REQUEST
-FindRequest(
+DWORD
+XcGnttabPermitForeignAccess(
     IN  PXENCONTROL_CONTEXT Xc,
-    IN  PVOID Address
-    )
+    IN  USHORT RemoteDomain,
+    IN  ULONG NumberPages,
+    IN  ULONG NotifyOffset,
+    IN  ULONG NotifyPort,
+    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
+    OUT PVOID* SharedAddress,
+    OUT ULONG* References
+)
 {
-    PLIST_ENTRY Entry;
-    PXENCONTROL_GNTTAB_REQUEST ReturnRequest = NULL;
-
-    EnterCriticalSection(&Xc->RequestListLock);
-    Entry = Xc->RequestList.Flink;
-    while (Entry != &Xc->RequestList) {
-        PXENCONTROL_GNTTAB_REQUEST Request = CONTAINING_RECORD(Entry, 
XENCONTROL_GNTTAB_REQUEST, ListEntry);
-
-        if (Request->Address == Address) {
-            ReturnRequest = Request;
-            break;
-        }
-
-        Entry = Entry->Flink;
-    }
-    LeaveCriticalSection(&Xc->RequestListLock);
-
-    return ReturnRequest;
+    Log(XLL_DEBUG, L"RemoteDomain: %d, NumberPages: %lu, NotifyOffset: 0x%x, 
NotifyPort: %lu, Flags: 0x%x",
+        RemoteDomain, NumberPages, NotifyOffset, NotifyPort, Flags);
+
+    return XcGnttabPermitForeignAccess2(Xc,
+                                        RemoteDomain,
+                                        NULL,
+                                        NumberPages,
+                                        NotifyOffset,
+                                        NotifyPort,
+                                        Flags,
+                                        SharedAddress,
+                                        References);
 }
 
 DWORD
-XcGnttabPermitForeignAccess(
+XcGnttabPermitForeignAccess2(
     IN  PXENCONTROL_CONTEXT Xc,
     IN  USHORT RemoteDomain,
+    IN  PVOID Address,
     IN  ULONG NumberPages,
     IN  ULONG NotifyOffset,
     IN  ULONG NotifyPort,
     IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
-    OUT PVOID *Address,
+    OUT PVOID *SharedAddress,
     OUT ULONG *References
     )
 {
-    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_IN In;
-    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OUT *Out;
-    PXENCONTROL_GNTTAB_REQUEST Request;
+    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_IN_V2 In;
+    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OUT_V2 *Out;
     DWORD Returned, Size;
+    OVERLAPPED Overlapped;
     BOOL Success;
     DWORD Status;
 
-    // lock the whole operation to not generate duplicate IDs
-    EnterCriticalSection(&Xc->RequestListLock);
-
-    In.RequestId = Xc->RequestId;
     In.RemoteDomain = RemoteDomain;
+    In.Address = Address;
     In.NumberPages = NumberPages;
     In.NotifyOffset = NotifyOffset;
     In.NotifyPort = NotifyPort;
     In.Flags = Flags;
 
-    Size = (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OUT, 
References[NumberPages]);
+    Size = (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OUT_V2, 
References[NumberPages]);
     Out = malloc(Size);
-    Request = malloc(sizeof(*Request));
 
     Status = ERROR_OUTOFMEMORY;
-    if (!Request || !Out)
+    if (!Out)
         goto fail;
 
-    ZeroMemory(Request, sizeof(*Request));
-    Request->Id = In.RequestId;
-
-    Log(XLL_DEBUG, L"Id %lu, RemoteDomain: %d, NumberPages: %lu, NotifyOffset: 
0x%x, NotifyPort: %lu, Flags: 0x%x",
-        In.RequestId, RemoteDomain, NumberPages, NotifyOffset, NotifyPort, 
Flags);
+    Log(XLL_DEBUG, L"RemoteDomain: %d, Address %p, NumberPages: %lu, 
NotifyOffset: 0x%x, NotifyPort: %lu, Flags: 0x%x",
+        RemoteDomain, Address, NumberPages, NotifyOffset, NotifyPort, Flags);
 
+    ZeroMemory(&Overlapped, sizeof(Overlapped));
     Success = DeviceIoControl(Xc->XenIface,
-                              IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS,
+                              IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_V2,
                               &In, sizeof(In),
                               Out, Size,
                               &Returned,
-                              &Request->Overlapped);
+                              &Overlapped);
 
     Status = GetLastError();
     // this IOCTL is expected to be pending on success
     if (!Success) {
         if (Status != ERROR_IO_PENDING) {
-            Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS 
failed");
+            Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_V2 
failed");
             goto fail;
         }
     } else {
-        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS not 
pending");
+        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_V2 not 
pending");
         Status = ERROR_UNIDENTIFIED_ERROR;
         goto fail;
     }
 
-    Request->Address = Out->Address;
-
-    InsertTailList(&Xc->RequestList, &Request->ListEntry);
-    Xc->RequestId++;
-    LeaveCriticalSection(&Xc->RequestListLock);
-
-    *Address = Out->Address;
+    *SharedAddress = Out->Address;
     memcpy(References, &Out->References, NumberPages * sizeof(ULONG));
-    Log(XLL_DEBUG, L"Address: %p", *Address);
+    Log(XLL_DEBUG, L"Address: %p", Out->Address);
+#ifdef _DEBUG
     for (ULONG i = 0; i < NumberPages; i++)
         Log(XLL_DEBUG, L"Grant ref[%lu]: %lu", i, Out->References[i]);
+#endif
 
     free(Out);
     return ERROR_SUCCESS;
 
 fail:
-    LeaveCriticalSection(&Xc->RequestListLock);
     Log(XLL_ERROR, L"Error: 0x%x", Status);
     free(Out);
-    free(Request);
     return Status;
 }
 
@@ -482,25 +467,16 @@ XcGnttabRevokeForeignAccess(
     IN  PVOID Address
     )
 {
-    XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS_IN In;
-    PXENCONTROL_GNTTAB_REQUEST Request;
+    XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS_IN_V2 In;
     DWORD Returned;
     BOOL Success;
     DWORD Status;
 
     Log(XLL_DEBUG, L"Address: %p", Address);
-
-    Status = ERROR_NOT_FOUND;
-    Request = FindRequest(Xc, Address);
-    if (!Request) {
-        Log(XLL_ERROR, L"Address %p not granted", Address);
-        goto fail;
-    }
-
-    In.RequestId = Request->Id;
+    In.Address = Address;
 
     Success = DeviceIoControl(Xc->XenIface,
-                              IOCTL_XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS,
+                              IOCTL_XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS_V2,
                               &In, sizeof(In),
                               NULL, 0,
                               &Returned,
@@ -508,15 +484,10 @@ XcGnttabRevokeForeignAccess(
 
     Status = GetLastError();
     if (!Success) {
-        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS failed");
+        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS_V2 
failed");
         goto fail;
     }
 
-    EnterCriticalSection(&Xc->RequestListLock);
-    RemoveEntryList(&Request->ListEntry);
-    LeaveCriticalSection(&Xc->RequestListLock);
-    free(Request);
-
     return Status;
 
 fail:
@@ -536,24 +507,19 @@ XcGnttabMapForeignPages(
     OUT PVOID *Address
     )
 {
-    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN *In;
-    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_OUT Out;
-    PXENCONTROL_GNTTAB_REQUEST Request;
+    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN_V2 *In;
+    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_OUT_V2 Out;
     DWORD Returned, Size;
+    OVERLAPPED Overlapped;
     BOOL Success;
     DWORD Status;
 
-    // lock the whole operation to not generate duplicate IDs
-    EnterCriticalSection(&Xc->RequestListLock);
-
     Status = ERROR_OUTOFMEMORY;
-    Size = (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN, 
References[NumberPages]);
+    Size = (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN_V2, 
References[NumberPages]);
     In = malloc(Size);
-    Request = malloc(sizeof(*Request));
-    if (!In || !Request)
+    if (!In)
         goto fail;
 
-    In->RequestId = Xc->RequestId;
     In->RemoteDomain = RemoteDomain;
     In->NumberPages = NumberPages;
     In->NotifyOffset = NotifyOffset;
@@ -561,40 +527,35 @@ XcGnttabMapForeignPages(
     In->Flags = Flags;
     memcpy(&In->References, References, NumberPages * sizeof(ULONG));
 
-    ZeroMemory(Request, sizeof(*Request));
-    Request->Id = In->RequestId;
-
-    Log(XLL_DEBUG, L"Id %lu, RemoteDomain: %d, NumberPages: %lu, NotifyOffset: 
0x%x, NotifyPort: %lu, Flags: 0x%x",
-        In->RequestId, RemoteDomain, NumberPages, NotifyOffset, NotifyPort, 
Flags);
+    Log(XLL_DEBUG, L"RemoteDomain: %d, NumberPages: %lu, NotifyOffset: 0x%x, 
NotifyPort: %lu, Flags: 0x%x",
+        RemoteDomain, NumberPages, NotifyOffset, NotifyPort, Flags);
 
+#ifdef _DEBUG
     for (ULONG i = 0; i < NumberPages; i++)
         Log(XLL_DEBUG, L"Grant ref[%lu]: %lu", i, References[i]);
+#endif
 
+    ZeroMemory(&Overlapped, sizeof(Overlapped));
     Success = DeviceIoControl(Xc->XenIface,
-                              IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES,
+                              IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_V2,
                               In, Size,
                               &Out, sizeof(Out),
                               &Returned,
-                              &Request->Overlapped);
+                              &Overlapped);
 
     Status = GetLastError();
     // this IOCTL is expected to be pending on success
     if (!Success) {
         if (Status != ERROR_IO_PENDING) {
-            Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES failed");
+            Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_V2 
failed");
             goto fail;
         }
     } else {
-        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES not pending");
+        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_V2 not 
pending");
         Status = ERROR_UNIDENTIFIED_ERROR;
         goto fail;
     }
 
-    Request->Address = Out.Address;
-    InsertTailList(&Xc->RequestList, &Request->ListEntry);
-    Xc->RequestId++;
-    LeaveCriticalSection(&Xc->RequestListLock);
-
     *Address = Out.Address;
 
     Log(XLL_DEBUG, L"Address: %p", *Address);
@@ -603,10 +564,8 @@ XcGnttabMapForeignPages(
     return ERROR_SUCCESS;
 
 fail:
-    LeaveCriticalSection(&Xc->RequestListLock);
     Log(XLL_ERROR, L"Error: 0x%x", Status);
     free(In);
-    free(Request);
     return Status;
 }
 
@@ -616,25 +575,17 @@ XcGnttabUnmapForeignPages(
     IN  PVOID Address
     )
 {
-    XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN In;
-    PXENCONTROL_GNTTAB_REQUEST Request;
+    XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN_V2 In;
     DWORD Returned;
     BOOL Success;
     DWORD Status;
 
     Log(XLL_DEBUG, L"Address: %p", Address);
 
-    Status = ERROR_NOT_FOUND;
-    Request = FindRequest(Xc, Address);
-    if (!Request) {
-        Log(XLL_ERROR, L"Address %p not mapped", Address);
-        goto fail;
-    }
-
-    In.RequestId = Request->Id;
+    In.Address = Address;
 
     Success = DeviceIoControl(Xc->XenIface,
-                              IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES,
+                              IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_V2,
                               &In, sizeof(In),
                               NULL, 0,
                               &Returned,
@@ -642,15 +593,10 @@ XcGnttabUnmapForeignPages(
 
     Status = GetLastError();
     if (!Success) {
-        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES failed");
+        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_V2 failed");
         goto fail;
     }
 
-    EnterCriticalSection(&Xc->RequestListLock);
-    RemoveEntryList(&Request->ListEntry);
-    LeaveCriticalSection(&Xc->RequestListLock);
-    free(Request);
-
     return Status;
 
 fail:
diff --git a/src/xencontrol/xencontrol_private.h 
b/src/xencontrol/xencontrol_private.h
index 685bcfa..8a0076a 100644
--- a/src/xencontrol/xencontrol_private.h
+++ b/src/xencontrol/xencontrol_private.h
@@ -7,43 +7,10 @@
 #define Log(level, format, ...) \
         _Log(Xc->Logger, level, Xc->LogLevel, __FUNCTION__, format, 
__VA_ARGS__)
 
-#define InitializeListHead(ListHead) ( \
-    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
-
-#define InsertTailList(ListHead, Entry) { \
-    PLIST_ENTRY _EX_Blink; \
-    PLIST_ENTRY _EX_ListHead; \
-    _EX_ListHead = (ListHead); \
-    _EX_Blink = _EX_ListHead->Blink; \
-    (Entry)->Flink = _EX_ListHead; \
-    (Entry)->Blink = _EX_Blink; \
-    _EX_Blink->Flink = (Entry); \
-    _EX_ListHead->Blink = (Entry); \
-    }
-
-#define RemoveEntryList(Entry) { \
-    PLIST_ENTRY _EX_Blink; \
-    PLIST_ENTRY _EX_Flink; \
-    _EX_Flink = (Entry)->Flink; \
-    _EX_Blink = (Entry)->Blink; \
-    _EX_Blink->Flink = _EX_Flink; \
-    _EX_Flink->Blink = _EX_Blink; \
-    }
-
 typedef struct _XENCONTROL_CONTEXT {
     HANDLE XenIface;
     XENCONTROL_LOGGER *Logger;
     XENCONTROL_LOG_LEVEL LogLevel;
-    ULONG RequestId;
-    LIST_ENTRY RequestList;
-    CRITICAL_SECTION RequestListLock;
 } XENCONTROL_CONTEXT, *PXENCONTROL_CONTEXT;
 
-typedef struct _XENCONTROL_GNTTAB_REQUEST {
-    LIST_ENTRY  ListEntry;
-    OVERLAPPED  Overlapped;
-    ULONG       Id;
-    PVOID       Address;
-} XENCONTROL_GNTTAB_REQUEST, *PXENCONTROL_GNTTAB_REQUEST;
-
 #endif // _XENCONTROL_PRIVATE_H_
-- 
2.40.1.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.