diff options
author | Peter Maydell | 2016-10-31 15:48:47 +0100 |
---|---|---|
committer | Peter Maydell | 2016-10-31 15:48:47 +0100 |
commit | 0bb1137930f51a89fb1bfeb0c46aa68af0395167 (patch) | |
tree | 6456b6a0e0008f47710b6b301dd64471c1601b43 /hw/s390x/s390-pci-inst.c | |
parent | Merge remote-tracking branch 'remotes/amit-migration/tags/migration-for-2.8' ... (diff) | |
parent | s390x/pci: Check memory region dispatching callbacks (diff) | |
download | qemu-0bb1137930f51a89fb1bfeb0c46aa68af0395167.tar.gz qemu-0bb1137930f51a89fb1bfeb0c46aa68af0395167.tar.xz qemu-0bb1137930f51a89fb1bfeb0c46aa68af0395167.zip |
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20161031' into staging
Two PCI fixes/improvements for s390x.
# gpg: Signature made Mon 31 Oct 2016 10:09:24 GMT
# gpg: using RSA key 0xDECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF
* remotes/cohuck/tags/s390x-20161031:
s390x/pci: Check memory region dispatching callbacks
s390x/pci: use generic interface to inject interrupt
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/s390x/s390-pci-inst.c')
-rw-r--r-- | hw/s390x/s390-pci-inst.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 80a51049ca..0864d9be12 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -316,6 +316,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) uint64_t offset; uint64_t data; MemoryRegion *mr; + MemTxResult result; uint8_t len; uint32_t fh; uint8_t pcias; @@ -365,8 +366,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) return 0; } mr = pbdev->pdev->io_regions[pcias].memory; - memory_region_dispatch_read(mr, offset, &data, len, - MEMTXATTRS_UNSPECIFIED); + result = memory_region_dispatch_read(mr, offset, &data, len, + MEMTXATTRS_UNSPECIFIED); + if (result != MEMTX_OK) { + program_interrupt(env, PGM_OPERAND, 4); + return 0; + } } else if (pcias == 15) { if ((4 - (offset & 0x3)) < len) { program_interrupt(env, PGM_OPERAND, 4); @@ -444,6 +449,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) uint64_t offset, data; S390PCIBusDevice *pbdev; MemoryRegion *mr; + MemTxResult result; uint8_t len; uint32_t fh; uint8_t pcias; @@ -502,8 +508,12 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) mr = pbdev->pdev->io_regions[pcias].memory; } - memory_region_dispatch_write(mr, offset, data, len, + result = memory_region_dispatch_write(mr, offset, data, len, MEMTXATTRS_UNSPECIFIED); + if (result != MEMTX_OK) { + program_interrupt(env, PGM_OPERAND, 4); + return 0; + } } else if (pcias == 15) { if ((4 - (offset & 0x3)) < len) { program_interrupt(env, PGM_OPERAND, 4); @@ -633,6 +643,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr, CPUS390XState *env = &cpu->env; S390PCIBusDevice *pbdev; MemoryRegion *mr; + MemTxResult result; int i; uint32_t fh; uint8_t pcias; @@ -690,7 +701,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr, mr = pbdev->pdev->io_regions[pcias].memory; if (!memory_region_access_valid(mr, env->regs[r3], len, true)) { - program_interrupt(env, PGM_ADDRESSING, 6); + program_interrupt(env, PGM_OPERAND, 6); return 0; } @@ -699,9 +710,13 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr, } for (i = 0; i < len / 8; i++) { - memory_region_dispatch_write(mr, env->regs[r3] + i * 8, + result = memory_region_dispatch_write(mr, env->regs[r3] + i * 8, ldq_p(buffer + i * 8), 8, MEMTXATTRS_UNSPECIFIED); + if (result != MEMTX_OK) { + program_interrupt(env, PGM_OPERAND, 6); + return 0; + } } setcc(cpu, ZPCI_PCI_LS_OK); |