1b2b12376c
This patch introduce ECAP_PASID via "x-pasid-mode". Based on the existing support for scalable mode, we need to implement the following missing parts: 1) tag VTDAddressSpace with PASID and support IOMMU/DMA translation with PASID 2) tag IOTLB with PASID 3) PASID cache and its flush 4) PASID based IOTLB invalidation For simplicity PASID cache is not implemented so we can simply implement the PASID cache flush as a no and leave it to be implemented in the future. For PASID based IOTLB invalidation, since we haven't had L1 stage support, the PASID based IOTLB invalidation is not implemented yet. For PASID based device IOTLB invalidation, it requires the support for vhost so we forbid enabling device IOTLB when PASID is enabled now. Those work could be done in the future. Note that though PASID based IOMMU translation is ready but no device can issue PASID DMA right now. In this case, PCI_NO_PASID is used as PASID to identify the address without PASID. vtd_find_add_as() has been extended to provision address space with PASID which could be utilized by the future extension of PCI core to allow device model to use PASID based DMA translation. This feature would be useful for: 1) prototyping PASID support for devices like virtio 2) future vPASID work 3) future PRS and vSVA work Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20221028061436.30093-5-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
76 lines
1.9 KiB
C
76 lines
1.9 KiB
C
#ifndef QEMU_PCI_BUS_H
|
|
#define QEMU_PCI_BUS_H
|
|
|
|
#include "hw/pci/pci.h"
|
|
|
|
/*
|
|
* PCI Bus datastructures.
|
|
*
|
|
* Do not access the following members directly;
|
|
* use accessor functions in pci.h
|
|
*/
|
|
|
|
struct PCIBusClass {
|
|
/*< private >*/
|
|
BusClass parent_class;
|
|
/*< public >*/
|
|
|
|
int (*bus_num)(PCIBus *bus);
|
|
uint16_t (*numa_node)(PCIBus *bus);
|
|
};
|
|
|
|
enum PCIBusFlags {
|
|
/* This bus is the root of a PCI domain */
|
|
PCI_BUS_IS_ROOT = 0x0001,
|
|
/* PCIe extended configuration space is accessible on this bus */
|
|
PCI_BUS_EXTENDED_CONFIG_SPACE = 0x0002,
|
|
/* This is a CXL Type BUS */
|
|
PCI_BUS_CXL = 0x0004,
|
|
};
|
|
|
|
#define PCI_NO_PASID UINT32_MAX
|
|
|
|
struct PCIBus {
|
|
BusState qbus;
|
|
enum PCIBusFlags flags;
|
|
PCIIOMMUFunc iommu_fn;
|
|
void *iommu_opaque;
|
|
uint8_t devfn_min;
|
|
uint32_t slot_reserved_mask;
|
|
pci_set_irq_fn set_irq;
|
|
pci_map_irq_fn map_irq;
|
|
pci_route_irq_fn route_intx_to_irq;
|
|
void *irq_opaque;
|
|
PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
|
|
PCIDevice *parent_dev;
|
|
MemoryRegion *address_space_mem;
|
|
MemoryRegion *address_space_io;
|
|
|
|
QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
|
|
QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
|
|
|
|
/* The bus IRQ state is the logical OR of the connected devices.
|
|
Keep a count of the number of devices with raised IRQs. */
|
|
int nirq;
|
|
int *irq_count;
|
|
|
|
Notifier machine_done;
|
|
};
|
|
|
|
static inline bool pci_bus_is_cxl(PCIBus *bus)
|
|
{
|
|
return !!(bus->flags & PCI_BUS_CXL);
|
|
}
|
|
|
|
static inline bool pci_bus_is_root(PCIBus *bus)
|
|
{
|
|
return !!(bus->flags & PCI_BUS_IS_ROOT);
|
|
}
|
|
|
|
static inline bool pci_bus_allows_extended_config_space(PCIBus *bus)
|
|
{
|
|
return !!(bus->flags & PCI_BUS_EXTENDED_CONFIG_SPACE);
|
|
}
|
|
|
|
#endif /* QEMU_PCI_BUS_H */
|