This field is only used when S390PCIBusDevice exists, so it can be moved
there to simplify S390PCIIOMMU which purpose is just to store the "root"
AddressSpace.
Signed-off-by: Konstantin Shkolnyy <kshk@linux.ibm.com>
---
hw/s390x/s390-pci-bus.c | 32 ++++++++++++++++++--------------
hw/s390x/s390-pci-inst.c | 28 +++++++++++++++-------------
include/hw/s390x/s390-pci-bus.h | 6 +++---
include/hw/s390x/s390-pci-inst.h | 4 ++--
4 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 3665aba106..99d503e85e 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -206,7 +206,7 @@ void s390_pci_sclp_deconfigure(SCCB *sccb)
pci_dereg_irqs(pbdev);
}
if (pbdev->iommu->enabled) {
- pci_dereg_ioat(pbdev->iommu);
+ pci_dereg_ioat(pbdev);
}
pbdev->state = ZPCI_FS_STANDBY;
rc = SCLP_RC_NORMAL_COMPLETION;
@@ -538,7 +538,8 @@ uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr,
static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
IOMMUAccessFlags flag, int iommu_idx)
{
- S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr);
+ S390PCIBusDevice *pbdev = container_of(mr, S390PCIBusDevice, iommu_mr);
+ S390PCIIOMMU *iommu = pbdev->iommu;
S390IOTLBEntry *entry;
uint64_t iova = addr & TARGET_PAGE_MASK;
uint16_t error = 0;
@@ -592,12 +593,13 @@ err:
return ret;
}
-static void s390_pci_ioat_replay(S390PCIIOMMU *iommu)
+static void s390_pci_ioat_replay(S390PCIBusDevice *pbdev)
{
S390IOTLBEntry entry;
uint16_t error = 0;
uint32_t dma_avail;
hwaddr curr, end;
+ S390PCIIOMMU *iommu = pbdev->iommu;
curr = iommu->pba;
end = iommu->pal;
@@ -622,7 +624,7 @@ static void s390_pci_ioat_replay(S390PCIIOMMU *iommu)
if (entry.perm != IOMMU_NONE) {
if (dma_avail > 0) {
- dma_avail = s390_pci_update_iotlb(iommu, &entry);
+ dma_avail = s390_pci_update_iotlb(pbdev, &entry);
} else {
error_report("DMA mappings exhausted: iommu remap failed");
return;
@@ -635,9 +637,9 @@ static void s390_pci_ioat_replay(S390PCIIOMMU *iommu)
static void s390_pci_iommu_replay(IOMMUMemoryRegion *mr,
IOMMUNotifier *notifier)
{
- S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr);
+ S390PCIBusDevice *pbdev = container_of(mr, S390PCIBusDevice, iommu_mr);
- s390_pci_ioat_replay(iommu);
+ s390_pci_ioat_replay(pbdev);
}
static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s, PCIBus *bus,
@@ -759,19 +761,20 @@ static const MemoryRegionOps s390_msi_ctrl_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
+void s390_pci_iommu_enable(S390PCIBusDevice *pbdev)
{
+ S390PCIIOMMU *iommu = pbdev->iommu;
/*
* The iommu region is initialized against a 0-mapped address space,
* so the smallest IOMMU region we can define runs from 0 to the end
* of the PCI address space.
*/
char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid);
- memory_region_init_iommu(&iommu->iommu_mr, sizeof(iommu->iommu_mr),
+ memory_region_init_iommu(&pbdev->iommu_mr, sizeof(pbdev->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));
+ memory_region_add_subregion(&iommu->mr, 0, MEMORY_REGION(&pbdev->iommu_mr));
g_free(name);
}
@@ -797,8 +800,9 @@ void s390_pci_iommu_direct_map_enable(S390PCIIOMMU *iommu)
iommu->dm_mr);
}
-void s390_pci_iommu_disable(S390PCIIOMMU *iommu)
+void s390_pci_iommu_disable(S390PCIBusDevice *pbdev)
{
+ S390PCIIOMMU *iommu = pbdev->iommu;
iommu->enabled = false;
g_hash_table_remove_all(iommu->iotlb);
if (iommu->dm_mr) {
@@ -808,8 +812,8 @@ void s390_pci_iommu_disable(S390PCIIOMMU *iommu)
iommu->dm_mr = NULL;
} else {
memory_region_del_subregion(&iommu->mr,
- MEMORY_REGION(&iommu->iommu_mr));
- object_unparent(OBJECT(&iommu->iommu_mr));
+ MEMORY_REGION(&pbdev->iommu_mr));
+ object_unparent(OBJECT(&pbdev->iommu_mr));
}
}
@@ -1408,7 +1412,7 @@ static void s390_pcihost_reset(DeviceState *dev)
pci_dereg_irqs(pbdev);
}
if (pbdev->iommu->enabled) {
- pci_dereg_ioat(pbdev->iommu);
+ pci_dereg_ioat(pbdev);
}
pbdev->state = ZPCI_FS_STANDBY;
s390_pci_perform_unplug(pbdev);
@@ -1549,7 +1553,7 @@ static void s390_pci_device_reset(DeviceState *dev)
pci_dereg_irqs(pbdev);
}
if (pbdev->iommu->enabled) {
- pci_dereg_ioat(pbdev->iommu);
+ pci_dereg_ioat(pbdev);
}
fmb_timer_free(pbdev);
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 7c784b31f3..ed60e6100e 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -613,9 +613,10 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
return 0;
}
-uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
+uint32_t s390_pci_update_iotlb(S390PCIBusDevice *pbdev,
S390IOTLBEntry *entry)
{
+ S390PCIIOMMU *iommu = pbdev->iommu;
S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
IOMMUTLBEvent event = {
.type = entry->perm ? IOMMU_NOTIFIER_MAP : IOMMU_NOTIFIER_UNMAP,
@@ -645,7 +646,7 @@ uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
event.type = IOMMU_NOTIFIER_UNMAP;
event.entry.perm = IOMMU_NONE;
- memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
+ memory_region_notify_iommu(&pbdev->iommu_mr, 0, event);
event.type = IOMMU_NOTIFIER_MAP;
event.entry.perm = entry->perm;
}
@@ -663,13 +664,13 @@ uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
* All associated iotlb entries have already been cleared, trigger the
* unmaps.
*/
- memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
+ memory_region_notify_iommu(&pbdev->iommu_mr, 0, event);
out:
return iommu->dma_limit ? iommu->dma_limit->avail : 1;
}
-static void s390_pci_batch_unmap(S390PCIIOMMU *iommu, uint64_t iova,
+static void s390_pci_batch_unmap(S390PCIBusDevice *pbdev, uint64_t iova,
uint64_t len)
{
uint64_t remain = len, start = iova, end = start + len - 1, mask, size;
@@ -687,7 +688,7 @@ static void s390_pci_batch_unmap(S390PCIIOMMU *iommu, uint64_t iova,
size = mask + 1;
event.entry.iova = start;
event.entry.addr_mask = mask;
- memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
+ memory_region_notify_iommu(&pbdev->iommu_mr, 0, event);
start += size;
remain -= size;
}
@@ -778,14 +779,14 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
coalesce += entry.len;
} else if (coalesce > 0) {
/* Unleash the coalesced unmap before processing a new map */
- s390_pci_batch_unmap(iommu, iova, coalesce);
+ s390_pci_batch_unmap(pbdev, iova, coalesce);
coalesce = 0;
}
start += entry.len;
while (entry.iova < start && entry.iova < end) {
if (dma_avail > 0 || entry.perm == IOMMU_NONE) {
- dma_avail = s390_pci_update_iotlb(iommu, &entry);
+ dma_avail = s390_pci_update_iotlb(pbdev, &entry);
entry.iova += TARGET_PAGE_SIZE;
entry.translated_addr += TARGET_PAGE_SIZE;
} else {
@@ -801,7 +802,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
}
if (coalesce) {
/* Unleash the coalesced unmap before finishing rpcit */
- s390_pci_batch_unmap(iommu, iova, coalesce);
+ s390_pci_batch_unmap(pbdev, iova, coalesce);
coalesce = 0;
}
if (again && dma_avail > 0)
@@ -1031,7 +1032,7 @@ static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
iommu->g_iota = g_iota;
if (t) {
- s390_pci_iommu_enable(iommu);
+ s390_pci_iommu_enable(pbdev);
} else {
s390_pci_iommu_direct_map_enable(iommu);
}
@@ -1039,9 +1040,10 @@ static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
return 0;
}
-void pci_dereg_ioat(S390PCIIOMMU *iommu)
+void pci_dereg_ioat(S390PCIBusDevice *pbdev)
{
- s390_pci_iommu_disable(iommu);
+ S390PCIIOMMU *iommu = pbdev->iommu;
+ s390_pci_iommu_disable(pbdev);
iommu->pba = 0;
iommu->pal = 0;
iommu->g_iota = 0;
@@ -1265,7 +1267,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
cc = ZPCI_PCI_LS_ERR;
s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
} else {
- pci_dereg_ioat(pbdev->iommu);
+ pci_dereg_ioat(pbdev);
}
break;
case ZPCI_MOD_FC_REREG_IOAT:
@@ -1276,7 +1278,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
cc = ZPCI_PCI_LS_ERR;
s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
} else {
- pci_dereg_ioat(pbdev->iommu);
+ pci_dereg_ioat(pbdev);
if (reg_ioat(env, pbdev, fib, ra)) {
cc = ZPCI_PCI_LS_ERR;
s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
index eb15cb8b2d..a71f562dfc 100644
--- a/include/hw/s390x/s390-pci-bus.h
+++ b/include/hw/s390x/s390-pci-bus.h
@@ -276,7 +276,6 @@ struct S390PCIIOMMU {
S390PCIBusDevice *pbdev;
AddressSpace as;
MemoryRegion mr;
- IOMMUMemoryRegion iommu_mr;
MemoryRegion *dm_mr;
bool enabled;
uint64_t g_iota;
@@ -354,6 +353,7 @@ struct S390PCIBusDevice {
S390MsixInfo msix;
AdapterRoutes routes;
S390PCIIOMMU *iommu;
+ IOMMUMemoryRegion iommu_mr;
MemoryRegion msix_notify_mr;
IndAddr *summary_ind;
IndAddr *indicator;
@@ -391,9 +391,9 @@ int pci_chsc_sei_nt2_have_event(void);
void s390_pci_sclp_configure(SCCB *sccb);
void s390_pci_sclp_deconfigure(SCCB *sccb);
bool s390_pci_is_translation_enabled(uint64_t g_iota);
-void s390_pci_iommu_enable(S390PCIIOMMU *iommu);
+void s390_pci_iommu_enable(S390PCIBusDevice *pbdev);
void s390_pci_iommu_direct_map_enable(S390PCIIOMMU *iommu);
-void s390_pci_iommu_disable(S390PCIIOMMU *iommu);
+void s390_pci_iommu_disable(S390PCIBusDevice *pbdev);
void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid,
uint64_t faddr, uint32_t e);
uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr,
diff --git a/include/hw/s390x/s390-pci-inst.h b/include/hw/s390x/s390-pci-inst.h
index c782990e3b..38268c256e 100644
--- a/include/hw/s390x/s390-pci-inst.h
+++ b/include/hw/s390x/s390-pci-inst.h
@@ -99,7 +99,7 @@ typedef struct ZpciFib {
} QEMU_PACKED ZpciFib;
int pci_dereg_irqs(S390PCIBusDevice *pbdev);
-void pci_dereg_ioat(S390PCIIOMMU *iommu);
+void pci_dereg_ioat(S390PCIBusDevice *pbdev);
int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra);
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
@@ -111,7 +111,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra);
void fmb_timer_free(S390PCIBusDevice *pbdev);
-uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry);
+uint32_t s390_pci_update_iotlb(S390PCIBusDevice *pbdev, S390IOTLBEntry *entry);
#define ZPCI_IO_BAR_MIN 0
#define ZPCI_IO_BAR_MAX 5
--
2.34.1