From patchwork Tue Apr 14 19:44:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitry Kozlyuk X-Patchwork-Id: 68443 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 61754A0577; Tue, 14 Apr 2020 21:44:51 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3942E1D37F; Tue, 14 Apr 2020 21:44:44 +0200 (CEST) Received: from mail-lj1-f196.google.com (mail-lj1-f196.google.com [209.85.208.196]) by dpdk.org (Postfix) with ESMTP id 982C31D15C for ; Tue, 14 Apr 2020 21:44:42 +0200 (CEST) Received: by mail-lj1-f196.google.com with SMTP id d8so1130784ljo.6 for ; Tue, 14 Apr 2020 12:44:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/LcieALohMA7P3wxubjSpXuQ8UhoSbJqvuQUj1XS5Ok=; b=BSCimoSxCSE2plgLDCdEuEAxnfc66sPBGb014guNGNLx4Q5Ms7ckDPETDoEgh+AGIQ lSDoISjso6HZB6ronnYWxCfHPvXOPESXY6wBkO6pRKe0KJGtELQ4MkKHYq0PZYpyDz/Z Wu045LsEain9b/A8sHiWxL+34Y4A+lyfdbYoco20MjkFsm6fGAa+fxKkjSU5Jbz1ry2D Li6lF7937HMMuzsJED0YiFKqSICATivnkEKmUQSXw5gT3KUpJzzjeZi//qM7BpEX9sAB TqktrVinkVZ7IrvNQ5KjwD3Ehs+qlc5Utss1Lo39NeQW+BVIUK7T0YQe4APkbKO6FZcz aiPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/LcieALohMA7P3wxubjSpXuQ8UhoSbJqvuQUj1XS5Ok=; b=nZrY+JUbuVBkNu64bJnr+k+asnrJlcQnmt74p855OUWegOj4Nazq3X81dSKAr9aPrX 61WnRCasclu09wGDC+dpT1WvOf+uFGLcND9IsCH2XnLNnriwQSfEdRjOLjHdGvGDu683 7QcEoo4oGXVYZg6xiqyqh5VeiCnG5EhAdWiubYL6Kja9FQsvYEu7hHhWrUQJbaKlLtEK 3RLdogyXaAGdOBc0de21Wgn3HiJAb0iZ3A82fi8lV9pdvLcV0TB7IYItjPgSX9R5bRrO V19/jiAeiaVI/t9ISqNxGefqM/juQNzZtLAv2+g4orl3Y2EeG9rbgZtXCRqDRnbxHIZh 7TNw== X-Gm-Message-State: AGi0Puaq0luLLCNVSVKrkhyFwLPN/tpRexXmYtu2rAtLsACsKDxZ00X5 3O/dJ56NSsVVUUIo87OvyOvNka0ereUP/g== X-Google-Smtp-Source: APiQypI7r1gNiJ7faKhTUWPqs1hRUb4lzhs47NU2tSNYqdPehgvhR0m3fKgNTHc/blqfCiDZ1KlIyw== X-Received: by 2002:a2e:9455:: with SMTP id o21mr1040038ljh.245.1586893481363; Tue, 14 Apr 2020 12:44:41 -0700 (PDT) Received: from localhost.localdomain (broadband-37-110-65-23.ip.moscow.rt.ru. [37.110.65.23]) by smtp.googlemail.com with ESMTPSA id h14sm11272426lfm.60.2020.04.14.12.44.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2020 12:44:40 -0700 (PDT) From: Dmitry Kozlyuk To: dev@dpdk.org Cc: "Dmitry Malloy (MESHCHANINOV)" , Narcisa Ana Maria Vasile , Fady Bader , Tal Shnaiderman , Dmitry Kozlyuk , Ranjit Menon Date: Tue, 14 Apr 2020 22:44:16 +0300 Message-Id: <20200414194426.1640704-2-dmitry.kozliuk@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200414194426.1640704-1-dmitry.kozliuk@gmail.com> References: <20200410164342.1194634-1-dmitry.kozliuk@gmail.com> <20200414194426.1640704-1-dmitry.kozliuk@gmail.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3 1/1] virt2phys: virtual to physical address translator for Windows X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This driver supports Windows EAL memory management by translating current process virtual addresses to physical addresses (IOVA). Standalone virt2phys allows using DPDK without PMD and provides a reference implementation. Suggested-by: Ranjit Menon Signed-off-by: Dmitry Kozlyuk Reviewed-by: Ranjit Menon Acked-by: Ranjit Menon --- windows/README.rst | 103 +++++++++ windows/virt2phys/virt2phys.c | 129 +++++++++++ windows/virt2phys/virt2phys.h | 34 +++ windows/virt2phys/virt2phys.inf | 64 ++++++ windows/virt2phys/virt2phys.sln | 27 +++ windows/virt2phys/virt2phys.vcxproj | 228 ++++++++++++++++++++ windows/virt2phys/virt2phys.vcxproj.filters | 36 ++++ 7 files changed, 621 insertions(+) create mode 100644 windows/README.rst create mode 100644 windows/virt2phys/virt2phys.c create mode 100644 windows/virt2phys/virt2phys.h create mode 100644 windows/virt2phys/virt2phys.inf create mode 100644 windows/virt2phys/virt2phys.sln create mode 100644 windows/virt2phys/virt2phys.vcxproj create mode 100644 windows/virt2phys/virt2phys.vcxproj.filters diff --git a/windows/README.rst b/windows/README.rst new file mode 100644 index 0000000..45a1d80 --- /dev/null +++ b/windows/README.rst @@ -0,0 +1,103 @@ +Developing Windows Drivers +========================== + +Prerequisites +------------- + +Building Windows Drivers is only possible on Windows. + +1. Visual Studio 2019 Community or Professional Edition +2. Windows Driver Kit (WDK) for Windows 10, version 1903 + +Follow the official instructions to obtain all of the above: +https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk + + +Build the Drivers +----------------- + +Build from Visual Studio +~~~~~~~~~~~~~~~~~~~~~~~~ + +Open a solution (``*.sln``) with Visual Studio and build it (Ctrl+Shift+B). + + +Build from Command-Line +~~~~~~~~~~~~~~~~~~~~~~~ + +Run *Developer Command Prompt for VS 2019* from the Start menu. + +Navigate to the solution directory (with ``*.sln``), then run: + +.. code-block:: console + + msbuild + +To build a particular combination of configuration and platform: + +.. code-block:: console + + msbuild -p:Configuration=Debug;Platform=x64 + + +Install the Drivers +------------------- + +Disable Driver Signature Enforcement +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default Windows prohibits installing and loading drivers without `digital +signature`_ obtained from Microsoft. For development signature enforcement may +be disabled as follows. + +In Elevated Command Prompt (from this point, sufficient privileges are +assumed): + +.. code-block:: console + + bcdedit -set loadoptions DISABLE_INTEGRITY_CHECKS + bcdedit -set TESTSIGNING ON + shutdown -r -t 0 + +Upon reboot, an overlay message should appear on the desktop informing +that Windows is in test mode, which means it allows loading unsigned drivers. + +.. _digital signature: https://docs.microsoft.com/en-us/windows-hardware/drivers/install/driver-signing + +Install, List, and Remove Drivers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Driver package is by default located in a subdirectory of its source tree, +e.g. ``x64\Debug\virt2phys\virt2phys`` (note two levels of ``virt2phys``). + +To install the driver and bind associated devices to it: + +.. code-block:: console + + pnputil /add-driver x64\Debug\virt2phys\virt2phys\virt2phys.inf /install + +A graphical confirmation to load an unsigned driver will still appear. + +On Windows Server additional steps are required if the driver uses a custom +setup class: + +1. From "Device Manager", "Action" menu, select "Add legacy hardware". +2. It will launch the "Add Hardware Wizard". Click "Next". +3. Select second option "Install the hardware that I manually select + from a list (Advanced)". +4. On the next screen, locate the driver device class. +5. Select it, and click "Next". +6. The previously installed drivers will now be installed for + the appropriate devices (software devices will be created). + +To list installed drivers: + +.. code-block:: console + + pnputil /enum-drivers + +To remove the driver package and to uninstall its devices: + +.. code-block:: console + + pnputil /delete-driver oem2.inf /uninstall diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c new file mode 100644 index 0000000..e157e9c --- /dev/null +++ b/windows/virt2phys/virt2phys.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Dmitry Kozlyuk + */ + +#include +#include +#include +#include + +#include "virt2phys.h" + +DRIVER_INITIALIZE DriverEntry; +EVT_WDF_DRIVER_DEVICE_ADD virt2phys_driver_EvtDeviceAdd; +EVT_WDF_IO_IN_CALLER_CONTEXT virt2phys_device_EvtIoInCallerContext; + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT driver_object, IN PUNICODE_STRING registry_path) +{ + WDF_DRIVER_CONFIG config; + WDF_OBJECT_ATTRIBUTES attributes; + NTSTATUS status; + + PAGED_CODE(); + + WDF_DRIVER_CONFIG_INIT(&config, virt2phys_driver_EvtDeviceAdd); + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + status = WdfDriverCreate( + driver_object, registry_path, + &attributes, &config, WDF_NO_HANDLE); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate() failed, status=%08x\n", status)); + } + + return status; +} + +_Use_decl_annotations_ +NTSTATUS +virt2phys_driver_EvtDeviceAdd( + WDFDRIVER driver, PWDFDEVICE_INIT init) +{ + WDF_OBJECT_ATTRIBUTES attributes; + WDFDEVICE device; + NTSTATUS status; + + UNREFERENCED_PARAMETER(driver); + + PAGED_CODE(); + + WdfDeviceInitSetIoType( + init, WdfDeviceIoNeither); + WdfDeviceInitSetIoInCallerContextCallback( + init, virt2phys_device_EvtIoInCallerContext); + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + + status = WdfDeviceCreate(&init, &attributes, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate() failed, status=%08x\n", status)); + return status; + } + + status = WdfDeviceCreateDeviceInterface( + device, &GUID_DEVINTERFACE_VIRT2PHYS, NULL); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreateDeviceInterface() failed, " + "status=%08x\n", status)); + return status; + } + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ +VOID +virt2phys_device_EvtIoInCallerContext( + IN WDFDEVICE device, IN WDFREQUEST request) +{ + WDF_REQUEST_PARAMETERS params; + ULONG code; + PVOID *virt; + PHYSICAL_ADDRESS *phys; + size_t size; + NTSTATUS status; + + UNREFERENCED_PARAMETER(device); + + PAGED_CODE(); + + WDF_REQUEST_PARAMETERS_INIT(¶ms); + WdfRequestGetParameters(request, ¶ms); + + if (params.Type != WdfRequestTypeDeviceControl) { + KdPrint(("bogus request type=%u\n", params.Type)); + WdfRequestComplete(request, STATUS_NOT_SUPPORTED); + return; + } + + code = params.Parameters.DeviceIoControl.IoControlCode; + if (code != IOCTL_VIRT2PHYS_TRANSLATE) { + KdPrint(("bogus IO control code=%lu\n", code)); + WdfRequestComplete(request, STATUS_NOT_SUPPORTED); + return; + } + + status = WdfRequestRetrieveInputBuffer( + request, sizeof(*virt), (PVOID *)&virt, &size); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfRequestRetrieveInputBuffer() failed, " + "status=%08x\n", status)); + WdfRequestComplete(request, status); + return; + } + + status = WdfRequestRetrieveOutputBuffer( + request, sizeof(*phys), (PVOID *)&phys, &size); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfRequestRetrieveOutputBuffer() failed, " + "status=%08x\n", status)); + WdfRequestComplete(request, status); + return; + } + + *phys = MmGetPhysicalAddress(*virt); + + WdfRequestCompleteWithInformation( + request, STATUS_SUCCESS, sizeof(*phys)); +} diff --git a/windows/virt2phys/virt2phys.h b/windows/virt2phys/virt2phys.h new file mode 100644 index 0000000..4bb2b4a --- /dev/null +++ b/windows/virt2phys/virt2phys.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Dmitry Kozlyuk + */ + +/** + * @file virt2phys driver interface + */ + +/** + * Driver device interface GUID {539c2135-793a-4926-afec-d3a1b61bbc8a}. + */ +DEFINE_GUID(GUID_DEVINTERFACE_VIRT2PHYS, + 0x539c2135, 0x793a, 0x4926, + 0xaf, 0xec, 0xd3, 0xa1, 0xb6, 0x1b, 0xbc, 0x8a); + +/** + * Driver device type for IO control codes. + */ +#define VIRT2PHYS_DEVTYPE 0x8000 + +/** + * Translate a valid non-paged virtual address to a physical address. + * + * Note: A physical address zero (0) is reported if input address + * is paged out or not mapped. However, if input is a valid mapping + * of I/O port 0x0000, output is also zero. There is no way + * to distinguish between these cases by return value only. + * + * Input: a non-paged virtual address (PVOID). + * + * Output: the corresponding physical address (LARGE_INTEGER). + */ +#define IOCTL_VIRT2PHYS_TRANSLATE CTL_CODE( \ + VIRT2PHYS_DEVTYPE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) diff --git a/windows/virt2phys/virt2phys.inf b/windows/virt2phys/virt2phys.inf new file mode 100644 index 0000000..e35765e --- /dev/null +++ b/windows/virt2phys/virt2phys.inf @@ -0,0 +1,64 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright (c) 2020 Dmitry Kozlyuk + +[Version] +Signature = "$WINDOWS NT$" +Class = %ClassName% +ClassGuid = {78A1C341-4539-11d3-B88D-00C04FAD5171} +Provider = %ManufacturerName% +CatalogFile = virt2phys.cat +DriverVer = + +[DestinationDirs] +DefaultDestDir = 12 + +; ================= Class section ===================== + +[ClassInstall32] +Addreg = virt2phys_ClassReg + +[virt2phys_ClassReg] +HKR,,,0,%ClassName% +HKR,,Icon,,-5 + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] +virt2phys.sys = 1,, + +;***************************************** +; Install Section +;***************************************** + +[Manufacturer] +%ManufacturerName%=Standard,NT$ARCH$ + +[Standard.NT$ARCH$] +%virt2phys.DeviceDesc%=virt2phys_Device, Root\virt2phys + +[virt2phys_Device.NT] +CopyFiles = Drivers_Dir + +[Drivers_Dir] +virt2phys.sys + +;-------------- Service installation +[virt2phys_Device.NT.Services] +AddService = virt2phys,%SPSVCINST_ASSOCSERVICE%, virt2phys_Service_Inst + +; -------------- virt2phys driver install sections +[virt2phys_Service_Inst] +DisplayName = %virt2phys.SVCDESC% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %12%\virt2phys.sys + +[Strings] +SPSVCINST_ASSOCSERVICE = 0x00000002 +ManufacturerName = "Dmitry Kozlyuk" +ClassName = "Kernel bypass" +DiskName = "virt2phys Installation Disk" +virt2phys.DeviceDesc = "Virtual to physical address translator" +virt2phys.SVCDESC = "virt2phys Service" diff --git a/windows/virt2phys/virt2phys.sln b/windows/virt2phys/virt2phys.sln new file mode 100644 index 0000000..0f5ecdc --- /dev/null +++ b/windows/virt2phys/virt2phys.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29613.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "virt2phys", "virt2phys.vcxproj", "{0EEF826B-9391-43A8-A722-BDD6F6115137}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Debug|x64.ActiveCfg = Debug|x64 + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Debug|x64.Build.0 = Debug|x64 + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Debug|x64.Deploy.0 = Debug|x64 + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Release|x64.ActiveCfg = Release|x64 + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Release|x64.Build.0 = Release|x64 + {0EEF826B-9391-43A8-A722-BDD6F6115137}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {845012FB-4471-4A12-A1C4-FF7E05C40E8E} + EndGlobalSection +EndGlobal diff --git a/windows/virt2phys/virt2phys.vcxproj b/windows/virt2phys/virt2phys.vcxproj new file mode 100644 index 0000000..fa51916 --- /dev/null +++ b/windows/virt2phys/virt2phys.vcxproj @@ -0,0 +1,228 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + + + + + + + + + + {0EEF826B-9391-43A8-A722-BDD6F6115137} + {497e31cb-056b-4f31-abb8-447fd55ee5a5} + v4.5 + 12.0 + Debug + Win32 + virt2phys + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + true + true + trace.h + true + + + + + true + true + trace.h + true + + + + + false + true + trace.h + true + + + $(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies) + + + 0.1 + + + + + true + true + trace.h + true + + + + + true + true + trace.h + true + + + + + true + true + trace.h + true + + + + + true + true + trace.h + true + + + + + true + true + trace.h + true + + + + + + + + + \ No newline at end of file diff --git a/windows/virt2phys/virt2phys.vcxproj.filters b/windows/virt2phys/virt2phys.vcxproj.filters new file mode 100644 index 0000000..0fe65fc --- /dev/null +++ b/windows/virt2phys/virt2phys.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Header Files + + + + + Source Files + + +