Commit 0bb11379 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents eab9e962 88ee13c7
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -463,7 +463,6 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
                                unsigned int size)
{
    S390PCIBusDevice *pbdev = opaque;
    uint32_t io_int_word;
    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
    uint32_t vec = data & ZPCI_MSI_VEC_MASK;
    uint64_t ind_bit;
@@ -489,8 +488,7 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
                   0x80 >> ((ind_bit + vec) % 8));
    if (!set_ind_atomic(pbdev->routes.adapter.summary_addr + sum_bit / 8,
                                       0x80 >> (sum_bit % 8))) {
        io_int_word = (pbdev->isc << 27) | IO_INT_WORD_AI;
        s390_io_interrupt(0, 0, 0, io_int_word);
        css_adapter_interrupt(pbdev->isc);
    }
}

+20 −5
Original line number Diff line number Diff line
@@ -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,
        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);