int vboxPciOsDevUnregisterWithIommu(PVBOXRAWPCIINS pIns) { #ifdef VBOX_WITH_IOMMU int rc = VINF_SUCCESS; PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns); if (!pData) { printk(KERN_DEBUG "vboxpci: VM data not inited (detach)\n"); return VERR_INVALID_PARAMETER; } if (!pData->pIommuDomain) { printk(KERN_DEBUG "vboxpci: No IOMMU domain (detach)\n"); return VERR_NOT_FOUND; } if (pIns->fIommuUsed) { iommu_detach_device(pData->pIommuDomain, &pIns->pPciDev->dev); printk(KERN_DEBUG "vboxpci: iommu_detach_device()\n"); pIns->fIommuUsed = false; } return rc; #else return VERR_NOT_SUPPORTED; #endif }
static DECLCALLBACK(int) vboxPciDevPowerStateChange(PRAWPCIDEVPORT pPort, PCIRAWPOWERSTATE aState, uint64_t *pu64Param) { PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort); int rc; RTSPINLOCKTMP aTmp; vboxPciDevLock(pThis, &aTmp); rc = vboxPciOsDevPowerStateChange(pThis, aState); switch (aState) { case PCIRAW_POWER_ON: /* * Let virtual device know about VM caps. */ *pu64Param = VBOX_DRV_VMDATA(pThis)->pPerVmData->fVmCaps; break; default: pu64Param = 0; break; } vboxPciDevUnlock(pThis, &aTmp); return rc; }
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 }
int vboxPciOsDevRegisterWithIommu(PVBOXRAWPCIINS pIns) { #ifdef VBOX_WITH_IOMMU int rc; int status; PVBOXRAWPCIDRVVM pData = VBOX_DRV_VMDATA(pIns); if (!pData) { printk(KERN_DEBUG "vboxpci: VM data not initialized (attach)\n"); return VERR_INVALID_PARAMETER; } if (!pData->pIommuDomain) { printk(KERN_DEBUG "vboxpci: No IOMMU domain (attach)\n"); return VERR_NOT_FOUND; } status = iommu_attach_device(pData->pIommuDomain, &pIns->pPciDev->dev); if (status == 0) { printk(KERN_DEBUG "vboxpci: iommu_attach_device() success\n"); pIns->fIommuUsed = true; rc = VINF_SUCCESS;; } else { printk(KERN_DEBUG "vboxpci: iommu_attach_device() failed\n"); rc = VERR_INTERNAL_ERROR; } /* @todo: KVM checks IOMMU_CAP_CACHE_COHERENCY and sets flag IOMMU_CACHE later used when mapping physical addresses, which could improve performance. */ 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 }