summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/ppc/ppc.c2
-rw-r--r--hw/ppc/spapr.c65
-rw-r--r--hw/ppc/spapr_irq.c50
3 files changed, 71 insertions, 46 deletions
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 49d57469fb..ad20584f26 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1101,7 +1101,7 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
     tb_env = g_malloc0(sizeof(ppc_tb_t));
     env->tb_env = tb_env;
     tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
-    if (env->insns_flags & PPC_SEGMENT_64B) {
+    if (is_book3s_arch2x(env)) {
         /* All Book3S 64bit CPUs implement level based DEC logic */
         tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL;
     }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6c16d6cfaf..b52b82d298 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1252,38 +1252,8 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
     _FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by qemu)"));
     _FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries"));
 
-    /*
-     * Add info to guest to indentify which host is it being run on
-     * and what is the uuid of the guest
-     */
-    if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) {
-        if (g_str_equal(spapr->host_model, "passthrough")) {
-            /* -M host-model=passthrough */
-            if (kvmppc_get_host_model(&buf)) {
-                _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
-                g_free(buf);
-            }
-        } else {
-            /* -M host-model=<user-string> */
-            _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
-        }
-    }
-
-    if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) {
-        if (g_str_equal(spapr->host_serial, "passthrough")) {
-            /* -M host-serial=passthrough */
-            if (kvmppc_get_host_serial(&buf)) {
-                _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
-                g_free(buf);
-            }
-        } else {
-            /* -M host-serial=<user-string> */
-            _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
-        }
-    }
-
+    /* Guest UUID & Name*/
     buf = qemu_uuid_unparse_strdup(&qemu_uuid);
-
     _FDT(fdt_setprop_string(fdt, 0, "vm,uuid", buf));
     if (qemu_uuid_set) {
         _FDT(fdt_setprop_string(fdt, 0, "system-id", buf));
@@ -1295,6 +1265,21 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
                                 qemu_get_vm_name()));
     }
 
+    /* Host Model & Serial Number */
+    if (spapr->host_model) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
+    } else if (smc->broken_host_serial_model && kvmppc_get_host_model(&buf)) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
+        g_free(buf);
+    }
+
+    if (spapr->host_serial) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
+    } else if (smc->broken_host_serial_model && kvmppc_get_host_serial(&buf)) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
+        g_free(buf);
+    }
+
     _FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
     _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
@@ -2795,13 +2780,7 @@ static void spapr_machine_init(MachineState *machine)
 
     /* advertise XIVE on POWER9 machines */
     if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
-        if (ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
-                                  0, spapr->max_compat_pvr)) {
-            spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
-        } else if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) {
-            error_report("XIVE-only machines require a POWER9 CPU");
-            exit(1);
-        }
+        spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
     }
 
     /* init CPUs */
@@ -3352,12 +3331,12 @@ static void spapr_instance_init(Object *obj)
         spapr_get_host_model, spapr_set_host_model,
         &error_abort);
     object_property_set_description(obj, "host-model",
-        "Set host's model-id to use - none|passthrough|string", &error_abort);
+        "Host model to advertise in guest device tree", &error_abort);
     object_property_add_str(obj, "host-serial",
         spapr_get_host_serial, spapr_set_host_serial,
         &error_abort);
     object_property_set_description(obj, "host-serial",
-        "Set host's system-id to use - none|passthrough|string", &error_abort);
+        "Host serial number to advertise in guest device tree", &error_abort);
 }
 
 static void spapr_machine_finalizefn(Object *obj)
@@ -4381,18 +4360,14 @@ DEFINE_SPAPR_MACHINE(4_0, "4.0", true);
 static void spapr_machine_3_1_class_options(MachineClass *mc)
 {
     SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-    static GlobalProperty compat[] = {
-        { TYPE_SPAPR_MACHINE, "host-model", "passthrough" },
-        { TYPE_SPAPR_MACHINE, "host-serial", "passthrough" },
-    };
 
     spapr_machine_4_0_class_options(mc);
     compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
-    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
 
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
     smc->update_dt_enabled = false;
     smc->dr_phb_enabled = false;
+    smc->broken_host_serial_model = true;
     smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
     smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
     smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 253e4de7fd..0a84e4cf63 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -16,6 +16,7 @@
 #include "hw/ppc/spapr_xive.h"
 #include "hw/ppc/xics.h"
 #include "hw/ppc/xics_spapr.h"
+#include "cpu-models.h"
 #include "sysemu/kvm.h"
 
 #include "trace.h"
@@ -582,12 +583,55 @@ SpaprIrq spapr_irq_dual = {
     .get_nodename = spapr_irq_get_nodename_dual,
 };
 
+
+static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+{
+    MachineState *machine = MACHINE(spapr);
+
+    /*
+     * Sanity checks on non-P9 machines. On these, XIVE is not
+     * advertised, see spapr_dt_ov5_platform_support()
+     */
+    if (!ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
+                               0, spapr->max_compat_pvr)) {
+        /*
+         * If the 'dual' interrupt mode is selected, force XICS as CAS
+         * negotiation is useless.
+         */
+        if (spapr->irq == &spapr_irq_dual) {
+            spapr->irq = &spapr_irq_xics;
+            return;
+        }
+
+        /*
+         * Non-P9 machines using only XIVE is a bogus setup. We have two
+         * scenarios to take into account because of the compat mode:
+         *
+         * 1. POWER7/8 machines should fail to init later on when creating
+         *    the XIVE interrupt presenters because a POWER9 exception
+         *    model is required.
+
+         * 2. POWER9 machines using the POWER8 compat mode won't fail and
+         *    will let the OS boot with a partial XIVE setup : DT
+         *    properties but no hcalls.
+         *
+         * To cover both and not confuse the OS, add an early failure in
+         * QEMU.
+         */
+        if (spapr->irq == &spapr_irq_xive) {
+            error_setg(errp, "XIVE-only machines require a POWER9 CPU");
+            return;
+        }
+    }
+}
+
 /*
  * sPAPR IRQ frontend routines for devices
  */
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
+    Error *local_err = NULL;
 
     if (machine_kernel_irqchip_split(machine)) {
         error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -600,6 +644,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         return;
     }
 
+    spapr_irq_check(spapr, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     /* Initialize the MSI IRQ allocator. */
     if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);