mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
pci: Add a PCI-level API for PRI
A device can send a PRI request to the IOMMU using pci_pri_request_page. The PRI response is sent back using the notifier managed with pci_pri_register_notifier and pci_pri_unregister_notifier. Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com> Co-authored-by: Ethan Milon <ethan.milon@eviden.com> Message-Id: <20250520071823.764266-12-clement.mathieu--drif@eviden.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
e9b457500a
commit
f0f37daf8e
2 changed files with 196 additions and 0 deletions
66
hw/pci/pci.c
66
hw/pci/pci.c
|
@ -2987,6 +2987,72 @@ void pci_device_unset_iommu_device(PCIDevice *dev)
|
|||
}
|
||||
}
|
||||
|
||||
int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
|
||||
bool exec_req, hwaddr addr, bool lpig,
|
||||
uint16_t prgi, bool is_read, bool is_write)
|
||||
{
|
||||
PCIBus *bus;
|
||||
PCIBus *iommu_bus;
|
||||
int devfn;
|
||||
|
||||
if (!dev->is_master ||
|
||||
((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!pcie_pri_enabled(dev)) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
|
||||
if (iommu_bus && iommu_bus->iommu_ops->pri_request_page) {
|
||||
return iommu_bus->iommu_ops->pri_request_page(bus,
|
||||
iommu_bus->iommu_opaque,
|
||||
devfn, pasid, priv_req,
|
||||
exec_req, addr, lpig, prgi,
|
||||
is_read, is_write);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
|
||||
IOMMUPRINotifier *notifier)
|
||||
{
|
||||
PCIBus *bus;
|
||||
PCIBus *iommu_bus;
|
||||
int devfn;
|
||||
|
||||
if (!dev->is_master ||
|
||||
((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
|
||||
if (iommu_bus && iommu_bus->iommu_ops->pri_register_notifier) {
|
||||
iommu_bus->iommu_ops->pri_register_notifier(bus,
|
||||
iommu_bus->iommu_opaque,
|
||||
devfn, pasid, notifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid)
|
||||
{
|
||||
PCIBus *bus;
|
||||
PCIBus *iommu_bus;
|
||||
int devfn;
|
||||
|
||||
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
|
||||
if (iommu_bus && iommu_bus->iommu_ops->pri_unregister_notifier) {
|
||||
iommu_bus->iommu_ops->pri_unregister_notifier(bus,
|
||||
iommu_bus->iommu_opaque,
|
||||
devfn, pasid);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid,
|
||||
bool priv_req, bool exec_req,
|
||||
hwaddr addr, size_t length,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue