diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2017-07-11 13:56:20 +1000 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-07-14 12:04:41 +0200 |
commit | 1221a4746769f70231beab4db8da1c937e60340c (patch) | |
tree | bbed52840d69ac3c8a6cfbc3043e66f1d2e3bab6 /hw | |
parent | 3df9d748067f5a7f01b98ddc63597c98c8244a95 (diff) |
memory/iommu: introduce IOMMUMemoryRegionClass
This finishes QOM'fication of IOMMUMemoryRegion by introducing
a IOMMUMemoryRegionClass. This also provides a fastpath analog for
IOMMU_MEMORY_REGION_GET_CLASS().
This makes IOMMUMemoryRegion an abstract class.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-Id: <20170711035620.4232-3-aik@ozlabs.ru>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/alpha/typhoon.c | 23 | ||||
-rw-r--r-- | hw/dma/rc4030.c | 26 | ||||
-rw-r--r-- | hw/i386/amd_iommu.c | 24 | ||||
-rw-r--r-- | hw/i386/amd_iommu.h | 5 | ||||
-rw-r--r-- | hw/i386/intel_iommu.c | 25 | ||||
-rw-r--r-- | hw/pci-host/apb.c | 23 | ||||
-rw-r--r-- | hw/ppc/spapr_iommu.c | 26 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.c | 23 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.h | 1 | ||||
-rw-r--r-- | hw/s390x/s390-pci-inst.c | 5 |
10 files changed, 139 insertions, 42 deletions
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index dd47b4569f..ae11e012c7 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -17,6 +17,7 @@ #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost" +#define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region" typedef struct TyphoonCchip { MemoryRegion region; @@ -725,10 +726,6 @@ static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu, return ret; } -static const MemoryRegionIOMMUOps typhoon_iommu_ops = { - .translate = typhoon_translate_iommu, -}; - static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) { TyphoonState *s = opaque; @@ -892,7 +889,8 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, qdev_init_nofail(dev); /* Host memory as seen from the PCI side, via the IOMMU. */ - memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops, + memory_region_init_iommu(&s->pchip.iommu, sizeof(s->pchip.iommu), + TYPE_TYPHOON_IOMMU_MEMORY_REGION, OBJECT(s), "iommu-typhoon", UINT64_MAX); address_space_init(&s->pchip.iommu_as, MEMORY_REGION(&s->pchip.iommu), "pchip0-pci"); @@ -953,9 +951,24 @@ static const TypeInfo typhoon_pcihost_info = { .class_init = typhoon_pcihost_class_init, }; +static void typhoon_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = typhoon_translate_iommu; +} + +static const TypeInfo typhoon_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_TYPHOON_IOMMU_MEMORY_REGION, + .class_init = typhoon_iommu_memory_region_class_init, +}; + static void typhoon_register_types(void) { type_register_static(&typhoon_pcihost_info); + type_register_static(&typhoon_iommu_memory_region_info); } type_init(typhoon_register_types) diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index 32c06760ef..5d4833eeca 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -54,6 +54,8 @@ typedef struct dma_pagetable_entry { #define RC4030(obj) \ OBJECT_CHECK(rc4030State, (obj), TYPE_RC4030) +#define TYPE_RC4030_IOMMU_MEMORY_REGION "rc4030-iommu-memory-region" + typedef struct rc4030State { SysBusDevice parent; @@ -516,10 +518,6 @@ static IOMMUTLBEntry rc4030_dma_translate(IOMMUMemoryRegion *iommu, hwaddr addr, return ret; } -static const MemoryRegionIOMMUOps rc4030_dma_ops = { - .translate = rc4030_dma_translate, -}; - static void rc4030_reset(DeviceState *dev) { rc4030State *s = RC4030(dev); @@ -677,8 +675,9 @@ static void rc4030_realize(DeviceState *dev, Error **errp) memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s, "rc4030.jazzio", 0x00001000); - memory_region_init_iommu(&s->dma_mr, o, &rc4030_dma_ops, - "rc4030.dma", UINT32_MAX); + memory_region_init_iommu(&s->dma_mr, sizeof(s->dma_mr), + TYPE_RC4030_IOMMU_MEMORY_REGION, + o, "rc4030.dma", UINT32_MAX); address_space_init(&s->dma_as, MEMORY_REGION(&s->dma_mr), "rc4030-dma"); } @@ -710,9 +709,24 @@ static const TypeInfo rc4030_info = { .class_init = rc4030_class_init, }; +static void rc4030_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = rc4030_dma_translate; +} + +static const TypeInfo rc4030_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_RC4030_IOMMU_MEMORY_REGION, + .class_init = rc4030_iommu_memory_region_class_init, +}; + static void rc4030_register_types(void) { type_register_static(&rc4030_info); + type_register_static(&rc4030_iommu_memory_region_info); } type_init(rc4030_register_types) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 7a67c573af..334938a280 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -1044,8 +1044,11 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) iommu_as[devfn]->devfn = (uint8_t)devfn; iommu_as[devfn]->iommu_state = s; - memory_region_init_iommu(&iommu_as[devfn]->iommu, OBJECT(s), - &s->iommu_ops, "amd-iommu", UINT64_MAX); + memory_region_init_iommu(&iommu_as[devfn]->iommu, + sizeof(iommu_as[devfn]->iommu), + TYPE_AMD_IOMMU_MEMORY_REGION, + OBJECT(s), + "amd-iommu", UINT64_MAX); address_space_init(&iommu_as[devfn]->as, MEMORY_REGION(&iommu_as[devfn]->iommu), "amd-iommu"); @@ -1086,8 +1089,6 @@ static void amdvi_init(AMDVIState *s) { amdvi_iotlb_reset(s); - s->iommu_ops.translate = amdvi_translate; - s->iommu_ops.notify_flag_changed = amdvi_iommu_notify_flag_changed; s->devtab_len = 0; s->cmdbuf_len = 0; s->cmdbuf_head = 0; @@ -1228,10 +1229,25 @@ static const TypeInfo amdviPCI = { .instance_size = sizeof(AMDVIPCIState), }; +static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = amdvi_translate; + imrc->notify_flag_changed = amdvi_iommu_notify_flag_changed; +} + +static const TypeInfo amdvi_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_AMD_IOMMU_MEMORY_REGION, + .class_init = amdvi_iommu_memory_region_class_init, +}; + static void amdviPCI_register_types(void) { type_register_static(&amdviPCI); type_register_static(&amdvi); + type_register_static(&amdvi_iommu_memory_region_info); } type_init(amdviPCI_register_types); diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 0d3dc6a9f2..d370ae3549 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -220,6 +220,8 @@ #define TYPE_AMD_IOMMU_PCI "AMDVI-PCI" +#define TYPE_AMD_IOMMU_MEMORY_REGION "amd-iommu-iommu-memory-region" + typedef struct AMDVIAddressSpace AMDVIAddressSpace; /* functions to steal PCI config space */ @@ -276,9 +278,6 @@ typedef struct AMDVIState { uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */ bool mmio_enabled; - /* IOMMU function */ - MemoryRegionIOMMUOps iommu_ops; - /* for each served device */ AMDVIAddressSpace **address_spaces[PCI_BUS_MAX]; diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 11dba0e274..e398746b4b 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2718,8 +2718,9 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) * vtd_sys_alias and intel_iommu regions. IR region is always * enabled. */ - memory_region_init_iommu(&vtd_dev_as->iommu, OBJECT(s), - &s->iommu_ops, "intel_iommu_dmar", + memory_region_init_iommu(&vtd_dev_as->iommu, sizeof(vtd_dev_as->iommu), + TYPE_INTEL_IOMMU_MEMORY_REGION, OBJECT(s), + "intel_iommu_dmar", UINT64_MAX); memory_region_init_alias(&vtd_dev_as->sys_alias, OBJECT(s), "vtd_sys_alias", get_system_memory(), @@ -2857,9 +2858,6 @@ static void vtd_init(IntelIOMMUState *s) memset(s->w1cmask, 0, DMAR_REG_SIZE); memset(s->womask, 0, DMAR_REG_SIZE); - s->iommu_ops.translate = vtd_iommu_translate; - s->iommu_ops.notify_flag_changed = vtd_iommu_notify_flag_changed; - s->iommu_ops.replay = vtd_iommu_replay; s->root = 0; s->root_extended = false; s->dmar_enabled = false; @@ -3074,9 +3072,26 @@ static const TypeInfo vtd_info = { .class_init = vtd_class_init, }; +static void vtd_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = vtd_iommu_translate; + imrc->notify_flag_changed = vtd_iommu_notify_flag_changed; + imrc->replay = vtd_iommu_replay; +} + +static const TypeInfo vtd_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_INTEL_IOMMU_MEMORY_REGION, + .class_init = vtd_iommu_memory_region_class_init, +}; + static void vtd_register_types(void) { type_register_static(&vtd_info); + type_register_static(&vtd_iommu_memory_region_info); } type_init(vtd_register_types) diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 76a56ae29b..96e5d0b60d 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -133,6 +133,8 @@ typedef struct IOMMUState { #define APB_DEVICE(obj) \ OBJECT_CHECK(APBState, (obj), TYPE_APB) +#define TYPE_APB_IOMMU_MEMORY_REGION "pbm-iommu-memory-region" + typedef struct APBState { PCIHostState parent_obj; @@ -322,10 +324,6 @@ static IOMMUTLBEntry pbm_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr, return ret; } -static MemoryRegionIOMMUOps pbm_iommu_ops = { - .translate = pbm_translate_iommu, -}; - static void iommu_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -697,7 +695,8 @@ PCIBus *pci_apb_init(hwaddr special_base, is = &d->iommu; memset(is, 0, sizeof(IOMMUState)); - memory_region_init_iommu(&is->iommu, OBJECT(dev), &pbm_iommu_ops, + memory_region_init_iommu(&is->iommu, sizeof(is->iommu), + TYPE_APB_IOMMU_MEMORY_REGION, OBJECT(dev), "iommu-apb", UINT64_MAX); address_space_init(&is->iommu_as, MEMORY_REGION(&is->iommu), "pbm-as"); pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is); @@ -860,11 +859,25 @@ static const TypeInfo pbm_pci_bridge_info = { .class_init = pbm_pci_bridge_class_init, }; +static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = pbm_translate_iommu; +} + +static const TypeInfo pbm_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_APB_IOMMU_MEMORY_REGION, + .class_init = pbm_iommu_memory_region_class_init, +}; + static void pbm_register_types(void) { type_register_static(&pbm_host_info); type_register_static(&pbm_pci_host_info); type_register_static(&pbm_pci_bridge_info); + type_register_static(&pbm_iommu_memory_region_info); } type_init(pbm_register_types) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 6b6ced5710..d07b4b460d 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -248,12 +248,6 @@ static const VMStateDescription vmstate_spapr_tce_table = { } }; -static MemoryRegionIOMMUOps spapr_iommu_ops = { - .translate = spapr_tce_translate_iommu, - .get_min_page_size = spapr_tce_get_min_page_size, - .notify_flag_changed = spapr_tce_notify_flag_changed, -}; - static int spapr_tce_table_realize(DeviceState *dev) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); @@ -266,7 +260,9 @@ static int spapr_tce_table_realize(DeviceState *dev) memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX); snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn); - memory_region_init_iommu(&tcet->iommu, tcetobj, &spapr_iommu_ops, tmp, 0); + memory_region_init_iommu(&tcet->iommu, sizeof(tcet->iommu), + TYPE_SPAPR_IOMMU_MEMORY_REGION, + tcetobj, tmp, 0); QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); @@ -639,9 +635,25 @@ static TypeInfo spapr_tce_table_info = { .class_init = spapr_tce_table_class_init, }; +static void spapr_iommu_memory_region_class_init(ObjectClass *klass, void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = spapr_tce_translate_iommu; + imrc->get_min_page_size = spapr_tce_get_min_page_size; + imrc->notify_flag_changed = spapr_tce_notify_flag_changed; +} + +static const TypeInfo spapr_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_SPAPR_IOMMU_MEMORY_REGION, + .class_init = spapr_iommu_memory_region_class_init, +}; + static void register_types(void) { type_register_static(&spapr_tce_table_info); + type_register_static(&spapr_iommu_memory_region_info); } type_init(register_types); diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e4fc82cbe1..903b3cadc5 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -407,10 +407,6 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr, return ret; } -static const MemoryRegionIOMMUOps s390_iommu_ops = { - .translate = s390_translate_iommu, -}; - static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s, PCIBus *bus, int devfn) { @@ -522,8 +518,9 @@ static const MemoryRegionOps s390_msi_ctrl_ops = { void s390_pci_iommu_enable(S390PCIIOMMU *iommu) { char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid); - memory_region_init_iommu(&iommu->iommu_mr, OBJECT(&iommu->mr), - &s390_iommu_ops, name, iommu->pal + 1); + memory_region_init_iommu(&iommu->iommu_mr, sizeof(iommu->iommu_mr), + TYPE_S390_IOMMU_MEMORY_REGION, OBJECT(&iommu->mr), + name, iommu->pal + 1); iommu->enabled = true; memory_region_add_subregion(&iommu->mr, 0, MEMORY_REGION(&iommu->iommu_mr)); g_free(name); @@ -1058,12 +1055,26 @@ static TypeInfo s390_pci_iommu_info = { .instance_size = sizeof(S390PCIIOMMU), }; +static void s390_iommu_memory_region_class_init(ObjectClass *klass, void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = s390_translate_iommu; +} + +static const TypeInfo s390_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_S390_IOMMU_MEMORY_REGION, + .class_init = s390_iommu_memory_region_class_init, +}; + static void s390_pci_register_types(void) { type_register_static(&s390_pcihost_info); type_register_static(&s390_pcibus_info); type_register_static(&s390_pci_device_info); type_register_static(&s390_pci_iommu_info); + type_register_static(&s390_iommu_memory_region_info); } type_init(s390_pci_register_types) diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 6a599ed353..67af2c12ff 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -24,6 +24,7 @@ #define TYPE_S390_PCI_BUS "s390-pcibus" #define TYPE_S390_PCI_DEVICE "zpci" #define TYPE_S390_PCI_IOMMU "s390-pci-iommu" +#define TYPE_S390_IOMMU_MEMORY_REGION "s390-iommu-memory-region" #define FH_MASK_ENABLE 0x80000000 #define FH_MASK_INSTANCE 0x7f000000 #define FH_MASK_SHM 0x00ff0000 diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index a53c29c487..b7beb8c36a 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -564,6 +564,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) hwaddr start, end; IOMMUTLBEntry entry; IOMMUMemoryRegion *iommu_mr; + IOMMUMemoryRegionClass *imrc; cpu_synchronize_state(CPU(cpu)); @@ -623,8 +624,10 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) } iommu_mr = &iommu->iommu_mr; + imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); + while (start < end) { - entry = iommu_mr->iommu_ops->translate(iommu_mr, start, IOMMU_NONE); + entry = imrc->translate(iommu_mr, start, IOMMU_NONE); if (!entry.translated_addr) { pbdev->state = ZPCI_FS_ERROR; |