pci_device_get_viommu_cap() call pci_device_get_iommu_bus_devfn() to get iommu_bus->iommu_ops and call get_viommu_cap() callback to get a bitmap with each bit represents a vIOMMU exposed capability.
Suggested-by: Yi Liu <yi.l....@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- MAINTAINERS | 1 + hw/pci/pci.c | 11 +++++++++++ include/hw/iommu.h | 16 ++++++++++++++++ include/hw/pci/pci.h | 23 +++++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 include/hw/iommu.h diff --git a/MAINTAINERS b/MAINTAINERS index 1842c3dd83..d9fc977b81 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2302,6 +2302,7 @@ F: include/system/iommufd.h F: backends/host_iommu_device.c F: include/system/host_iommu_device.h F: include/qemu/chardev_open.h +F: include/hw/iommu.h F: util/chardev_open.c F: docs/devel/vfio-iommufd.rst diff --git a/hw/pci/pci.c b/hw/pci/pci.c index c70b5ceeba..df1fb615a8 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2992,6 +2992,17 @@ void pci_device_unset_iommu_device(PCIDevice *dev) } } +uint64_t pci_device_get_viommu_cap(PCIDevice *dev) +{ + PCIBus *iommu_bus; + + pci_device_get_iommu_bus_devfn(dev, &iommu_bus, NULL, NULL); + if (iommu_bus && iommu_bus->iommu_ops->get_viommu_cap) { + return iommu_bus->iommu_ops->get_viommu_cap(iommu_bus->iommu_opaque); + } + return 0; +} + 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) diff --git a/include/hw/iommu.h b/include/hw/iommu.h new file mode 100644 index 0000000000..e80aaf4431 --- /dev/null +++ b/include/hw/iommu.h @@ -0,0 +1,16 @@ +/* + * General vIOMMU capabilities, flags, etc + * + * Copyright (C) 2025 Intel Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_IOMMU_H +#define HW_IOMMU_H + +enum { + VIOMMU_CAP_STAGE1 = BIT_ULL(0), /* stage1 page table supported */ +}; + +#endif /* HW_IOMMU_H */ diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index df3cc7b875..a11ab14bdc 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -453,6 +453,19 @@ typedef struct PCIIOMMUOps { * @devfn: device and function number of the PCI device. */ void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn); + /** + * @get_viommu_cap: get vIOMMU capabilities + * + * Optional callback, if not implemented, then vIOMMU doesn't + * support exposing capabilities to other subsystem, e.g., VFIO. + * vIOMMU can choose which capabilities to expose. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * Returns: 64bit bitmap with each bit represents a capability emulated + * by VIOMMU_CAP_* in include/hw/iommu.h + */ + uint64_t (*get_viommu_cap)(void *opaque); /** * @get_iotlb_info: get properties required to initialize a device IOTLB. * @@ -633,6 +646,16 @@ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, Error **errp); void pci_device_unset_iommu_device(PCIDevice *dev); +/** + * pci_device_get_viommu_cap: get vIOMMU capabilities. + * + * Returns a 64bit bitmap with each bit represents a vIOMMU exposed + * capability, 0 if vIOMMU doesn't support esposing capabilities. + * + * @dev: PCI device pointer. + */ +uint64_t pci_device_get_viommu_cap(PCIDevice *dev); + /** * pci_iommu_get_iotlb_info: get properties required to initialize a * device IOTLB. -- 2.47.1