[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |