From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/HostDrivers/VBoxPci/linux/Makefile | 81 ++ src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup | 0 src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c | 1186 ++++++++++++++++++++ src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci | 111 ++ 4 files changed, 1378 insertions(+) create mode 100644 src/VBox/HostDrivers/VBoxPci/linux/Makefile create mode 100644 src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup create mode 100644 src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c create mode 100755 src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci (limited to 'src/VBox/HostDrivers/VBoxPci/linux') diff --git a/src/VBox/HostDrivers/VBoxPci/linux/Makefile b/src/VBox/HostDrivers/VBoxPci/linux/Makefile new file mode 100644 index 00000000..bbcefe76 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxPci/linux/Makefile @@ -0,0 +1,81 @@ +# $Id: Makefile $ +## @file +# Makefile for the VirtualBox Linux Host PCI Driver. +# + +# +# Copyright (C) 2011-2023 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.org. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, in version 3 of the +# License. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +# in the VirtualBox distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# +# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +# + + +# Linux kbuild sets this to our source directory if we are called from there +obj ?= $(CURDIR) +include $(obj)/Makefile-header.gmk +VBOXPCI_DIR := $(VBOX_MODULE_SRC_DIR) + +# Allow building directly from the subdirectory without assuming the toplevel +# makefile has done the copying. Not the default use case, but can be handy. +ifndef KBUILD_EXTRA_SYMBOLS +KBUILD_EXTRA_SYMBOLS=$(abspath $(VBOXPCI_DIR)/../vboxdrv/Module.symvers) +endif + +# override is required by the Debian guys +VBOXMOD_NAME = vboxpci +VBOXMOD_OBJS = \ + linux/VBoxPci-linux.o \ + VBoxPci.o \ + SUPR0IdcClient.o \ + SUPR0IdcClientComponent.o \ + linux/SUPR0IdcClient-linux.o +ifeq ($(VBOX_KBUILD_TARGET_ARCH),x86) +VBOXMOD_OBJS += \ + math/gcc/divdi3.o \ + math/gcc/moddi3.o \ + math/gcc/qdivrem.o \ + math/gcc/udivdi3.o \ + math/gcc/udivmoddi4.o \ + math/gcc/divdi3.o \ + math/gcc/umoddi3.o +endif +VBOXMOD_INCL = \ + $(VBOXPCI_DIR) \ + $(VBOXPCI_DIR)include \ + $(VBOXPCI_DIR)r0drv/linux +VBOXMOD_DEFS = \ + RT_OS_LINUX \ + IN_RING0 \ + IN_RT_R0 \ + IN_SUP_R0 \ + VBOX \ + RT_WITH_VBOX \ + VBOX_WITH_HARDENING +VBOXMOD_CFLAGS = -include $(VBOXPCI_DIR)include/VBox/SUPDrvMangling.h -fno-pie + +include $(obj)/Makefile-footer.gmk diff --git a/src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup b/src/VBox/HostDrivers/VBoxPci/linux/Makefile.kup new file mode 100644 index 00000000..e69de29b diff --git a/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c b/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c new file mode 100644 index 00000000..36685dd9 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c @@ -0,0 +1,1186 @@ +/* $Id: VBoxPci-linux.c $ */ +/** @file + * VBoxPci - PCI Driver (Host), Linux Specific Code. + */ + +/* + * Copyright (C) 2011-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "the-linux-kernel.h" +#include "version-generated.h" +#include "revision-generated.h" +#include "product-generated.h" + +#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW +#include +#include +#include +#include +#include +#include + +#include "../VBoxPciInternal.h" + +#ifdef VBOX_WITH_IOMMU +# include +# include +# include +# if RTLNX_VER_MAX(3,1,0) && \ + (RTLNX_VER_MAX(2,6,41) || RTLNX_VER_MIN(3,0,0)) +# include +# else +# include +# endif +# if RTLNX_VER_MAX(3,2,0) +# define IOMMU_PRESENT() iommu_found() +# define IOMMU_DOMAIN_ALLOC() iommu_domain_alloc() +# else +# define IOMMU_PRESENT() iommu_present(&pci_bus_type) +# define IOMMU_DOMAIN_ALLOC() iommu_domain_alloc(&pci_bus_type) +# endif +#endif /* VBOX_WITH_IOMMU */ + + +/********************************************************************************************************************************* +* Internal Functions * +*********************************************************************************************************************************/ +static int __init VBoxPciLinuxInit(void); +static void __exit VBoxPciLinuxUnload(void); + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +static VBOXRAWPCIGLOBALS g_VBoxPciGlobals; + +module_init(VBoxPciLinuxInit); +module_exit(VBoxPciLinuxUnload); + +MODULE_AUTHOR(VBOX_VENDOR); +MODULE_DESCRIPTION(VBOX_PRODUCT " PCI access Driver"); +MODULE_LICENSE("GPL"); +#ifdef MODULE_VERSION +MODULE_VERSION(VBOX_VERSION_STRING " r" RT_XSTR(VBOX_SVN_REV)); +#endif + + +#if RTLNX_VER_MIN(2,6,20) +# define PCI_DEV_GET(v,d,p) pci_get_device(v,d,p) +# define PCI_DEV_PUT(x) pci_dev_put(x) +#if RTLNX_VER_MIN(4,17,0) +/* assume the domain number to be zero - exactly the same assumption of + * pci_get_bus_and_slot() + */ +# define PCI_DEV_GET_SLOT(bus, devfn) pci_get_domain_bus_and_slot(0, bus, devfn) +#else +# define PCI_DEV_GET_SLOT(bus, devfn) pci_get_bus_and_slot(bus, devfn) +#endif +#else +# define PCI_DEV_GET(v,d,p) pci_find_device(v,d,p) +# define PCI_DEV_PUT(x) do { } while (0) +# define PCI_DEV_GET_SLOT(bus, devfn) pci_find_slot(bus, devfn) +#endif + +/** + * Name of module used to attach to the host PCI device, when + * PCI device passthrough is used. + */ +#define PCI_STUB_MODULE "pci-stub" +/* For some reasons my kernel names module for find_module() this way, + * while device name seems to be above one. + */ +#define PCI_STUB_MODULE_NAME "pci_stub" + +/** + * Our driver name. + */ +#define DRIVER_NAME "vboxpci" + +/* + * Currently we keep the device bound to pci stub driver, so + * dev_printk() &co would report that instead of our name. They also + * expect non-NULL dev pointer in older kernels. + */ +#define vbpci_printk(level, pdev, format, arg...) \ + printk(level DRIVER_NAME "%s%s: " format, \ + pdev ? " " : "", pdev ? pci_name(pdev) : "", \ + ## arg) + + +/** + * Initialize module. + * + * @returns appropriate status code. + */ +static int __init VBoxPciLinuxInit(void) +{ + int rc; + /* + * Initialize IPRT. + */ + rc = RTR0Init(0); + + if (RT_FAILURE(rc)) + goto error; + + + LogRel(("VBoxPciLinuxInit\n")); + + RT_ZERO(g_VBoxPciGlobals); + + rc = vboxPciInit(&g_VBoxPciGlobals); + if (RT_FAILURE(rc)) + { + LogRel(("cannot do VBoxPciInit: %Rc\n", rc)); + goto error; + } + +#if defined(CONFIG_PCI_STUB) + /* nothing to do, pci_stub module part of the kernel */ + g_VBoxPciGlobals.fPciStubModuleAvail = true; + +#elif defined(CONFIG_PCI_STUB_MODULE) + if (request_module(PCI_STUB_MODULE) == 0) + { +# if RTLNX_VER_MIN(2,6,30) + /* find_module() is static before Linux 2.6.30 */ + mutex_lock(&module_mutex); + g_VBoxPciGlobals.pciStubModule = find_module(PCI_STUB_MODULE_NAME); + mutex_unlock(&module_mutex); + if (g_VBoxPciGlobals.pciStubModule) + { + if (try_module_get(g_VBoxPciGlobals.pciStubModule)) + g_VBoxPciGlobals.fPciStubModuleAvail = true; + } + else + printk(KERN_INFO "vboxpci: find_module %s failed\n", PCI_STUB_MODULE); +# endif + } + else + printk(KERN_INFO "vboxpci: cannot load %s\n", PCI_STUB_MODULE); + +#else + printk(KERN_INFO "vboxpci: %s module not available, cannot detach PCI devices\n", + PCI_STUB_MODULE); +#endif + +#ifdef VBOX_WITH_IOMMU + if (IOMMU_PRESENT()) + printk(KERN_INFO "vboxpci: IOMMU found\n"); + else + printk(KERN_INFO "vboxpci: IOMMU not found (not registered)\n"); +#else + printk(KERN_INFO "vboxpci: IOMMU not found (not compiled)\n"); +#endif + + return 0; + + error: + return -RTErrConvertToErrno(rc); +} + +/** + * Unload the module. + */ +static void __exit VBoxPciLinuxUnload(void) +{ + LogRel(("VBoxPciLinuxLinuxUnload\n")); + + /* + * Undo the work done during start (in reverse order). + */ + vboxPciShutdown(&g_VBoxPciGlobals); + + RTR0Term(); + + if (g_VBoxPciGlobals.pciStubModule) + { + module_put(g_VBoxPciGlobals.pciStubModule); + g_VBoxPciGlobals.pciStubModule = NULL; + } + + Log(("VBoxPciLinuxUnload - done\n")); +} + +static int vboxPciLinuxDevRegisterWithIommu(PVBOXRAWPCIINS pIns) +{ +#ifdef VBOX_WITH_IOMMU + int rc = VINF_SUCCESS; + struct pci_dev *pPciDev = pIns->pPciDev; + PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns); + IPRT_LINUX_SAVE_EFL_AC(); + + if (RT_LIKELY(pData)) + { + if (RT_LIKELY(pData->pIommuDomain)) + { + /** @todo KVM checks IOMMU_CAP_CACHE_COHERENCY and sets + * flag IOMMU_CACHE later used when mapping physical + * addresses, which could improve performance. + */ + int rcLnx = iommu_attach_device(pData->pIommuDomain, &pPciDev->dev); + if (!rcLnx) + { + vbpci_printk(KERN_DEBUG, pPciDev, "attached to IOMMU\n"); + pIns->fIommuUsed = true; + rc = VINF_SUCCESS; + } + else + { + vbpci_printk(KERN_DEBUG, pPciDev, "failed to attach to IOMMU, error %d\n", rcLnx); + rc = VERR_INTERNAL_ERROR; + } + } + else + { + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "cannot attach to IOMMU, no domain\n"); + rc = VERR_NOT_FOUND; + } + } + else + { + vbpci_printk(KERN_DEBUG, pPciDev, "cannot attach to IOMMU, no VM data\n"); + rc = VERR_INVALID_PARAMETER; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +#else + return VERR_NOT_SUPPORTED; +#endif +} + +static int vboxPciLinuxDevUnregisterWithIommu(PVBOXRAWPCIINS pIns) +{ +#ifdef VBOX_WITH_IOMMU + int rc = VINF_SUCCESS; + struct pci_dev *pPciDev = pIns->pPciDev; + PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns); + IPRT_LINUX_SAVE_EFL_AC(); + + if (RT_LIKELY(pData)) + { + if (RT_LIKELY(pData->pIommuDomain)) + { + if (pIns->fIommuUsed) + { + iommu_detach_device(pData->pIommuDomain, &pIns->pPciDev->dev); + vbpci_printk(KERN_DEBUG, pPciDev, "detached from IOMMU\n"); + pIns->fIommuUsed = false; + } + } + else + { + vbpci_printk(KERN_DEBUG, pPciDev, + "cannot detach from IOMMU, no domain\n"); + rc = VERR_NOT_FOUND; + } + } + else + { + vbpci_printk(KERN_DEBUG, pPciDev, + "cannot detach from IOMMU, no VM data\n"); + rc = VERR_INVALID_PARAMETER; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +#else + return VERR_NOT_SUPPORTED; +#endif +} + +static int vboxPciLinuxDevReset(PVBOXRAWPCIINS pIns) +{ + int rc = VINF_SUCCESS; + IPRT_LINUX_SAVE_EFL_AC(); + + if (RT_LIKELY(pIns->pPciDev)) + { +#if RTLNX_VER_MIN(2,6,28) + if (pci_reset_function(pIns->pPciDev)) + { + vbpci_printk(KERN_DEBUG, pIns->pPciDev, + "pci_reset_function() failed\n"); + rc = VERR_INTERNAL_ERROR; + } +#else + rc = VERR_NOT_SUPPORTED; +#endif + } + else + rc = VERR_INVALID_PARAMETER; + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +static struct file* vboxPciFileOpen(const char* path, int flags) +{ + struct file* filp = NULL; + int err = 0; + + filp = filp_open(path, flags, 0); + + if (IS_ERR(filp)) + { + err = PTR_ERR(filp); + printk(KERN_DEBUG "vboxPciFileOpen: error %d\n", err); + return NULL; + } + + if (!filp->f_op || !filp->f_op->write) + { + printk(KERN_DEBUG "Not writable FS\n"); + filp_close(filp, NULL); + return NULL; + } + + return filp; +} + +static void vboxPciFileClose(struct file* file) +{ + filp_close(file, NULL); +} + +static int vboxPciFileWrite(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size) +{ + int ret; + mm_segment_t fs_save; + + fs_save = get_fs(); + set_fs(KERNEL_DS); +#if RTLNX_VER_MIN(4,14,0) + ret = kernel_write(file, data, size, &offset); +#else + ret = vfs_write(file, data, size, &offset); +#endif + set_fs(fs_save); + if (ret < 0) + printk(KERN_DEBUG "vboxPciFileWrite: error %d\n", ret); + + return ret; +} + +static int vboxPciLinuxDevDetachHostDriver(PVBOXRAWPCIINS pIns) +{ + struct pci_dev *pPciDev = NULL; + uint8_t uBus = (pIns->HostPciAddress) >> 8; + uint8_t uDevFn = (pIns->HostPciAddress) & 0xff; + const char* currentDriver; + uint16_t uVendor, uDevice; + bool fDetach = 0; + + if (!g_VBoxPciGlobals.fPciStubModuleAvail) + { + printk(KERN_INFO "vboxpci: stub module %s not detected: cannot detach\n", + PCI_STUB_MODULE); + return VERR_ACCESS_DENIED; + } + + pPciDev = PCI_DEV_GET_SLOT(uBus, uDevFn); + + if (!pPciDev) + { + printk(KERN_INFO "vboxpci: device at %02x:%02x.%d not found\n", + uBus, uDevFn>>3, uDevFn&7); + return VERR_NOT_FOUND; + } + + uVendor = pPciDev->vendor; + uDevice = pPciDev->device; + + currentDriver = pPciDev->driver ? pPciDev->driver->name : NULL; + + printk(KERN_DEBUG "vboxpci: detected device: %04x:%04x at %02x:%02x.%d, driver %s\n", + uVendor, uDevice, uBus, uDevFn>>3, uDevFn&7, + currentDriver ? currentDriver : ""); + + fDetach = (currentDriver == NULL || (strcmp(currentDriver, PCI_STUB_MODULE) != 0)); + + /* Init previous driver data. */ + pIns->szPrevDriver[0] = '\0'; + + if (fDetach && currentDriver) + { + /* Dangerous: if device name for some reasons contains slashes - arbitrary file could be written to. */ + if (strchr(currentDriver, '/') != 0) + { + printk(KERN_DEBUG "vboxpci: ERROR: %s contains invalid symbols\n", currentDriver); + return VERR_ACCESS_DENIED; + } + /** @todo RTStrCopy not exported. */ + strncpy(pIns->szPrevDriver, currentDriver, sizeof(pIns->szPrevDriver) - 1); + pIns->szPrevDriver[sizeof(pIns->szPrevDriver) - 1] = '\0'; + } + + PCI_DEV_PUT(pPciDev); + pPciDev = NULL; + + if (fDetach) + { + char* szCmdBuf; + char* szFileBuf; + struct file* pFile; + int iCmdLen; + const int cMaxBuf = 128; +#if RTLNX_VER_MIN(2,6,29) + const struct cred *pOldCreds; + struct cred *pNewCreds; +#endif + + /* + * Now perform kernel analog of: + * + * echo -n "10de 040a" > /sys/bus/pci/drivers/pci-stub/new_id + * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/nvidia/unbind + * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/pci-stub/bind + * + * We do this way, as this interface is presumingly more stable than + * in-kernel ones. + */ + szCmdBuf = kmalloc(cMaxBuf, GFP_KERNEL); + szFileBuf = kmalloc(cMaxBuf, GFP_KERNEL); + if (!szCmdBuf || !szFileBuf) + goto done; + + /* Somewhat ugly hack - override current credentials */ +#if RTLNX_VER_MIN(2,6,29) + pNewCreds = prepare_creds(); + if (!pNewCreds) + goto done; + +# if RTLNX_VER_MIN(3,5,0) + pNewCreds->fsuid = GLOBAL_ROOT_UID; +# else + pNewCreds->fsuid = 0; +# endif + pOldCreds = override_creds(pNewCreds); +#endif + + RTStrPrintf(szFileBuf, cMaxBuf, + "/sys/bus/pci/drivers/%s/new_id", + PCI_STUB_MODULE); + pFile = vboxPciFileOpen(szFileBuf, O_WRONLY); + if (pFile) + { + iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf, + "%04x %04x", + uVendor, uDevice); + /* Don't write trailing \0 */ + vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen); + vboxPciFileClose(pFile); + } + else + printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf); + + iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf, + "0000:%02x:%02x.%d", + uBus, uDevFn>>3, uDevFn&7); + + /* Unbind if bound to smth */ + if (pIns->szPrevDriver[0]) + { + RTStrPrintf(szFileBuf, cMaxBuf, + "/sys/bus/pci/drivers/%s/unbind", + pIns->szPrevDriver); + pFile = vboxPciFileOpen(szFileBuf, O_WRONLY); + if (pFile) + { + + /* Don't write trailing \0 */ + vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen); + vboxPciFileClose(pFile); + } + else + printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf); + } + + RTStrPrintf(szFileBuf, cMaxBuf, + "/sys/bus/pci/drivers/%s/bind", + PCI_STUB_MODULE); + pFile = vboxPciFileOpen(szFileBuf, O_WRONLY); + if (pFile) + { + /* Don't write trailing \0 */ + vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen); + vboxPciFileClose(pFile); + } + else + printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf); + +#if RTLNX_VER_MIN(2,6,29) + revert_creds(pOldCreds); + put_cred(pNewCreds); +#endif + + done: + kfree(szCmdBuf); + kfree(szFileBuf); + } + + return 0; +} + +static int vboxPciLinuxDevReattachHostDriver(PVBOXRAWPCIINS pIns) +{ + struct pci_dev *pPciDev = pIns->pPciDev; + + if (!pPciDev) + return VINF_SUCCESS; + + if (pIns->szPrevDriver[0]) + { + char* szCmdBuf; + char* szFileBuf; + struct file* pFile; + int iCmdLen; + const int cMaxBuf = 128; +#if RTLNX_VER_MIN(2,6,29) + const struct cred *pOldCreds; + struct cred *pNewCreds; +#endif + uint8_t uBus = (pIns->HostPciAddress) >> 8; + uint8_t uDevFn = (pIns->HostPciAddress) & 0xff; + + vbpci_printk(KERN_DEBUG, pPciDev, + "reattaching old host driver %s\n", pIns->szPrevDriver); + /* + * Now perform kernel analog of: + * + * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/pci-stub/unbind + * echo -n 0000:03:00.0 > /sys/bus/pci/drivers/nvidia/bind + */ + szCmdBuf = kmalloc(cMaxBuf, GFP_KERNEL); + szFileBuf = kmalloc(cMaxBuf, GFP_KERNEL); + + if (!szCmdBuf || !szFileBuf) + goto done; + + iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf, + "0000:%02x:%02x.%d", + uBus, uDevFn>>3, uDevFn&7); + + /* Somewhat ugly hack - override current credentials */ +#if RTLNX_VER_MIN(2,6,29) + pNewCreds = prepare_creds(); + if (!pNewCreds) + goto done; + +# if RTLNX_VER_MIN(3,5,0) + pNewCreds->fsuid = GLOBAL_ROOT_UID; +# else + pNewCreds->fsuid = 0; +# endif + pOldCreds = override_creds(pNewCreds); +#endif + RTStrPrintf(szFileBuf, cMaxBuf, + "/sys/bus/pci/drivers/%s/unbind", + PCI_STUB_MODULE); + pFile = vboxPciFileOpen(szFileBuf, O_WRONLY); + if (pFile) + { + + /* Don't write trailing \0 */ + vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen); + vboxPciFileClose(pFile); + } + else + printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf); + + RTStrPrintf(szFileBuf, cMaxBuf, + "/sys/bus/pci/drivers/%s/bind", + pIns->szPrevDriver); + pFile = vboxPciFileOpen(szFileBuf, O_WRONLY); + if (pFile) + { + + /* Don't write trailing \0 */ + vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen); + vboxPciFileClose(pFile); + pIns->szPrevDriver[0] = '\0'; + } + else + printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf); + +#if RTLNX_VER_MIN(2,6,29) + revert_creds(pOldCreds); + put_cred(pNewCreds); +#endif + + done: + kfree(szCmdBuf); + kfree(szFileBuf); + } + + return VINF_SUCCESS; +} + +DECLHIDDEN(int) vboxPciOsDevInit(PVBOXRAWPCIINS pIns, uint32_t fFlags) +{ + struct pci_dev *pPciDev = NULL; + int rc = VINF_SUCCESS; + IPRT_LINUX_SAVE_EFL_AC(); + + if (fFlags & PCIRAWDRIVERRFLAG_DETACH_HOST_DRIVER) + { + rc = vboxPciLinuxDevDetachHostDriver(pIns); + if (RT_FAILURE(rc)) + { + printk(KERN_DEBUG "Cannot detach host driver for device %x: %d\n", + pIns->HostPciAddress, rc); + } + } + + if (RT_SUCCESS(rc)) + { + pPciDev = PCI_DEV_GET_SLOT((pIns->HostPciAddress) >> 8, + (pIns->HostPciAddress) & 0xff); + + if (RT_LIKELY(pPciDev)) + { + int rcLnx = pci_enable_device(pPciDev); + + if (!rcLnx) + { + pIns->pPciDev = pPciDev; + vbpci_printk(KERN_DEBUG, pPciDev, "%s\n", __func__); + +#if RTLNX_VER_MIN(2,6,1) + if (pci_enable_msi(pPciDev) == 0) + pIns->fMsiUsed = true; +#endif + + /** @todo + * pci_enable_msix(pPciDev, entries, nvec) + * + * In fact, if device uses interrupts, and cannot be forced to use MSI or MSI-X + * we have to refuse using it, as we cannot work with shared PCI interrupts (unless we're lucky + * to grab unshared PCI interrupt). + */ + } + else + rc = RTErrConvertFromErrno(RT_ABS(rcLnx)); + } + else + rc = VERR_NOT_FOUND; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +DECLHIDDEN(int) vboxPciOsDevDeinit(PVBOXRAWPCIINS pIns, uint32_t fFlags) +{ + int rc = VINF_SUCCESS; + struct pci_dev *pPciDev = pIns->pPciDev; + IPRT_LINUX_SAVE_EFL_AC(); + + vbpci_printk(KERN_DEBUG, pPciDev, "%s\n", __func__); + + if (RT_LIKELY(pPciDev)) + { + int iRegion; + for (iRegion = 0; iRegion < 7; ++iRegion) + { + if (pIns->aRegionR0Mapping[iRegion]) + { + iounmap(pIns->aRegionR0Mapping[iRegion]); + pIns->aRegionR0Mapping[iRegion] = 0; + pci_release_region(pPciDev, iRegion); + } + } + + vboxPciLinuxDevUnregisterWithIommu(pIns); + +#if RTLNX_VER_MIN(2,6,1) + if (pIns->fMsiUsed) + pci_disable_msi(pPciDev); +#endif + // pci_disable_msix(pPciDev); + pci_disable_device(pPciDev); + vboxPciLinuxDevReattachHostDriver(pIns); + + PCI_DEV_PUT(pPciDev); + pIns->pPciDev = NULL; + } + else + rc = VERR_INVALID_PARAMETER; + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +DECLHIDDEN(int) vboxPciOsDevDestroy(PVBOXRAWPCIINS pIns) +{ + return VINF_SUCCESS; +} + +DECLHIDDEN(int) vboxPciOsDevGetRegionInfo(PVBOXRAWPCIINS pIns, + int32_t iRegion, + RTHCPHYS *pRegionStart, + uint64_t *pu64RegionSize, + bool *pfPresent, + uint32_t *pfFlags) +{ + int rc = VINF_SUCCESS; + struct pci_dev *pPciDev = pIns->pPciDev; + IPRT_LINUX_SAVE_EFL_AC(); + + if (RT_LIKELY(pPciDev)) + { + int fFlags = pci_resource_flags(pPciDev, iRegion); + + if ( ((fFlags & (IORESOURCE_MEM | IORESOURCE_IO)) == 0) + || ((fFlags & IORESOURCE_DISABLED) != 0)) + { + *pfPresent = false; + rc = VERR_INVALID_PARAMETER; + } + else + { + uint32_t fResFlags = 0; + *pfPresent = true; + + if (fFlags & IORESOURCE_MEM) + fResFlags |= PCIRAW_ADDRESS_SPACE_MEM; + + if (fFlags & IORESOURCE_IO) + fResFlags |= PCIRAW_ADDRESS_SPACE_IO; + +#ifdef IORESOURCE_MEM_64 + if (fFlags & IORESOURCE_MEM_64) + fResFlags |= PCIRAW_ADDRESS_SPACE_BAR64; +#endif + + if (fFlags & IORESOURCE_PREFETCH) + fResFlags |= PCIRAW_ADDRESS_SPACE_MEM_PREFETCH; + + *pfFlags = fResFlags; + *pRegionStart = pci_resource_start(pPciDev, iRegion); + *pu64RegionSize = pci_resource_len (pPciDev, iRegion); + + vbpci_printk(KERN_DEBUG, pPciDev, + "region %d: %s %llx+%lld\n", + iRegion, (fFlags & IORESOURCE_MEM) ? "mmio" : "pio", + *pRegionStart, *pu64RegionSize); + } + } + else + { + *pfPresent = false; + rc = VERR_INVALID_PARAMETER; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +DECLHIDDEN(int) vboxPciOsDevMapRegion(PVBOXRAWPCIINS pIns, + int32_t iRegion, + RTHCPHYS RegionStart, + uint64_t u64RegionSize, + uint32_t fFlags, + RTR0PTR *pRegionBase) +{ + int rc = VINF_SUCCESS; + struct pci_dev *pPciDev = pIns->pPciDev; + IPRT_LINUX_SAVE_EFL_AC(); + + if (!pPciDev || iRegion < 0 || iRegion > 0) + { + if (pPciDev) + vbpci_printk(KERN_DEBUG, pPciDev, "invalid region %d\n", iRegion); + + IPRT_LINUX_RESTORE_EFL_AC(); + return VERR_INVALID_PARAMETER; + } + + vbpci_printk(KERN_DEBUG, pPciDev, "reg=%d start=%llx size=%lld\n", + iRegion, RegionStart, u64RegionSize); + + if ( (pci_resource_flags(pPciDev, iRegion) & IORESOURCE_IO) + || RegionStart != pci_resource_start(pPciDev, iRegion) + || u64RegionSize != pci_resource_len(pPciDev, iRegion)) + { + IPRT_LINUX_RESTORE_EFL_AC(); + return VERR_INVALID_PARAMETER; + } + + /* + * XXX: Current code never calls unmap. To avoid leaking mappings + * only request and map resources once. + */ + if (!pIns->aRegionR0Mapping[iRegion]) + { + int rcLnx; + *pRegionBase = pIns->aRegionR0Mapping[iRegion]; + + rcLnx = pci_request_region(pPciDev, iRegion, "vboxpci"); + if (!rcLnx) + { +#if RTLNX_VER_MIN(2,6,25) + /* + * ioremap() defaults to no caching since the 2.6 kernels. + * ioremap_nocache() has been removed finally in 5.6-rc1. + */ + RTR0PTR R0PtrMapping = ioremap(pci_resource_start(pPciDev, iRegion), + pci_resource_len(pPciDev, iRegion)); +#else /* KERNEL_VERSION < 2.6.25 */ + /* For now no caching, try to optimize later. */ + RTR0PTR R0PtrMapping = ioremap_nocache(pci_resource_start(pPciDev, iRegion), + pci_resource_len(pPciDev, iRegion)); +#endif /* KERNEL_VERSION < 2.6.25 */ + if (R0PtrMapping != NIL_RTR0PTR) + pIns->aRegionR0Mapping[iRegion] = R0PtrMapping; + else + { +#if RTLNX_VER_MIN(2,6,25) + vbpci_printk(KERN_DEBUG, pPciDev, "ioremap() failed\n"); +#else + vbpci_printk(KERN_DEBUG, pPciDev, "ioremap_nocache() failed\n"); +#endif + pci_release_region(pPciDev, iRegion); + rc = VERR_MAP_FAILED; + } + } + else + rc = VERR_RESOURCE_BUSY; + } + + if (RT_SUCCESS(rc)) + *pRegionBase = pIns->aRegionR0Mapping[iRegion]; + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +DECLHIDDEN(int) vboxPciOsDevUnmapRegion(PVBOXRAWPCIINS pIns, + int32_t iRegion, + RTHCPHYS RegionStart, + uint64_t u64RegionSize, + RTR0PTR RegionBase) +{ + /* XXX: Current code never calls unmap. */ + return VERR_NOT_IMPLEMENTED; +} + +DECLHIDDEN(int) vboxPciOsDevPciCfgWrite(PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue) +{ + struct pci_dev *pPciDev = pIns->pPciDev; + int rc = VINF_SUCCESS; + IPRT_LINUX_SAVE_EFL_AC(); + + if (RT_LIKELY(pPciDev)) + { + switch (pValue->cb) + { + case 1: + pci_write_config_byte(pPciDev, Register, pValue->u.u8); + break; + case 2: + pci_write_config_word(pPciDev, Register, pValue->u.u16); + break; + case 4: + pci_write_config_dword(pPciDev, Register, pValue->u.u32); + break; + } + } + else + rc = VERR_INVALID_PARAMETER; + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} + +DECLHIDDEN(int) vboxPciOsDevPciCfgRead(PVBOXRAWPCIINS pIns, uint32_t Register, PCIRAWMEMLOC *pValue) +{ + struct pci_dev *pPciDev = pIns->pPciDev; + int rc = VINF_SUCCESS; + + if (RT_LIKELY(pPciDev)) + { + IPRT_LINUX_SAVE_EFL_AC(); + + switch (pValue->cb) + { + case 1: + pci_read_config_byte(pPciDev, Register, &pValue->u.u8); + break; + case 2: + pci_read_config_word(pPciDev, Register, &pValue->u.u16); + break; + case 4: + pci_read_config_dword(pPciDev, Register, &pValue->u.u32); + break; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + } + else + rc = VERR_INVALID_PARAMETER; + + return rc; +} + +/** + * Interrupt service routine. + * + * @returns In 2.6 we indicate whether we've handled the IRQ or not. + * + * @param iIrq The IRQ number. + * @param pvDevId The device ID, a pointer to PVBOXRAWPCIINS. + * @param pRegs Register set. Removed in 2.6.19. + */ +#if RTLNX_VER_MIN(2,6,19) && !defined(DOXYGEN_RUNNING) +static irqreturn_t vboxPciOsIrqHandler(int iIrq, void *pvDevId) +#else +static irqreturn_t vboxPciOsIrqHandler(int iIrq, void *pvDevId, struct pt_regs *pRegs) +#endif +{ + PVBOXRAWPCIINS pIns = (PVBOXRAWPCIINS)pvDevId; + bool fTaken = true; + + if (pIns && pIns->IrqHandler.pfnIrqHandler) + fTaken = pIns->IrqHandler.pfnIrqHandler(pIns->IrqHandler.pIrqContext, iIrq); +#ifndef VBOX_WITH_SHARED_PCI_INTERRUPTS + /* If we don't allow interrupts sharing, we consider all interrupts as non-shared, thus targetted to us. */ + fTaken = true; +#endif + + return fTaken; +} + +DECLHIDDEN(int) vboxPciOsDevRegisterIrqHandler(PVBOXRAWPCIINS pIns, PFNRAWPCIISR pfnHandler, void* pIrqContext, int32_t *piHostIrq) +{ + int rc; + int32_t iIrq = pIns->pPciDev->irq; + IPRT_LINUX_SAVE_EFL_AC(); + + if (iIrq == 0) + { + vbpci_printk(KERN_NOTICE, pIns->pPciDev, "no irq assigned\n"); + IPRT_LINUX_RESTORE_EFL_AC(); + return VERR_INVALID_PARAMETER; + } + + rc = request_irq(iIrq, + vboxPciOsIrqHandler, +#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS + /* Allow interrupts sharing. */ +# if RTLNX_VER_MIN(2,6,20) + IRQF_SHARED, +# else + SA_SHIRQ, +# endif + +#else + + /* We don't allow interrupts sharing */ + /* XXX overhaul */ +# if RTLNX_VER_MIN(2,6,20) && RTLNX_VER_MAX(4,1,0) + IRQF_DISABLED, /* keep irqs disabled when calling the action handler */ +# else + 0, +# endif +#endif + DRIVER_NAME, + pIns); + if (rc) + { + vbpci_printk(KERN_DEBUG, pIns->pPciDev, + "could not request irq %d, error %d\n", iIrq, rc); + IPRT_LINUX_RESTORE_EFL_AC(); + return VERR_RESOURCE_BUSY; + } + + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "got irq %d\n", iIrq); + *piHostIrq = iIrq; + + IPRT_LINUX_RESTORE_EFL_AC(); + return VINF_SUCCESS; +} + +DECLHIDDEN(int) vboxPciOsDevUnregisterIrqHandler(PVBOXRAWPCIINS pIns, int32_t iHostIrq) +{ + IPRT_LINUX_SAVE_EFL_AC(); + + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "freeing irq %d\n", iHostIrq); + free_irq(iHostIrq, pIns); + + IPRT_LINUX_RESTORE_EFL_AC(); + return VINF_SUCCESS; +} + +DECLHIDDEN(int) vboxPciOsDevPowerStateChange(PVBOXRAWPCIINS pIns, PCIRAWPOWERSTATE aState) +{ + int rc; + + switch (aState) + { + case PCIRAW_POWER_ON: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "PCIRAW_POWER_ON\n"); + /* Reset device, just in case. */ + vboxPciLinuxDevReset(pIns); + /* register us with IOMMU */ + rc = vboxPciLinuxDevRegisterWithIommu(pIns); + break; + case PCIRAW_POWER_RESET: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "PCIRAW_POWER_RESET\n"); + rc = vboxPciLinuxDevReset(pIns); + break; + case PCIRAW_POWER_OFF: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "PCIRAW_POWER_OFF\n"); + /* unregister us from IOMMU */ + rc = vboxPciLinuxDevUnregisterWithIommu(pIns); + break; + case PCIRAW_POWER_SUSPEND: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "PCIRAW_POWER_SUSPEND\n"); + rc = VINF_SUCCESS; + /// @todo what do we do here? + break; + case PCIRAW_POWER_RESUME: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "PCIRAW_POWER_RESUME\n"); + rc = VINF_SUCCESS; + /// @todo what do we do here? + break; + default: + vbpci_printk(KERN_DEBUG, pIns->pPciDev, "unknown power state %u\n", aState); + /* to make compiler happy */ + rc = VERR_NOT_SUPPORTED; + break; + } + + return rc; +} + + +#ifdef VBOX_WITH_IOMMU +/** Callback for FNRAWPCICONTIGPHYSMEMINFO. */ +static DECLCALLBACK(int) vboxPciOsContigMemInfo(PRAWPCIPERVM pVmCtx, RTHCPHYS HostStart, RTGCPHYS GuestStart, + uint64_t cMemSize, PCIRAWMEMINFOACTION Action) +{ + struct iommu_domain* domain = ((PVBOXRAWPCIDRVVM)(pVmCtx->pDriverData))->pIommuDomain; + int rc = VINF_SUCCESS; + IPRT_LINUX_SAVE_EFL_AC(); + + switch (Action) + { + case PCIRAW_MEMINFO_MAP: + { + int flags, r; + + if (iommu_iova_to_phys(domain, GuestStart)) + break; + + flags = IOMMU_READ | IOMMU_WRITE; + /** @todo flags |= IOMMU_CACHE; */ + + r = iommu_map(domain, GuestStart, HostStart, get_order(cMemSize), flags); + if (r) + { + printk(KERN_ERR "vboxPciOsContigMemInfo:" + "iommu failed to map pfn=%llx\n", HostStart); + rc = VERR_GENERAL_FAILURE; + break; + } + rc = VINF_SUCCESS; + break; + } + case PCIRAW_MEMINFO_UNMAP: + { + int order; + order = iommu_unmap(domain, GuestStart, get_order(cMemSize)); + NOREF(order); + break; + } + + default: + printk(KERN_DEBUG "Unsupported action: %d\n", (int)Action); + rc = VERR_NOT_SUPPORTED; + break; + } + + IPRT_LINUX_RESTORE_EFL_AC(); + return rc; +} +#endif + +DECLHIDDEN(int) vboxPciOsInitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM, PRAWPCIPERVM pVmData) +{ + int rc = VINF_SUCCESS; + +#ifdef VBOX_WITH_IOMMU + IPRT_LINUX_SAVE_EFL_AC(); + + if (IOMMU_PRESENT()) + { + pThis->pIommuDomain = IOMMU_DOMAIN_ALLOC(); + if (!pThis->pIommuDomain) + { + vbpci_printk(KERN_DEBUG, NULL, "cannot allocate IOMMU domain\n"); + rc = VERR_NO_MEMORY; + } + else + { + pVmData->pfnContigMemInfo = vboxPciOsContigMemInfo; + + vbpci_printk(KERN_DEBUG, NULL, "created IOMMU domain %p\n", + pThis->pIommuDomain); + } + } + + IPRT_LINUX_RESTORE_EFL_AC(); +#endif + return rc; +} + +DECLHIDDEN(void) vboxPciOsDeinitVm(PVBOXRAWPCIDRVVM pThis, PVM pVM) +{ +#ifdef VBOX_WITH_IOMMU + IPRT_LINUX_SAVE_EFL_AC(); + + if (pThis->pIommuDomain) + { + vbpci_printk(KERN_DEBUG, NULL, "freeing IOMMU domain %p\n", + pThis->pIommuDomain); + iommu_domain_free(pThis->pIommuDomain); + pThis->pIommuDomain = NULL; + } + + IPRT_LINUX_RESTORE_EFL_AC(); +#endif +} diff --git a/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci b/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci new file mode 100755 index 00000000..70e15ed2 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxPci/linux/files_vboxpci @@ -0,0 +1,111 @@ +#!/bin/sh +# $Id: files_vboxpci $ +## @file +# Shared file between Makefile.kmk and export_modules.sh. +# + +# +# Copyright (C) 2011-2023 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.org. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, in version 3 of the +# License. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +# in the VirtualBox distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# +# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +# + +VBOX_VBOXPCI_SOURCES=" \ + ${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \ + ${PATH_ROOT}/include/iprt/alloca.h=>include/iprt/alloca.h \ + ${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \ + ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \ + ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \ + ${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \ + ${PATH_ROOT}/include/iprt/assertcompile.h=>include/iprt/assertcompile.h \ + ${PATH_ROOT}/include/iprt/avl.h=>include/iprt/avl.h \ + ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \ + ${PATH_ROOT}/include/iprt/cpuset.h=>include/iprt/cpuset.h \ + ${PATH_ROOT}/include/iprt/ctype.h=>include/iprt/ctype.h \ + ${PATH_ROOT}/include/iprt/err.h=>include/iprt/err.h \ + ${PATH_ROOT}/include/iprt/errcore.h=>include/iprt/errcore.h \ + ${PATH_ROOT}/include/iprt/heap.h=>include/iprt/heap.h \ + ${PATH_ROOT}/include/iprt/initterm.h=>include/iprt/initterm.h \ + ${PATH_ROOT}/include/iprt/latin1.h=>include/iprt/latin1.h \ + ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \ + ${PATH_ROOT}/include/iprt/mangling.h=>include/iprt/mangling.h \ + ${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \ + ${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \ + ${PATH_ROOT}/include/iprt/mp.h=>include/iprt/mp.h \ + ${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \ + ${PATH_ROOT}/include/iprt/power.h=>include/iprt/power.h \ + ${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \ + ${PATH_ROOT}/include/iprt/semaphore.h=>include/iprt/semaphore.h \ + ${PATH_ROOT}/include/iprt/spinlock.h=>include/iprt/spinlock.h \ + ${PATH_ROOT}/include/iprt/stdarg.h=>include/iprt/stdarg.h \ + ${PATH_ROOT}/include/iprt/stdint.h=>include/iprt/stdint.h \ + ${PATH_ROOT}/include/iprt/string.h=>include/iprt/string.h \ + ${PATH_ROOT}/include/iprt/thread.h=>include/iprt/thread.h \ + ${PATH_ROOT}/include/iprt/time.h=>include/iprt/time.h \ + ${PATH_ROOT}/include/iprt/timer.h=>include/iprt/timer.h \ + ${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \ + ${PATH_ROOT}/include/iprt/uint64.h=>include/iprt/uint64.h \ + ${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \ + ${PATH_ROOT}/include/iprt/utf16.h=>include/iprt/utf16.h \ + ${PATH_ROOT}/include/iprt/uuid.h=>include/iprt/uuid.h \ + ${PATH_ROOT}/include/iprt/x86-helpers.h=>include/iprt/x86-helpers.h \ + ${PATH_ROOT}/include/iprt/linux/version.h=>include/iprt/linux/version.h \ + ${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \ + ${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \ + ${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \ + ${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \ + ${PATH_ROOT}/include/VBox/rawpci.h=>include/VBox/rawpci.h \ + ${PATH_ROOT}/include/VBox/vmm/stam.h=>include/VBox/vmm/stam.h \ + ${PATH_ROOT}/include/VBox/param.h=>include/VBox/param.h \ + ${PATH_ROOT}/include/VBox/sup.h=>include/VBox/sup.h \ + ${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \ + ${PATH_ROOT}/include/VBox/version.h=>include/VBox/version.h \ + ${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \ + ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c=>linux/VBoxPci-linux.c \ + ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/VBoxPci.c=>VBoxPci.c \ + ${PATH_ROOT}/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h=>VBoxPciInternal.h \ + ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvIDC.h=>SUPDrvIDC.h \ + ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClient.c=>SUPR0IdcClient.c \ + ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c=>SUPR0IdcClientComponent.c \ + ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h=>SUPR0IdcClientInternal.h \ + ${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c=>linux/SUPR0IdcClient-linux.c \ + ${PATH_ROOT}/src/VBox/Installer/linux/Makefile-footer.gmk=>Makefile-footer.gmk \ + ${PATH_ROOT}/src/VBox/Installer/linux/Makefile-header.gmk=>Makefile-header.gmk \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/divdi3.c=>math/gcc/divdi3.c \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/moddi3.c=>math/gcc/moddi3.c \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/qdivrem.c=>math/gcc/qdivrem.c \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/quad.h=>math/gcc/quad.h \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivdi3.c=>math/gcc/udivdi3.c \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivmoddi4.c=>math/gcc/udivmoddi4.c \ + ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/umoddi3.c=>math/gcc/umoddi3.c \ + ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \ + ${PATH_OUT}/version-generated.h=>version-generated.h \ + ${PATH_OUT}/revision-generated.h=>revision-generated.h \ + ${PATH_OUT}/product-generated.h=>product-generated.h \ +" + -- cgit v1.2.3