Commit 007c99fd authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150203' into staging



Some bugfixes and cleanups for s390x, both in the new pci code and
in old code.

# gpg: Signature made Tue 03 Feb 2015 13:01:04 GMT using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"

* remotes/cohuck/tags/s390x-20150203:
  pc-bios/s390-ccw: update binary
  pc-bios/s390-ccw: fix sparse warnings
  s390x/ipl: Improved code indentation in s390_ipl_init()
  s390x/kvm: unknown DIAGNOSE code should give a specification exception
  s390x/kvm: Fix diag-308 register decoding
  s390x/pci: fix dma notifications in rpcit instruction
  s390x/pci: check for invalid function handle
  s390x/pci: avoid sign extension in stpcifc
  s390: Plug memory leak on s390_pci_generate_event() error path

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents d5fbb4c9 553ce81c
Loading
Loading
Loading
Loading
+24 −23
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ typedef struct S390IPLState {
static int s390_ipl_init(SysBusDevice *dev)
{
    S390IPLState *ipl = S390_IPL(dev);
    uint64_t pentry = KERN_IMAGE_START;
    int kernel_size;

    if (!ipl->kernel) {
@@ -94,8 +95,8 @@ static int s390_ipl_init(SysBusDevice *dev)
            hw_error("could not load bootloader '%s'\n", bios_name);
        }
        return 0;
    } else {
        uint64_t pentry = KERN_IMAGE_START;
    }

    kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
                           NULL, 1, ELF_MACHINE, 0);
    if (kernel_size < 0) {
@@ -118,7 +119,7 @@ static int s390_ipl_init(SysBusDevice *dev)
    } else {
        ipl->start_addr = pentry;
    }
    }

    if (ipl->initrd) {
        ram_addr_t initrd_offset;
        int initrd_size;
+3 −2
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
    S390pciState *s = S390_PCI_HOST_BRIDGE(
        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));

    if (!s) {
    if (!s || !fh) {
        return NULL;
    }

@@ -187,7 +187,7 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
                                    uint32_t fid, uint64_t faddr, uint32_t e)
{
    SeiContainer *sei_cont = g_malloc0(sizeof(SeiContainer));
    SeiContainer *sei_cont;
    S390pciState *s = S390_PCI_HOST_BRIDGE(
        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));

@@ -195,6 +195,7 @@ static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
        return;
    }

    sei_cont = g_malloc0(sizeof(SeiContainer));
    sei_cont->fh = fh;
    sei_cont->fid = fid;
    sei_cont->cc = cc;
+16 −12
Original line number Diff line number Diff line
@@ -487,7 +487,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
    CPUS390XState *env = &cpu->env;
    uint32_t fh;
    S390PCIBusDevice *pbdev;
    ram_addr_t size;
    hwaddr start, end;
    IOMMUTLBEntry entry;
    MemoryRegion *mr;

@@ -504,7 +504,8 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
    }

    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);

@@ -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;
    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) {
            setcc(cpu, ZPCI_PCI_LS_ERR);
            goto out;
        }

    entry.addr_mask = size - 1;
        memory_region_notify_iommu(mr, entry);
        start += entry.addr_mask + 1;
    }

    setcc(cpu, ZPCI_PCI_LS_OK);
out:
    return 0;
@@ -784,10 +788,10 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
    stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
    stq_p(&fib.fmb_addr, pbdev->fmb_addr);

    data = (pbdev->isc << 28) | (pbdev->noi << 16) |
           (pbdev->routes.adapter.ind_offset << 8) | (pbdev->sum << 7) |
           pbdev->routes.adapter.summary_offset;
    stw_p(&fib.data, data);
    data = ((uint32_t)pbdev->isc << 28) | ((uint32_t)pbdev->noi << 16) |
           ((uint32_t)pbdev->routes.adapter.ind_offset << 8) |
           ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset;
    stl_p(&fib.data, data);

    if (pbdev->fh >> ENABLE_BIT_OFFSET) {
        fib.fc |= 0x80;
(17.3 KiB)

File changed.

No diff preview for this file type.

+2 −2
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ typedef struct ResetInfo {
    uint32_t ipl_continue;
} ResetInfo;

ResetInfo save;
static ResetInfo save;

static void jump_to_IPL_2(void)
{
@@ -80,7 +80,7 @@ static void jump_to_IPL_code(uint64_t address)
 */

static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */
const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);

static inline void verify_boot_info(BootInfo *bip)
{
Loading