Commit c5d128ff authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20160927' into staging



Couple of s390x patches:
- some PCI cleanups
- fix build error due to uuid rework
- fix potential deadlock in sigp handling
- enable ccw devices in BIOS and enforce checking in QEMU

# gpg: Signature made Wed 28 Sep 2016 12:27:03 BST
# gpg:                using RSA key 0x117BBC80B5A61C7C
# gpg: Good signature from "Christian Borntraeger (IBM) <borntraeger@de.ibm.com>"
# Primary key fingerprint: F922 9381 A334 08F9 DBAB  FBCA 117B BC80 B5A6 1C7C

* remotes/borntraeger/tags/s390x-20160927:
  s390x/kvm: fix build against qemu_uuid
  s390x/css: {c,h,t,r,x}sch: require enable AND device number valid
  pc-bios/s390-ccw.img: rebuild image
  pc-bios/s390-ccw: enable subchannel for IPL I/O devices
  s390x/kvm: Fix potential deadlock in sigp handling
  s390x/pci: code cleanup
  s390x/pci: assign msix io region for each pci device
  s390x/pci: re-arrange variable declarations

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c69e3cef 794afd70
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -775,7 +775,7 @@ int css_do_xsch(SubchDev *sch)
    PMCW *p = &sch->curr_status.pmcw;
    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        ret = -ENODEV;
        goto out;
    }
@@ -815,7 +815,7 @@ int css_do_csch(SubchDev *sch)
    PMCW *p = &sch->curr_status.pmcw;
    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        ret = -ENODEV;
        goto out;
    }
@@ -837,7 +837,7 @@ int css_do_hsch(SubchDev *sch)
    PMCW *p = &sch->curr_status.pmcw;
    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        ret = -ENODEV;
        goto out;
    }
@@ -913,7 +913,7 @@ int css_do_ssch(SubchDev *sch, ORB *orb)
    PMCW *p = &sch->curr_status.pmcw;
    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        ret = -ENODEV;
        goto out;
    }
@@ -990,7 +990,7 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
    uint16_t stctl;
    IRB irb;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        return 3;
    }

@@ -1196,7 +1196,7 @@ int css_do_rsch(SubchDev *sch)
    PMCW *p = &sch->curr_status.pmcw;
    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
    if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
        ret = -ENODEV;
        goto out;
    }
+26 −22
Original line number Diff line number Diff line
@@ -383,7 +383,6 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
    uint64_t pte;
    uint32_t flags;
    S390PCIBusDevice *pbdev = container_of(iommu, S390PCIBusDevice, iommu_mr);
    S390pciState *s;
    IOMMUTLBEntry ret = {
        .target_as = &address_space_memory,
        .iova = 0,
@@ -405,19 +404,6 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,

    DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr);

    s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pbdev->pdev)->qbus.parent);
    /* s390 does not have an APIC mapped to main storage so we use
     * a separate AddressSpace only for msix notifications
     */
    if (addr == ZPCI_MSI_ADDR) {
        ret.target_as = &s->msix_notify_as;
        ret.iova = addr;
        ret.translated_addr = addr;
        ret.addr_mask = 0xfff;
        ret.perm = IOMMU_RW;
        return ret;
    }

    if (addr < pbdev->pba || addr > pbdev->pal) {
        return ret;
    }
@@ -476,7 +462,7 @@ static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
                                unsigned int size)
{
    S390PCIBusDevice *pbdev;
    S390PCIBusDevice *pbdev = opaque;
    uint32_t io_int_word;
    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
    uint32_t vec = data & ZPCI_MSI_VEC_MASK;
@@ -486,7 +472,6 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,

    DPRINTF("write_msix data 0x%" PRIx64 " idx %d vec 0x%x\n", data, idx, vec);

    pbdev = s390_pci_find_dev_by_idx(idx);
    if (!pbdev) {
        e |= (vec << ERR_EVENT_MVN_OFFSET);
        s390_pci_generate_error_event(ERR_EVENT_NOMSI, idx, 0, addr, e);
@@ -548,10 +533,6 @@ static void s390_pcihost_init_as(S390pciState *s)

        s->iommu[i] = iommu;
    }

    memory_region_init_io(&s->msix_notify_mr, OBJECT(s),
                          &s390_msi_ctrl_ops, s, "msix-s390", UINT64_MAX);
    address_space_init(&s->msix_notify_as, &s->msix_notify_mr, "msix-pci");
}

static int s390_pcihost_init(SysBusDevice *dev)
@@ -581,7 +562,7 @@ static int s390_pcihost_init(SysBusDevice *dev)
    return 0;
}

