Commit 58560ad2 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191024' into staging



ppc patch queue 2019-10-24

Last pull request before soft freeze.
  * Lots of fixes and cleanups for spapr interrupt controllers
  * More SLOF updates to fix problems with full FDT rendering at CAS
    time (alas, more yet are to come)
  * A few other assorted changes

This isn't quite as well tested as I usually try to do before a pull
request.  But I've been sick and running into some other difficulties,
and wanted to get this sent out before heading towards KVM forum.

# gpg: Signature made Thu 24 Oct 2019 09:14:31 BST
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-4.2-20191024: (28 commits)
  spapr/xive: Set the OS CAM line at reset
  ppc/pnv: Fix naming of routines realizing the CPUs
  ppc: Reset the interrupt presenter from the CPU reset handler
  ppc/pnv: Add a PnvChip pointer to PnvCore
  ppc/pnv: Introduce a PnvCore reset handler
  spapr_cpu_core: Implement DeviceClass::reset
  spapr: move CPU reset after presenter creation
  spapr: Don't request to unplug the same core twice
  pseries: Update SLOF firmware image
  spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  spapr: Remove SpaprIrq::nr_msis
  spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  spapr: Remove SpaprIrq::init_kvm hook
  spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
  spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
  spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
  spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  spapr: Formalize notion of active interrupt controller
  spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 81c1f71e 97c00c54
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
    PnvXive *xive = PNV_XIVE(xrtr);

    if (pnv_xive_get_ic(blk) != xive) {
        xive_error(xive, "VST: EAS %x is remote !?", XIVE_SRCNO(blk, idx));
        xive_error(xive, "VST: EAS %x is remote !?", XIVE_EAS(blk, idx));
        return -1;
    }

@@ -431,7 +431,7 @@ static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno)
    PnvXive *xive = PNV_XIVE(xn);
    uint8_t blk = xive->chip->chip_id;

    xive_router_notify(xn, XIVE_SRCNO(blk, srcno));
    xive_router_notify(xn, XIVE_EAS(blk, srcno));
}

/*
@@ -1225,12 +1225,24 @@ static const MemoryRegionOps pnv_xive_ic_reg_ops = {

static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
{
    uint8_t blk;
    uint32_t idx;

    if (val & XIVE_TRIGGER_END) {
        xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64,
                   addr, val);
        return;
    }

    /*
     * Forward the source event notification directly to the Router.
     * The source interrupt number should already be correctly encoded
     * with the chip block id by the sending device (PHB, PSI).
     */
    xive_router_notify(XIVE_NOTIFIER(xive), val);
    blk = XIVE_EAS_BLOCK(val);
    idx = XIVE_EAS_INDEX(val);

    xive_router_notify(XIVE_NOTIFIER(xive), XIVE_EAS(blk, idx));
}

static void pnv_xive_ic_notify_write(void *opaque, hwaddr addr, uint64_t val,
@@ -1566,7 +1578,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
{
    XiveRouter *xrtr = XIVE_ROUTER(xive);
    uint8_t blk = xive->chip->chip_id;
    uint32_t srcno0 = XIVE_SRCNO(blk, 0);
    uint32_t srcno0 = XIVE_EAS(blk, 0);
    uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
    uint32_t nr_ends = pnv_xive_nr_ends(xive);
    XiveEAS eas;
+210 −114
Original line number Diff line number Diff line
@@ -205,23 +205,6 @@ void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
    memory_region_set_enabled(&xive->end_source.esb_mmio, false);
}

/*
 * When a Virtual Processor is scheduled to run on a HW thread, the
 * hypervisor pushes its identifier in the OS CAM line. Emulate the
 * same behavior under QEMU.
 */
void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
{
    uint8_t  nvt_blk;
    uint32_t nvt_idx;
    uint32_t nvt_cam;

    spapr_xive_cpu_to_nvt(POWERPC_CPU(tctx->cs), &nvt_blk, &nvt_idx);

    nvt_cam = cpu_to_be32(TM_QW1W2_VO | xive_nvt_cam_line(nvt_blk, nvt_idx));
    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &nvt_cam, 4);
}

static void spapr_xive_end_reset(XiveEND *end)
{
    memset(end, 0, sizeof(*end));
@@ -462,10 +445,10 @@ static int vmstate_spapr_xive_pre_save(void *opaque)
 * Called by the sPAPR IRQ backend 'post_load' method at the machine
 * level.
 */
int spapr_xive_post_load(SpaprXive *xive, int version_id)
static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id)
{
    if (kvm_irqchip_in_kernel()) {
        return kvmppc_xive_post_load(xive, version_id);
        return kvmppc_xive_post_load(SPAPR_XIVE(intc), version_id);
    }

    return 0;
@@ -487,6 +470,42 @@ static const VMStateDescription vmstate_spapr_xive = {
    },
};

static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
                                bool lsi, Error **errp)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    XiveSource *xsrc = &xive->source;

    assert(lisn < xive->nr_irqs);

    if (xive_eas_is_valid(&xive->eat[lisn])) {
        error_setg(errp, "IRQ %d is not free", lisn);
        return -EBUSY;
    }

    /*
     * Set default values when allocating an IRQ number
     */
    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
    if (lsi) {
        xive_source_irq_set_lsi(xsrc, lisn);
    }

    if (kvm_irqchip_in_kernel()) {
        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
    }

    return 0;
}

static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    assert(lisn < xive->nr_irqs);

    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
}

static Property spapr_xive_properties[] = {
    DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
    DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
@@ -495,10 +514,167 @@ static Property spapr_xive_properties[] = {
    DEFINE_PROP_END_OF_LIST(),
};

static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
                                      PowerPCCPU *cpu, Error **errp)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    Object *obj;
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
    if (!obj) {
        return -1;
    }

    spapr_cpu->tctx = XIVE_TCTX(obj);
    return 0;
}

static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t os_cam)
{
    uint32_t qw1w2 = cpu_to_be32(TM_QW1W2_VO | os_cam);
    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
}

static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
                                     PowerPCCPU *cpu)
{
    XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
    uint8_t  nvt_blk;
    uint32_t nvt_idx;

    xive_tctx_reset(tctx);

    /*
     * When a Virtual Processor is scheduled to run on a HW thread,
     * the hypervisor pushes its identifier in the OS CAM line.
     * Emulate the same behavior under QEMU.
     */
    spapr_xive_cpu_to_nvt(cpu, &nvt_blk, &nvt_idx);

    xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
}

static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
{
    SpaprXive *xive = SPAPR_XIVE(intc);

    if (kvm_irqchip_in_kernel()) {
        kvmppc_xive_source_set_irq(&xive->source, irq, val);
    } else {
        xive_source_set_irq(&xive->source, irq, val);
    }
}

static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    CPUState *cs;

    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);

        xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
    }

    spapr_xive_pic_print_info(xive, mon);
}

static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
                          void *fdt, uint32_t phandle)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    int node;
    uint64_t timas[2 * 2];
    /* Interrupt number ranges for the IPIs */
    uint32_t lisn_ranges[] = {
        cpu_to_be32(0),
        cpu_to_be32(nr_servers),
    };
    /*
     * EQ size - the sizes of pages supported by the system 4K, 64K,
     * 2M, 16M. We only advertise 64K for the moment.
     */
    uint32_t eq_sizes[] = {
        cpu_to_be32(16), /* 64K */
    };
    /*
     * The following array is in sync with the reserved priorities
     * defined by the 'spapr_xive_priority_is_reserved' routine.
     */
    uint32_t plat_res_int_priorities[] = {
        cpu_to_be32(7),    /* start */
        cpu_to_be32(0xf8), /* count */
    };

    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
    timas[0] = cpu_to_be64(xive->tm_base +
                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
    timas[2] = cpu_to_be64(xive->tm_base +
                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
    timas[3] = cpu_to_be64(1ull << TM_SHIFT);

    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));

    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));

    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
                     sizeof(eq_sizes)));
    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
                     sizeof(lisn_ranges)));

    /* For Linux to link the LSIs to the interrupt controller. */
    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));

    /* For SLOF */
    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));

    /*
     * The "ibm,plat-res-int-priorities" property defines the priority
     * ranges reserved by the hypervisor
     */
    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
}

static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
{
    SpaprXive *xive = SPAPR_XIVE(intc);

    if (kvm_enabled()) {
        int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp);
        if (rc < 0) {
            return rc;
        }
    }

    /* Activate the XIVE MMIOs */
    spapr_xive_mmio_set_enabled(xive, true);

    return 0;
}

static void spapr_xive_deactivate(SpaprInterruptController *intc)
{
    SpaprXive *xive = SPAPR_XIVE(intc);

    spapr_xive_mmio_set_enabled(xive, false);

    if (kvm_irqchip_in_kernel()) {
        kvmppc_xive_disconnect(intc);
    }
}

static void spapr_xive_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);

    dc->desc    = "sPAPR XIVE Interrupt Controller";
    dc->props   = spapr_xive_properties;
@@ -511,6 +687,17 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
    xrc->get_nvt = spapr_xive_get_nvt;
    xrc->write_nvt = spapr_xive_write_nvt;
    xrc->get_tctx = spapr_xive_get_tctx;

    sicc->activate = spapr_xive_activate;
    sicc->deactivate = spapr_xive_deactivate;
    sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
    sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
    sicc->claim_irq = spapr_xive_claim_irq;
    sicc->free_irq = spapr_xive_free_irq;
    sicc->set_irq = spapr_xive_set_irq;
    sicc->print_info = spapr_xive_print_info;
    sicc->dt = spapr_xive_dt;
    sicc->post_load = spapr_xive_post_load;
}

static const TypeInfo spapr_xive_info = {
@@ -519,6 +706,10 @@ static const TypeInfo spapr_xive_info = {
    .instance_init = spapr_xive_instance_init,
    .instance_size = sizeof(SpaprXive),
    .class_init = spapr_xive_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_SPAPR_INTC },
        { }
    },
};

static void spapr_xive_register_types(void)
@@ -528,39 +719,6 @@ static void spapr_xive_register_types(void)

type_init(spapr_xive_register_types)

int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
{
    XiveSource *xsrc = &xive->source;

    assert(lisn < xive->nr_irqs);

    if (xive_eas_is_valid(&xive->eat[lisn])) {
        error_setg(errp, "IRQ %d is not free", lisn);
        return -EBUSY;
    }

    /*
     * Set default values when allocating an IRQ number
     */
    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
    if (lsi) {
        xive_source_irq_set_lsi(xsrc, lisn);
    }

    if (kvm_irqchip_in_kernel()) {
        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
    }

    return 0;
}

void spapr_xive_irq_free(SpaprXive *xive, int lisn)
{
    assert(lisn < xive->nr_irqs);

    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
}

/*
 * XIVE hcalls
 *
@@ -1540,65 +1698,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr)
    spapr_register_hypercall(H_INT_SYNC, h_int_sync);
    spapr_register_hypercall(H_INT_RESET, h_int_reset);
}

void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
                   uint32_t phandle)
{
    SpaprXive *xive = spapr->xive;
    int node;
    uint64_t timas[2 * 2];
    /* Interrupt number ranges for the IPIs */
    uint32_t lisn_ranges[] = {
        cpu_to_be32(0),
        cpu_to_be32(nr_servers),
    };
    /*
     * EQ size - the sizes of pages supported by the system 4K, 64K,
     * 2M, 16M. We only advertise 64K for the moment.
     */
    uint32_t eq_sizes[] = {
        cpu_to_be32(16), /* 64K */
    };
    /*
     * The following array is in sync with the reserved priorities
     * defined by the 'spapr_xive_priority_is_reserved' routine.
     */
    uint32_t plat_res_int_priorities[] = {
        cpu_to_be32(7),    /* start */
        cpu_to_be32(0xf8), /* count */
    };

    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
    timas[0] = cpu_to_be64(xive->tm_base +
                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
    timas[2] = cpu_to_be64(xive->tm_base +
                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
    timas[3] = cpu_to_be64(1ull << TM_SHIFT);

    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));

    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));

    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
                     sizeof(eq_sizes)));
    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
                     sizeof(lisn_ranges)));

    /* For Linux to link the LSIs to the interrupt controller. */
    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));

    /* For SLOF */
    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));

    /*
     * The "ibm,plat-res-int-priorities" property defines the priority
     * ranges reserved by the hypervisor
     */
    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
}
+10 −12
Original line number Diff line number Diff line
@@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
 * All the XIVE memory regions are now backed by mappings from the KVM
 * XIVE device.
 */
