aboutsummaryrefslogtreecommitdiff
path: root/hw/s390x
diff options
context:
space:
mode:
Diffstat (limited to 'hw/s390x')
-rw-r--r--hw/s390x/s390-pci-inst.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index d9e1e29f1e..76b08a39a7 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -755,7 +755,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
int i;
uint32_t fh;
uint8_t pcias;
- uint8_t len;
+ uint16_t len;
uint8_t buffer[128];
if (env->psw.mask & PSW_MASK_PSTATE) {
@@ -765,7 +765,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
fh = env->regs[r1] >> 32;
pcias = (env->regs[r1] >> 16) & 0xf;
- len = env->regs[r1] & 0xff;
+ len = env->regs[r1] & 0x1fff;
offset = env->regs[r3];
if (!(fh & FH_MASK_ENABLE)) {
@@ -821,10 +821,12 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
mr = s390_get_subregion(mr, offset, len);
offset -= mr->addr;
- if (!memory_region_access_valid(mr, offset, len, true,
- MEMTXATTRS_UNSPECIFIED)) {
- s390_program_interrupt(env, PGM_OPERAND, ra);
- return 0;
+ for (i = 0; i < len; i += 8) {
+ if (!memory_region_access_valid(mr, offset + i, 8, true,
+ MEMTXATTRS_UNSPECIFIED)) {
+ s390_program_interrupt(env, PGM_OPERAND, ra);
+ return 0;
+ }
}
if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {