VBoxPci-linux.c revision 5cbc8e6f19327d4705c3e80af1f97ce630dd11de
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * VBoxPci - PCI Driver (Host), Linux Specific Code.
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * Copyright (C) 2011 Oracle Corporation
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * available from http://www.virtualbox.org. This file is free software;
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * General Public License (GPL) as published by the Free Software
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync/*******************************************************************************
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Header Files *
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync *******************************************************************************/
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync/*******************************************************************************
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Internal Functions *
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync *******************************************************************************/
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsyncstatic int VBoxPciLinuxInit(void);
4e46eee5a96078ebec6cb36939b794a391f1ade0vboxsyncstatic void VBoxPciLinuxUnload(void);
4e46eee5a96078ebec6cb36939b794a391f1ade0vboxsync/*******************************************************************************
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Global Variables *
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync *******************************************************************************/
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsyncMODULE_DESCRIPTION(VBOX_PRODUCT " PCI access Driver");
4896726d903f56fe43eb13e2ba27ae1d63b8c40evboxsync# define PCI_DEV_GET_SLOT(bus, devfn) pci_get_bus_and_slot(bus, devfn)
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync# define PCI_DEV_PUT(x) do {} while(0)
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync# define PCI_DEV_GET_SLOT(bus, devfn) pci_find_slot(bus, devfn)
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Name of module used to attach to the host PCI device, when
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * PCI device passthrough is used.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync/* For some reasons my kernel names module for find_module() this way,
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * while device name seems to be above one.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Our driver name.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Initialize module.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * @returns appropriate status code.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync * Initialize IPRT.
9e201d78ac6efdd08550263f2e146cdb76e9d49bvboxsync /* nothing to do, pci_stub module part of the kernel */
#ifdef VBOX_WITH_IOMMU
if (iommu_found())
RTR0Term();
#ifdef VBOX_WITH_IOMMU
int rc;
int status;
if (!pData)
return VERR_INVALID_PARAMETER;
return VERR_NOT_FOUND;
if (status == 0)
return rc;
return VERR_NOT_SUPPORTED;
#ifdef VBOX_WITH_IOMMU
if (!pData)
return VERR_INVALID_PARAMETER;
return VERR_NOT_FOUND;
return rc;
return VERR_NOT_SUPPORTED;
return rc;
int err = 0;
return NULL;
return NULL;
return filp;
static int vboxPciFileWrite(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
int ret;
if (ret < 0)
return ret;
static int vboxPciFileRead(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
int ret;
return ret;
const char* currentDriver;
int fDetach = 0;
return VERR_ACCESS_DENIED;
if (!pPciDev)
return VERR_NOT_FOUND;
/* Dangerous: if device name for some reasons contains slashes - arbitrary file could be written to. */
return VERR_ACCESS_DENIED;
if (fDetach)
char* szCmdBuf;
char* szFileBuf;
int iCmdLen;
goto done;
if (!pNewCreds)
goto done;
if (pFile)
if (pFile)
if (pFile)
done:
if (!pPciDev)
return VINF_SUCCESS;
char* szCmdBuf;
char* szFileBuf;
int iCmdLen;
goto done;
if (!pNewCreds)
goto done;
if (pFile)
if (pFile)
done:
return VINF_SUCCESS;
int rc;
return VERR_ACCESS_DENIED;
if (!pPciDev)
return VINF_SUCCESS;
if (pPciDev)
bool *pfPresent,
int flags;
if (!pPciDev)
*pfPresent = false;
*pfPresent = false;
*pfPresent = true;
fResFlags = 0;
#ifdef IORESOURCE_MEM_64
printk(KERN_DEBUG "linux vboxPciOsDevMapRegion: reg=%d start=%llx size=%lld\n", iRegion, RegionStart, u64RegionSize);
if (!pPciDev)
return VERR_INVALID_PARAMETER;
if (!pRegion)
if (!result)
if (pRegion)
return VINF_SUCCESS;
if (!pPciDev)
return VINF_SUCCESS;
return VINF_SUCCESS;
if (!pPciDev)
return VINF_SUCCESS;
return VINF_SUCCESS;
bool fTaken = true;
#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;
return fTaken;
int vboxPciOsDevRegisterIrqHandler(PVBOXRAWPCIINS pIns, PFNRAWPCIISR pfnHandler, void* pIrqContext, int32_t *piHostIrq)
int rc;
if (iIrq == 0)
return VERR_INVALID_PARAMETER;
pIns);
if (rc)
return VERR_RESOURCE_BUSY;
return VINF_SUCCESS;
return VINF_SUCCESS;
int rc;
switch (aState)
case PCIRAW_POWER_ON:
case PCIRAW_POWER_RESET:
case PCIRAW_POWER_OFF:
case PCIRAW_POWER_SUSPEND:
case PCIRAW_POWER_RESUME:
return rc;
#ifdef VBOX_WITH_IOMMU
static int vboxPciOsContigMemInfo(PRAWPCIPERVM pVmCtx, RTHCPHYS HostStart, RTGCPHYS GuestStart, uint64_t cMemSize, PCIRAWMEMINFOACTION Action)
switch (Action)
case PCIRAW_MEMINFO_MAP:
int flags, r;
case PCIRAW_MEMINFO_UNMAP:
int order;
return rc;
#ifdef VBOX_WITH_IOMMU
if (iommu_found())
return VERR_NO_MEMORY;
return VINF_SUCCESS;
#ifdef VBOX_WITH_IOMMU