void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    XiveSource *xsrc = &xive->source;
    Error *local_err = NULL;
    size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
@@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
     * rebooting under the XIVE-only interrupt mode.
     */
    if (xive->fd != -1) {
        return;
        return 0;
    }

    if (!kvmppc_has_cap_xive()) {
        error_setg(errp, "IRQ_XIVE capability must be present for KVM");
        return;
        return -1;
    }

    /* First, create the KVM XIVE device */
    xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false);
    if (xive->fd < 0) {
        error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device");
        return;
        return -1;
    }

    /*
@@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
    kvm_kernel_irqchip = true;
    kvm_msi_via_irqfd_allowed = true;
    kvm_gsi_direct_mapping = true;
    return;
    return 0;

fail:
    error_propagate(errp, local_err);
    kvmppc_xive_disconnect(xive, NULL);
    kvmppc_xive_disconnect(intc);
    return -1;
}

void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
void kvmppc_xive_disconnect(SpaprInterruptController *intc)
{
    SpaprXive *xive = SPAPR_XIVE(intc);
    XiveSource *xsrc;
    size_t esb_len;

@@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
        return;
    }

    if (!kvmppc_has_cap_xive()) {
        error_setg(errp, "IRQ_XIVE capability must be present for KVM");
        return;
    }

    /* Clear the KVM mapping */
    xsrc = &xive->source;
    esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
+12 −6
Original line number Diff line number Diff line
@@ -274,10 +274,8 @@ static const VMStateDescription vmstate_icp_server = {
    },
};

static void icp_reset_handler(void *dev)
void icp_reset(ICPState *icp)
{
    ICPState *icp = ICP(dev);

    icp->xirr = 0;
    icp->pending_priority = 0xff;
    icp->mfrr = 0xff;
@@ -288,7 +286,7 @@ static void icp_reset_handler(void *dev)
    if (kvm_irqchip_in_kernel()) {
        Error *local_err = NULL;

        icp_set_kvm_state(ICP(dev), &local_err);
        icp_set_kvm_state(icp, &local_err);
        if (local_err) {
            error_report_err(local_err);
        }
@@ -351,7 +349,6 @@ static void icp_realize(DeviceState *dev, Error **errp)
        }
    }

    qemu_register_reset(icp_reset_handler, dev);
    vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
}

@@ -360,7 +357,6 @@ static void icp_unrealize(DeviceState *dev, Error **errp)
    ICPState *icp = ICP(dev);

    vmstate_unregister(NULL, &vmstate_icp_server, icp);
    qemu_unregister_reset(icp_reset_handler, dev);
}

static void icp_class_init(ObjectClass *klass, void *data)
@@ -369,6 +365,11 @@ static void icp_class_init(ObjectClass *klass, void *data)

    dc->realize = icp_realize;
    dc->unrealize = icp_unrealize;
    /*
     * Reason: part of XICS interrupt controller, needs to be wired up
     * by icp_create().
     */
    dc->user_creatable = false;
}

static const TypeInfo icp_info = {
@@ -689,6 +690,11 @@ static void ics_class_init(ObjectClass *klass, void *data)
    dc->props = ics_properties;
    dc->reset = ics_reset;
    dc->vmsd = &vmstate_ics;
    /*
     * Reason: part of XICS interrupt controller, needs to be wired up,
     * e.g. by spapr_irq_init().
     */
    dc->user_creatable = false;
}

static const TypeInfo ics_info = {
+5 −4
Original line number Diff line number Diff line
@@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
    }
}

int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
{
    ICSState *ics = ICS_SPAPR(intc);
    int rc;
    CPUState *cs;
    Error *local_err = NULL;
@@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
    }

    /* Update the KVM sources */
    ics_set_kvm_state(spapr->ics, &local_err);
    ics_set_kvm_state(ics, &local_err);
    if (local_err) {
        goto fail;
    }
@@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)

fail:
    error_propagate(errp, local_err);
    xics_kvm_disconnect(spapr, NULL);
    xics_kvm_disconnect(intc);
    return -1;
}

void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
void xics_kvm_disconnect(SpaprInterruptController *intc)
{
    /*
     * Only on P9 using the XICS-on XIVE KVM device:
Loading