static int s390_pcihost_setup_msix(S390PCIBusDevice *pbdev)
static int s390_pci_setup_msix(S390PCIBusDevice *pbdev)
{
    uint8_t pos;
    uint16_t ctrl;
@@ -609,6 +590,26 @@ static int s390_pcihost_setup_msix(S390PCIBusDevice *pbdev)
    return 0;
}

static void s390_pci_msix_init(S390PCIBusDevice *pbdev)
{
    char *name;

    name = g_strdup_printf("msix-s390-%04x", pbdev->uid);

    memory_region_init_io(&pbdev->msix_notify_mr, OBJECT(pbdev),
                          &s390_msi_ctrl_ops, pbdev, name, PAGE_SIZE);
    memory_region_add_subregion(&pbdev->iommu->mr, ZPCI_MSI_ADDR,
                                &pbdev->msix_notify_mr);

    g_free(name);
}

static void s390_pci_msix_free(S390PCIBusDevice *pbdev)
{
    memory_region_del_subregion(&pbdev->iommu->mr, &pbdev->msix_notify_mr);
    object_unparent(OBJECT(&pbdev->msix_notify_mr));
}

static S390PCIBusDevice *s390_pci_device_new(const char *target)
{
    DeviceState *dev = NULL;
@@ -662,7 +663,9 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
        pbdev->pdev = pdev;
        pbdev->iommu = s->iommu[PCI_SLOT(pdev->devfn)];
        pbdev->state = ZPCI_FS_STANDBY;
        s390_pcihost_setup_msix(pbdev);

        s390_pci_msix_init(pbdev);
        s390_pci_setup_msix(pbdev);

        if (dev->hotplugged) {
            s390_pci_generate_plug_event(HP_EVENT_RESERVED_TO_STANDBY,
@@ -749,6 +752,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
                                 pbdev->fh, pbdev->fid);
    object_unparent(OBJECT(pci_dev));
    s390_pci_msix_free(pbdev);
    pbdev->pdev = NULL;
    pbdev->state = ZPCI_FS_RESERVED;
out:
+2 −2
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
#define ZPCI_EDMA_ADDR 0x1ffffffffffffffULL

#define PAGE_SHIFT      12
#define PAGE_SIZE       (1 << PAGE_SHIFT)
#define PAGE_MASK       (~(PAGE_SIZE-1))
#define PAGE_DEFAULT_ACC        0
#define PAGE_DEFAULT_KEY        (PAGE_DEFAULT_ACC << 4)
@@ -283,6 +284,7 @@ typedef struct S390PCIBusDevice {
    AdapterRoutes routes;
    S390PCIIOMMU *iommu;
    MemoryRegion iommu_mr;
    MemoryRegion msix_notify_mr;
    IndAddr *summary_ind;
    IndAddr *indicator;
    QEMUTimer *release_timer;
@@ -297,8 +299,6 @@ typedef struct S390pciState {
    S390PCIBus *bus;
    S390PCIBusDevice *pbdev[PCI_SLOT_MAX];
    S390PCIIOMMU *iommu[PCI_SLOT_MAX];
    AddressSpace msix_notify_as;
    MemoryRegion msix_notify_mr;
    QTAILQ_HEAD(, SeiContainer) pending_sei;
} S390pciState;

+4 −2
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
    S390PCIBusDevice *pbdev;
    uint64_t offset;
    uint64_t data;
    MemoryRegion *mr;
    uint8_t len;
    uint32_t fh;
    uint8_t pcias;
@@ -363,7 +364,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
            program_interrupt(env, PGM_OPERAND, 4);
            return 0;
        }
        MemoryRegion *mr = pbdev->pdev->io_regions[pcias].memory;
        mr = pbdev->pdev->io_regions[pcias].memory;
        memory_region_dispatch_read(mr, offset, &data, len,
                                    MEMTXATTRS_UNSPECIFIED);
    } else if (pcias == 15) {
@@ -442,6 +443,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
    CPUS390XState *env = &cpu->env;
    uint64_t offset, data;
    S390PCIBusDevice *pbdev;
    MemoryRegion *mr;
    uint8_t len;
    uint32_t fh;
    uint8_t pcias;
@@ -491,7 +493,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
            program_interrupt(env, PGM_OPERAND, 4);
            return 0;
        }
        MemoryRegion *mr;

        if (trap_msix(pbdev, offset, pcias)) {
            offset = offset - pbdev->msix.table_offset;
            mr = &pbdev->pdev->msix_table_mmio;
−48 B (25.8 KiB)

File changed.

No diff preview for this file type.

Loading