Commit 9746211b authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.10-20170609' into staging



ppc patch queue 2017-06-09

This batch contains more patches to rework the pseries machine hotplug
infrastructure, plus an assorted batch of bugfixes.

It contains a start on fixes to restore migration from older machine
types on older versions which was broken by some xics changes.  There
are still a few missing pieces here, though.

# gpg: Signature made Fri 09 Jun 2017 06:26:03 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.10-20170609:
  Revert "spapr: fix memory hot-unplugging"
  xics: drop ICPStateClass::cpu_setup() handler
  xics: setup cpu at realize time
  xics: pass appropriate types to realize() handlers.
  xics: introduce macros for ICP/ICS link properties
  hw/cpu: core.c can be compiled as common object
  hw/ppc/spapr: Adjust firmware name for PCI bridges
  xics: add reset() handler to ICPStateClass
  pnv_core: drop reference on ICPState object during CPU realization
  spapr: Rework DRC name handling
  spapr: Fold spapr_phb_{add,remove}_pci_device() into their only callers
  spapr: Change DRC attach & detach methods to functions
  spapr: Clean up handling of DR-indicator
  spapr: Clean up RTAS set-indicator
  spapr: Don't misuse DR-indicator in spapr_recover_pending_dimm_state()
  spapr: Clean up DR entity sense handling
  pseries: Correct panic behaviour for pseries machine type
  spapr: fix memory leak in spapr_memory_pre_plug()
  target/ppc: fix memory leak in kvmppc_is_mem_backend_page_size_ok()
  target/ppc: pass const string to kvmppc_is_mem_backend_page_size_ok()

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 8e3cf49c 59308093
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
obj-$(CONFIG_REALVIEW) += realview_mpcore.o
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
obj-y += core.o
common-obj-y += core.o
+41 −54
Original line number Diff line number Diff line
@@ -38,50 +38,6 @@
#include "monitor/monitor.h"
#include "hw/intc/intc.h"

void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
{
    CPUState *cs = CPU(cpu);
    ICPState *icp = ICP(cpu->intc);

    assert(icp);
    assert(cs == icp->cs);

    icp->output = NULL;
    icp->cs = NULL;
}

void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp)
{
    CPUState *cs = CPU(cpu);
    CPUPPCState *env = &cpu->env;
    ICPStateClass *icpc;

    assert(icp);

    cpu->intc = OBJECT(icp);
    icp->cs = cs;

    icpc = ICP_GET_CLASS(icp);
    if (icpc->cpu_setup) {
        icpc->cpu_setup(icp, cpu);
    }

    switch (PPC_INPUT(env)) {
    case PPC_FLAGS_INPUT_POWER7:
        icp->output = env->irq_inputs[POWER7_INPUT_INT];
        break;

    case PPC_FLAGS_INPUT_970:
        icp->output = env->irq_inputs[PPC970_INPUT_INT];
        break;

    default:
        error_report("XICS interrupt controller does not support this CPU "
                     "bus model");
        abort();
    }
}

