mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
s390x/pci: Check memory region dispatching callbacks
The instructions PCI STORE, PCI LOAD and PCI STORE BLOCK use calls to memory_region_dispatch_write() and memory_region_dispatch_read() but do not test the return value. Furthermore, the instruction PCI STORE BLOCK sets up a PGM_ADDRESSING exception when the operand 3 is not within the designated PCI address space instead of a PGM_OPERAND exception. Let's setup a PGM_OPERAND exception in all of these failure cases. Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
45bbcd35d7
commit
88ee13c7b6
1 changed files with 20 additions and 5 deletions
|
@ -316,6 +316,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
|
MemTxResult result;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint32_t fh;
|
uint32_t fh;
|
||||||
uint8_t pcias;
|
uint8_t pcias;
|
||||||
|
@ -365,8 +366,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mr = pbdev->pdev->io_regions[pcias].memory;
|
mr = pbdev->pdev->io_regions[pcias].memory;
|
||||||
memory_region_dispatch_read(mr, offset, &data, len,
|
result = memory_region_dispatch_read(mr, offset, &data, len,
|
||||||
MEMTXATTRS_UNSPECIFIED);
|
MEMTXATTRS_UNSPECIFIED);
|
||||||
|
if (result != MEMTX_OK) {
|
||||||
|
program_interrupt(env, PGM_OPERAND, 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else if (pcias == 15) {
|
} else if (pcias == 15) {
|
||||||
if ((4 - (offset & 0x3)) < len) {
|
if ((4 - (offset & 0x3)) < len) {
|
||||||
program_interrupt(env, PGM_OPERAND, 4);
|
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;
|
uint64_t offset, data;
|
||||||
S390PCIBusDevice *pbdev;
|
S390PCIBusDevice *pbdev;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
|
MemTxResult result;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint32_t fh;
|
uint32_t fh;
|
||||||
uint8_t pcias;
|
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;
|
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);
|
MEMTXATTRS_UNSPECIFIED);
|
||||||
|
if (result != MEMTX_OK) {
|
||||||
|
program_interrupt(env, PGM_OPERAND, 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else if (pcias == 15) {
|
} else if (pcias == 15) {
|
||||||
if ((4 - (offset & 0x3)) < len) {
|
if ((4 - (offset & 0x3)) < len) {
|
||||||
program_interrupt(env, PGM_OPERAND, 4);
|
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;
|
CPUS390XState *env = &cpu->env;
|
||||||
S390PCIBusDevice *pbdev;
|
S390PCIBusDevice *pbdev;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
|
MemTxResult result;
|
||||||
int i;
|
int i;
|
||||||
uint32_t fh;
|
uint32_t fh;
|
||||||
uint8_t pcias;
|
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;
|
mr = pbdev->pdev->io_regions[pcias].memory;
|
||||||
if (!memory_region_access_valid(mr, env->regs[r3], len, true)) {
|
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;
|
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++) {
|
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,
|
ldq_p(buffer + i * 8), 8,
|
||||||
MEMTXATTRS_UNSPECIFIED);
|
MEMTXATTRS_UNSPECIFIED);
|
||||||
|
if (result != MEMTX_OK) {
|
||||||
|
program_interrupt(env, PGM_OPERAND, 6);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setcc(cpu, ZPCI_PCI_LS_OK);
|
setcc(cpu, ZPCI_PCI_LS_OK);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue