mirror of https://github.com/xqemu/xqemu.git
s390x/pci: fix dma notifications in rpcit instruction
The virtual I/O address range passed to rpcit instruction might not map to consecutive physical guest pages. For this we have to translate and create mapping notifications for each vioa page separately. Signed-off-by: Yi Min Zhao <zyimin@cn.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
5b324bbafc
commit
4e99a0f7ae
|
@ -487,7 +487,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
|
||||||
CPUS390XState *env = &cpu->env;
|
CPUS390XState *env = &cpu->env;
|
||||||
uint32_t fh;
|
uint32_t fh;
|
||||||
S390PCIBusDevice *pbdev;
|
S390PCIBusDevice *pbdev;
|
||||||
ram_addr_t size;
|
hwaddr start, end;
|
||||||
IOMMUTLBEntry entry;
|
IOMMUTLBEntry entry;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
|
|
||||||
|
@ -504,7 +504,8 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fh = env->regs[r1] >> 32;
|
fh = env->regs[r1] >> 32;
|
||||||
size = env->regs[r2 + 1];
|
start = env->regs[r2];
|
||||||
|
end = start + env->regs[r2 + 1];
|
||||||
|
|
||||||
pbdev = s390_pci_find_dev_by_fh(fh);
|
pbdev = s390_pci_find_dev_by_fh(fh);
|
||||||
|
|
||||||
|
@ -515,15 +516,18 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
|
||||||
}
|
}
|
||||||
|
|
||||||
mr = pci_device_iommu_address_space(pbdev->pdev)->root;
|
mr = pci_device_iommu_address_space(pbdev->pdev)->root;
|
||||||
entry = mr->iommu_ops->translate(mr, env->regs[r2], 0);
|
while (start < end) {
|
||||||
|
entry = mr->iommu_ops->translate(mr, start, 0);
|
||||||
|
|
||||||
if (!entry.translated_addr) {
|
if (!entry.translated_addr) {
|
||||||
setcc(cpu, ZPCI_PCI_LS_ERR);
|
setcc(cpu, ZPCI_PCI_LS_ERR);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_notify_iommu(mr, entry);
|
||||||
|
start += entry.addr_mask + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.addr_mask = size - 1;
|
|
||||||
memory_region_notify_iommu(mr, entry);
|
|
||||||
setcc(cpu, ZPCI_PCI_LS_OK);
|
setcc(cpu, ZPCI_PCI_LS_OK);
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue