summary refs log tree commit diff stats
path: root/hw/intc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-02-18 16:20:13 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-02-18 16:20:13 +0000
commit2e68b8620637a4ee8c79b5724144b726af1e261b (patch)
treee53cbfaf5cbdd0d0b0c326838634e92096540256 /hw/intc
parenta0430dd8abb8a2f31c5ee919daab2e3d76353c04 (diff)
parent73e14c6a9cdefb94c01ea488f04e7fba7ac0dc5b (diff)
downloadfocaccia-qemu-2e68b8620637a4ee8c79b5724144b726af1e261b.tar.gz
focaccia-qemu-2e68b8620637a4ee8c79b5724144b726af1e261b.zip
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190219' into staging
ppc patch queue 2019-02-19

Here's the next batch of ppc and spapr patches.  Higlights are:

 * A bunch of improvements to TCG handling of vector instructions from
   Richard Henderson and Marc Cave-Ayland

 * Cleanup to the XICS interrupt controller from Greg Kurz, removing
   the special KVM subclasses which were a bad idea

 * Some refinements to the XIVE interrupt controller from Cédric Le
   Goater

 * Fix from Fabiano Rosas for a really dumb buffer overflow in the
   device tree code for memory hotplug

 * Code for allowing access to SPRs from the gdb stub from Fabiano
   Rosas

 * Assorted minor fixes and cleanups

# gpg: Signature made Mon 18 Feb 2019 13:47:54 GMT
# 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.0-20190219: (43 commits)
  target/ppc: convert vmin* and vmax* to vector operations
  target/ppc: convert vadd*s and vsub*s to vector operations
  target/ppc: Split out VSCR_SAT to a vector field
  target/ppc: Add set_vscr_sat
  target/ppc: Use mtvscr/mfvscr for vmstate
  target/ppc: Add helper_mfvscr
  target/ppc: Remove vscr_nj and vscr_sat
  target/ppc: Use helper_mtvscr for reset and gdb
  target/ppc: Pass integer to helper_mtvscr
  target/ppc: convert xxsel to vector operations
  target/ppc: convert xxspltw to vector operations
  target/ppc: convert xxspltib to vector operations
  target/ppc: convert VSX logical operations to vector operations
  target/ppc: convert vsplt[bhw] to use vector operations
  target/ppc: convert vspltis[bhw] to use vector operations
  target/ppc: convert vaddu[b,h,w,d] and vsubu[b,h,w,d] over to use vector operations
  target/ppc: convert VMX logical instructions to use vector operations
  xics: Drop the KVM ICS class
  spapr/irq: Use the "simple" ICS class for KVM
  xics: Handle KVM interrupt presentation from "simple" ICS code
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/spapr_xive.c7
-rw-r--r--hw/intc/xics.c76
-rw-r--r--hw/intc/xics_kvm.c120
3 files changed, 53 insertions, 150 deletions
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index a0f5ff9294..290a290e43 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -489,20 +489,19 @@ bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi)
     }
 
     xive->eat[lisn].w |= cpu_to_be64(EAS_VALID);
-    xive_source_irq_set(xsrc, lisn, lsi);
+    if (lsi) {
+        xive_source_irq_set_lsi(xsrc, lisn);
+    }
     return true;
 }
 
 bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn)
 {
-    XiveSource *xsrc = &xive->source;
-
     if (lisn >= xive->nr_irqs) {
         return false;
     }
 
     xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-    xive_source_irq_set(xsrc, lisn, false);
     return true;
 }
 
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 16e8ffa2aa..3009fa7472 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -37,18 +37,18 @@
 #include "qapi/visitor.h"
 #include "monitor/monitor.h"
 #include "hw/intc/intc.h"
+#include "sysemu/kvm.h"
 
 void icp_pic_print_info(ICPState *icp, Monitor *mon)
 {
-    ICPStateClass *icpc = ICP_GET_CLASS(icp);
     int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
 
     if (!icp->output) {
         return;
     }
 
-    if (icpc->synchronize_state) {
-        icpc->synchronize_state(icp);
+    if (kvm_irqchip_in_kernel()) {
+        icp_synchronize_state(icp);
     }
 
     monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
@@ -58,7 +58,6 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon)
 
 void ics_pic_print_info(ICSState *ics, Monitor *mon)
 {
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
     uint32_t i;
 
     monitor_printf(mon, "ICS %4x..%4x %p\n",
@@ -68,8 +67,8 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
         return;
     }
 
-    if (icsc->synchronize_state) {
-        icsc->synchronize_state(ics);
+    if (kvm_irqchip_in_kernel()) {
+        ics_synchronize_state(ics);
     }
 
     for (i = 0; i < ics->nr_irqs; i++) {
@@ -252,25 +251,23 @@ static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
     }
 }
 
-static int icp_dispatch_pre_save(void *opaque)
+static int icp_pre_save(void *opaque)
 {
     ICPState *icp = opaque;
-    ICPStateClass *info = ICP_GET_CLASS(icp);
 
-    if (info->pre_save) {
-        info->pre_save(icp);
+    if (kvm_irqchip_in_kernel()) {
+        icp_get_kvm_state(icp);
     }
 
     return 0;
 }
 
-static int icp_dispatch_post_load(void *opaque, int version_id)
+static int icp_post_load(void *opaque, int version_id)
 {
     ICPState *icp = opaque;
-    ICPStateClass *info = ICP_GET_CLASS(icp);
 
-    if (info->post_load) {
-        return info->post_load(icp, version_id);
+    if (kvm_irqchip_in_kernel()) {
+        return icp_set_kvm_state(icp);
     }
 
     return 0;
@@ -280,8 +277,8 @@ static const VMStateDescription vmstate_icp_server = {
     .name = "icp/server",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_save = icp_dispatch_pre_save,
-    .post_load = icp_dispatch_post_load,
+    .pre_save = icp_pre_save,
+    .post_load = icp_post_load,
     .fields = (VMStateField[]) {
         /* Sanity check */
         VMSTATE_UINT32(xirr, ICPState),
@@ -291,7 +288,7 @@ static const VMStateDescription vmstate_icp_server = {
     },
 };
 
-static void icp_reset(DeviceState *dev)
+static void icp_reset_handler(void *dev)
 {
     ICPState *icp = ICP(dev);
 
@@ -301,13 +298,10 @@ static void icp_reset(DeviceState *dev)
 
     /* Make all outputs are deasserted */
     qemu_set_irq(icp->output, 0);
-}
-
-static void icp_reset_handler(void *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    dc->reset(dev);
+    if (kvm_irqchip_in_kernel()) {
+        icp_set_kvm_state(ICP(dev));
+    }
 }
 
 static void icp_realize(DeviceState *dev, Error **errp)
@@ -354,6 +348,14 @@ static void icp_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    if (kvm_irqchip_in_kernel()) {
+        icp_kvm_realize(dev, &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+    }
+
     qemu_register_reset(icp_reset_handler, dev);
     vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
 }
@@ -372,7 +374,6 @@ static void icp_class_init(ObjectClass *klass, void *data)
 
     dc->realize = icp_realize;
     dc->unrealize = icp_unrealize;
-    dc->reset = icp_reset;
 }
 
 static const TypeInfo icp_info = {
@@ -465,6 +466,11 @@ void ics_simple_set_irq(void *opaque, int srcno, int val)
 {
     ICSState *ics = (ICSState *)opaque;
 
+    if (kvm_irqchip_in_kernel()) {
+        ics_kvm_set_irq(ics, srcno, val);
+        return;
+    }
+
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
         ics_simple_set_irq_lsi(ics, srcno, val);
     } else {
@@ -552,6 +558,10 @@ static void ics_simple_reset(DeviceState *dev)
     ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
 
     icsc->parent_reset(dev);
+
+    if (kvm_irqchip_in_kernel()) {
+        ics_set_kvm_state(ICS_BASE(dev));
+    }
 }
 
 static void ics_simple_reset_handler(void *dev)
@@ -645,25 +655,23 @@ static void ics_base_instance_init(Object *obj)
     ics->offset = XICS_IRQ_BASE;
 }
 
-static int ics_base_dispatch_pre_save(void *opaque)
+static int ics_base_pre_save(void *opaque)
 {
     ICSState *ics = opaque;
-    ICSStateClass *info = ICS_BASE_GET_CLASS(ics);
 
-    if (info->pre_save) {
-        info->pre_save(ics);
+    if (kvm_irqchip_in_kernel()) {
+        ics_get_kvm_state(ics);
     }
 
     return 0;
 }
 
-static int ics_base_dispatch_post_load(void *opaque, int version_id)
+static int ics_base_post_load(void *opaque, int version_id)
 {
     ICSState *ics = opaque;
-    ICSStateClass *info = ICS_BASE_GET_CLASS(ics);
 
-    if (info->post_load) {
-        return info->post_load(ics, version_id);
+    if (kvm_irqchip_in_kernel()) {
+        return ics_set_kvm_state(ics);
     }
 
     return 0;
@@ -687,8 +695,8 @@ static const VMStateDescription vmstate_ics_base = {
     .name = "ics",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_save = ics_base_dispatch_pre_save,
-    .post_load = ics_base_dispatch_post_load,
+    .pre_save = ics_base_pre_save,
+    .post_load = ics_base_post_load,
     .fields = (VMStateField[]) {
         /* Sanity check */
         VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index dff1330050..a00d0a7962 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -54,7 +54,7 @@ static QLIST_HEAD(, KVMEnabledICP)
 /*
  * ICP-KVM
  */
-static void icp_get_kvm_state(ICPState *icp)
+void icp_get_kvm_state(ICPState *icp)
 {
     uint64_t state;
     int ret;
@@ -83,14 +83,14 @@ static void do_icp_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
     icp_get_kvm_state(arg.host_ptr);
 }
 
-static void icp_synchronize_state(ICPState *icp)
+void icp_synchronize_state(ICPState *icp)
 {
     if (icp->cs) {
         run_on_cpu(icp->cs, do_icp_synchronize_state, RUN_ON_CPU_HOST_PTR(icp));
     }
 }
 
-static int icp_set_kvm_state(ICPState *icp, int version_id)
+int icp_set_kvm_state(ICPState *icp)
 {
     uint64_t state;
     int ret;
@@ -115,20 +115,9 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
     return 0;
 }
 
-static void icp_kvm_reset(DeviceState *dev)
-{
-    ICPStateClass *icpc = ICP_GET_CLASS(dev);
-
-    icpc->parent_reset(dev);
-
-    icp_set_kvm_state(ICP(dev), 1);
-}
-
-static void icp_kvm_realize(DeviceState *dev, Error **errp)
+void icp_kvm_realize(DeviceState *dev, Error **errp)
 {
     ICPState *icp = ICP(dev);
-    ICPStateClass *icpc = ICP_GET_CLASS(icp);
-    Error *local_err = NULL;
     CPUState *cs;
     KVMEnabledICP *enabled_icp;
     unsigned long vcpu_id;
@@ -138,12 +127,6 @@ static void icp_kvm_realize(DeviceState *dev, Error **errp)
         abort();
     }
 
-    icpc->parent_realize(dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
     cs = icp->cs;
     vcpu_id = kvm_arch_vcpu_id(cs);
 
@@ -169,33 +152,10 @@ static void icp_kvm_realize(DeviceState *dev, Error **errp)
     QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node);
 }
 
-static void icp_kvm_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    ICPStateClass *icpc = ICP_CLASS(klass);
-
-    device_class_set_parent_realize(dc, icp_kvm_realize,
-                                    &icpc->parent_realize);
-    device_class_set_parent_reset(dc, icp_kvm_reset,
-                                  &icpc->parent_reset);
-
-    icpc->pre_save = icp_get_kvm_state;
-    icpc->post_load = icp_set_kvm_state;
-    icpc->synchronize_state = icp_synchronize_state;
-}
-
-static const TypeInfo icp_kvm_info = {
-    .name = TYPE_KVM_ICP,
-    .parent = TYPE_ICP,
-    .instance_size = sizeof(ICPState),
-    .class_init = icp_kvm_class_init,
-    .class_size = sizeof(ICPStateClass),
-};
-
 /*
  * ICS-KVM
  */
-static void ics_get_kvm_state(ICSState *ics)
+void ics_get_kvm_state(ICSState *ics)
 {
     uint64_t state;
     int i;
@@ -248,12 +208,12 @@ static void ics_get_kvm_state(ICSState *ics)
     }
 }
 
-static void ics_synchronize_state(ICSState *ics)
+void ics_synchronize_state(ICSState *ics)
 {
     ics_get_kvm_state(ics);
 }
 
-static int ics_set_kvm_state(ICSState *ics, int version_id)
+int ics_set_kvm_state(ICSState *ics)
 {
     uint64_t state;
     int i;
@@ -299,9 +259,8 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
     return 0;
 }
 
-void ics_kvm_set_irq(void *opaque, int srcno, int val)
+void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
 {
-    ICSState *ics = opaque;
     struct kvm_irq_level args;
     int rc;
 
@@ -320,61 +279,6 @@ void ics_kvm_set_irq(void *opaque, int srcno, int val)
     }
 }
 
-static void ics_kvm_reset(DeviceState *dev)
-{
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
-
-    icsc->parent_reset(dev);
-
-    ics_set_kvm_state(ICS_KVM(dev), 1);
-}
-
-static void ics_kvm_reset_handler(void *dev)
-{
-    ics_kvm_reset(dev);
-}
-
-static void ics_kvm_realize(DeviceState *dev, Error **errp)
-{
-    ICSState *ics = ICS_KVM(dev);
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
-    Error *local_err = NULL;
-
-    icsc->parent_realize(dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    qemu_register_reset(ics_kvm_reset_handler, ics);
-}
-
-static void ics_kvm_class_init(ObjectClass *klass, void *data)
-{
-    ICSStateClass *icsc = ICS_BASE_CLASS(klass);
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    device_class_set_parent_realize(dc, ics_kvm_realize,
-                                    &icsc->parent_realize);
-    device_class_set_parent_reset(dc, ics_kvm_reset,
-                                  &icsc->parent_reset);
-
-    icsc->pre_save = ics_get_kvm_state;
-    icsc->post_load = ics_set_kvm_state;
-    icsc->synchronize_state = ics_synchronize_state;
-}
-
-static const TypeInfo ics_kvm_info = {
-    .name = TYPE_ICS_KVM,
-    .parent = TYPE_ICS_BASE,
-    .instance_size = sizeof(ICSState),
-    .class_init = ics_kvm_class_init,
-};
-
-/*
- * XICS-KVM
- */
-
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
@@ -444,11 +348,3 @@ fail:
     kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
     return -1;
 }
-
-static void xics_kvm_register_types(void)
-{
-    type_register_static(&ics_kvm_info);
-    type_register_static(&icp_kvm_info);
-}
-
-type_init(xics_kvm_register_types)