void icp_pic_print_info(ICPState *icp, Monitor *mon)
{
    int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
@@ -325,6 +281,7 @@ static const VMStateDescription vmstate_icp_server = {
static void icp_reset(void *dev)
{
    ICPState *icp = ICP(dev);
    ICPStateClass *icpc = ICP_GET_CLASS(icp);

    icp->xirr = 0;
    icp->pending_priority = 0xff;
@@ -332,26 +289,58 @@ static void icp_reset(void *dev)

    /* Make all outputs are deasserted */
    qemu_set_irq(icp->output, 0);

    if (icpc->reset) {
        icpc->reset(icp);
    }
}

static void icp_realize(DeviceState *dev, Error **errp)
{
    ICPState *icp = ICP(dev);
    ICPStateClass *icpc = ICP_GET_CLASS(dev);
    PowerPCCPU *cpu;
    CPUPPCState *env;
    Object *obj;
    Error *err = NULL;

    obj = object_property_get_link(OBJECT(dev), "xics", &err);
    obj = object_property_get_link(OBJECT(dev), ICP_PROP_XICS, &err);
    if (!obj) {
        error_setg(errp, "%s: required link 'xics' not found: %s",
        error_setg(errp, "%s: required link '" ICP_PROP_XICS "' not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    icp->xics = XICS_FABRIC(obj);

    obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
    if (!obj) {
        error_setg(errp, "%s: required link '" ICP_PROP_CPU "' not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    cpu = POWERPC_CPU(obj);
    cpu->intc = OBJECT(icp);
    icp->cs = CPU(obj);

    env = &cpu->env;
    switch (PPC_INPUT(env)) {
    case PPC_FLAGS_INPUT_POWER7:
        icp->output = env->irq_inputs[POWER7_INPUT_INT];
        break;

    case PPC_FLAGS_INPUT_970:
        icp->output = env->irq_inputs[PPC970_INPUT_INT];
        break;

    default:
        error_setg(errp, "XICS interrupt controller does not support this CPU bus model");
        return;
    }

    if (icpc->realize) {
        icpc->realize(dev, errp);
        icpc->realize(icp, errp);
    }

    qemu_register_reset(icp_reset, dev);
@@ -601,10 +590,8 @@ static void ics_simple_initfn(Object *obj)
    ics->offset = XICS_IRQ_BASE;
}

static void ics_simple_realize(DeviceState *dev, Error **errp)
static void ics_simple_realize(ICSState *ics, Error **errp)
{
    ICSState *ics = ICS_SIMPLE(dev);

    if (!ics->nr_irqs) {
        error_setg(errp, "Number of interrupts needs to be greater 0");
        return;
@@ -612,7 +599,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
    ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
    ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);

    qemu_register_reset(ics_simple_reset, dev);
    qemu_register_reset(ics_simple_reset, ics);
}

static Property ics_simple_properties[] = {
@@ -649,9 +636,9 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
    Object *obj;
    Error *err = NULL;

    obj = object_property_get_link(OBJECT(dev), "xics", &err);
    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);
    if (!obj) {
        error_setg(errp, "%s: required link 'xics' not found: %s",
        error_setg(errp, "%s: required link '" ICS_PROP_XICS "' not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }
@@ -659,7 +646,7 @@ static void ics_base_realize(DeviceState *dev, Error **errp)


    if (icsc->realize) {
        icsc->realize(dev, errp);
        icsc->realize(ics, errp);
    }
}

+10 −35
Original line number Diff line number Diff line
@@ -110,25 +110,14 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
    return 0;
}

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

    icp->xirr = 0;
    icp->pending_priority = 0xff;
    icp->mfrr = 0xff;

    /* Make all outputs as deasserted only if the CPU thread is in use */
    if (icp->output) {
        qemu_set_irq(icp->output, 0);
    }

    icp_set_kvm_state(icp, 1);
}

static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)
static void icp_kvm_realize(ICPState *icp, Error **errp)
{
    CPUState *cs = CPU(cpu);
    CPUState *cs = icp->cs;
    KVMEnabledICP *enabled_icp;
    unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
    int ret;
@@ -150,35 +139,23 @@ static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)

    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id);
    if (ret < 0) {
        error_report("Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
        error_setg(errp, "Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
                   strerror(errno));
        exit(1);
        return;
    }
    enabled_icp = g_malloc(sizeof(*enabled_icp));
    enabled_icp->vcpu_id = vcpu_id;
    QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node);
}

static void icp_kvm_realize(DeviceState *dev, Error **errp)
{
    qemu_register_reset(icp_kvm_reset, dev);
}

static void icp_kvm_unrealize(DeviceState *dev, Error **errp)
{
    qemu_unregister_reset(icp_kvm_reset, dev);
}

static void icp_kvm_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ICPStateClass *icpc = ICP_CLASS(klass);

    dc->realize = icp_kvm_realize;
    dc->unrealize = icp_kvm_unrealize;
    icpc->pre_save = icp_get_kvm_state;
    icpc->post_load = icp_set_kvm_state;
    icpc->cpu_setup = icp_kvm_cpu_setup;
    icpc->realize = icp_kvm_realize;
    icpc->reset = icp_kvm_reset;
}

static const TypeInfo icp_kvm_info = {
@@ -351,10 +328,8 @@ static void ics_kvm_reset(void *dev)
    ics_set_kvm_state(ics, 1);
}

static void ics_kvm_realize(DeviceState *dev, Error **errp)
static void ics_kvm_realize(ICSState *ics, Error **errp)
{
    ICSState *ics = ICS_SIMPLE(dev);

    if (!ics->nr_irqs) {
        error_setg(errp, "Number of interrupts needs to be greater 0");
        return;
@@ -362,7 +337,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
    ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
    ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);

    qemu_register_reset(ics_kvm_reset, dev);
    qemu_register_reset(ics_kvm_reset, ics);
}

static void ics_kvm_class_init(ObjectClass *klass, void *data)
+3 −3
Original line number Diff line number Diff line
@@ -159,11 +159,11 @@ static const MemoryRegionOps pnv_icp_ops = {
    },
};

static void pnv_icp_realize(DeviceState *dev, Error **errp)
static void pnv_icp_realize(ICPState *icp, Error **errp)
{
    PnvICPState *icp = PNV_ICP(dev);
    PnvICPState *pnv_icp = PNV_ICP(icp);

    memory_region_init_io(&icp->mmio, OBJECT(dev), &pnv_icp_ops,
    memory_region_init_io(&pnv_icp->mmio, OBJECT(icp), &pnv_icp_ops,
                          icp, "icp-thread", 0x1000);
}

+8 −8
Original line number Diff line number Diff line
@@ -118,18 +118,20 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    Object *obj;

    obj = object_new(TYPE_PNV_ICP);
    object_property_add_child(OBJECT(cpu), "icp", obj, NULL);
    object_property_add_const_link(obj, "xics", OBJECT(xi), &error_abort);
    object_property_set_bool(obj, true, "realized", &local_err);
    object_property_set_bool(child, true, "realized", &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    object_property_set_bool(child, true, "realized", &local_err);
    obj = object_new(TYPE_PNV_ICP);
    object_property_add_child(child, "icp", obj, NULL);
    object_unref(obj);
    object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
                                   &error_abort);
    object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort);
    object_property_set_bool(obj, true, "realized", &local_err);
    if (local_err) {
        object_unparent(obj);
        error_propagate(errp, local_err);
        return;
    }
@@ -140,8 +142,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
        error_propagate(errp, local_err);
        return;
    }

    xics_cpu_setup(xi, cpu, ICP(obj));
}

static void pnv_core_realize(DeviceState *dev, Error **errp)
Loading