Commit c6370441 authored by Eric Auger's avatar Eric Auger Committed by Peter Maydell
Browse files

hw/arm/smmuv3: Remove SMMUNotifierNode



The SMMUNotifierNode struct is not necessary and brings extra
complexity so let's remove it. We now directly track the SMMUDevices
which have registered IOMMU MR notifiers.

This is inspired from the same transformation on intel-iommu
done in commit b4a4ba0d
("intel-iommu: remove IntelIOMMUNotifierNode")

Signed-off-by: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 413a99a9
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -412,10 +412,10 @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
/* Unmap all notifiers of all mr's */
void smmu_inv_notifiers_all(SMMUState *s)
{
    SMMUNotifierNode *node;
    SMMUDevice *sdev;

    QLIST_FOREACH(node, &s->notifiers_list, next) {
        smmu_inv_notifiers_mr(&node->sdev->iommu);
    QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
        smmu_inv_notifiers_mr(&sdev->iommu);
    }
}

+7 −21
Original line number Diff line number Diff line
@@ -828,10 +828,10 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
/* invalidate an asid/iova tuple in all mr's */
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
{
    SMMUNotifierNode *node;
    SMMUDevice *sdev;

    QLIST_FOREACH(node, &s->notifiers_list, next) {
        IOMMUMemoryRegion *mr = &node->sdev->iommu;
    QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
        IOMMUMemoryRegion *mr = &sdev->iommu;
        IOMMUNotifier *n;

        trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
@@ -1472,8 +1472,6 @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
    SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
    SMMUv3State *s3 = sdev->smmu;
    SMMUState *s = &(s3->smmu_state);
    SMMUNotifierNode *node = NULL;
    SMMUNotifierNode *next_node = NULL;

    if (new & IOMMU_NOTIFIER_MAP) {
        int bus_num = pci_bus_num(sdev->bus);
@@ -1485,22 +1483,10 @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,

    if (old == IOMMU_NOTIFIER_NONE) {
        trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
        node = g_malloc0(sizeof(*node));
        node->sdev = sdev;
        QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
        return;
    }

    /* update notifier node with new flags */
    QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
        if (node->sdev == sdev) {
            if (new == IOMMU_NOTIFIER_NONE) {
        QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
    } else if (new == IOMMU_NOTIFIER_NONE) {
        trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
                QLIST_REMOVE(node, next);
                g_free(node);
            }
            return;
        }
        QLIST_REMOVE(sdev, next);
    }
}

+2 −6
Original line number Diff line number Diff line
@@ -80,13 +80,9 @@ typedef struct SMMUDevice {
    AddressSpace       as;
    uint32_t           cfg_cache_hits;
    uint32_t           cfg_cache_misses;
    QLIST_ENTRY(SMMUDevice) next;
} SMMUDevice;

typedef struct SMMUNotifierNode {
    SMMUDevice *sdev;
    QLIST_ENTRY(SMMUNotifierNode) next;
} SMMUNotifierNode;

typedef struct SMMUPciBus {
    PCIBus       *bus;
    SMMUDevice   *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
@@ -108,7 +104,7 @@ typedef struct SMMUState {
    GHashTable *iotlb;
    SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
    PCIBus *pci_bus;
    QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
    QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
    uint8_t bus_num;
    PCIBus *primary_bus;
} SMMUState;