Blame SOURCES/kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch

4a2fec
From 8663586f2bc64d4761d4f621bc7aa781a4a450b2 Mon Sep 17 00:00:00 2001
4a2fec
From: Laurent Vivier <lvivier@redhat.com>
4a2fec
Date: Fri, 20 Oct 2017 14:02:07 +0200
4a2fec
Subject: [PATCH 1/9] qemu-kvm-rhev: only allows pseries-rhel7.5.0 machine type
4a2fec
 with POWER9 guest
4a2fec
4a2fec
RH-Author: Laurent Vivier <lvivier@redhat.com>
4a2fec
Message-id: <20171020140207.15190-1-lvivier@redhat.com>
4a2fec
Patchwork-id: 77416
4a2fec
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v3 3/4] qemu-kvm-rhev: only allows pseries-rhel7.5.0 machine type with POWER9 guest
4a2fec
Bugzilla: 1478469
4a2fec
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
4a2fec
RH-Acked-by: Thomas Huth <thuth@redhat.com>
4a2fec
RH-Acked-by: David Gibson <dgibson@redhat.com>
4a2fec
4a2fec
We disable all machine types except pseries-rhel7.5.0 for POWER9
4a2fec
guest.
4a2fec
4a2fec
qemu-kvm-rhev does't not support POWER9 with former machine types
4a2fec
so disable them dynamically. We allow all machine types on POWER9
4a2fec
host but with guest in POWER8 CPU mode
4a2fec
(for instance "-M pseries-rhel7.4.0,max-cpu-compat=power8")
4a2fec
4a2fec
"-M help" display all the machine types, but if the guest is started
4a2fec
with "-cpu POWER9" and with a machine type which is not
4a2fec
"pseries-rhel7.5.0" an error message is displayed and the guest is
4a2fec
stopped.
4a2fec
4a2fec
We use the ppc_check_compat() to compare current CPU version with ISA
4a2fec
level of POWER9 (CPU_POWERPC_LOGICAL_3_00), but as POWER9 DD1 has some
4a2fec
bugs, POWER9 DD1 does not advertise PCR_COMPAT_3_00 (see
4a2fec
kvmppc_host_cpu_class_init()), and thus this allows to run all the machine
4a2fec
types with POWER9 DD1.
4a2fec
4a2fec
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
---
4a2fec
 hw/ppc/spapr.c          |  2 ++
4a2fec
 hw/ppc/spapr_cpu_core.c | 13 +++++++++++++
4a2fec
 include/hw/ppc/spapr.h  |  1 +
4a2fec
 target/ppc/compat.c     | 11 +++++++++++
4a2fec
 target/ppc/cpu.h        |  1 +
4a2fec
 5 files changed, 28 insertions(+)
4a2fec
4a2fec
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
4a2fec
index 5fe7769..42028ef 100644
4a2fec
--- a/hw/ppc/spapr.c
4a2fec
+++ b/hw/ppc/spapr.c
4a2fec
@@ -3592,6 +3592,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
4a2fec
      * in which LMBs are represented and hot-added
4a2fec
      */
4a2fec
     mc->numa_mem_align_shift = 28;
4a2fec
+    smc->has_power9_support = true;
4a2fec
 }
4a2fec
 
4a2fec
 static const TypeInfo spapr_machine_info = {
4a2fec
@@ -3993,6 +3994,7 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
4a2fec
     spapr_machine_rhel750_class_options(mc);
4a2fec
     SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_4);
4a2fec
     mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
4a2fec
+    smc->has_power9_support = false;
4a2fec
     smc->pre_2_10_has_unused_icps = true;
4a2fec
     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
4a2fec
 }
4a2fec
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
4a2fec
index 3e731e4..400ab56 100644
4a2fec
--- a/hw/ppc/spapr_cpu_core.c
4a2fec
+++ b/hw/ppc/spapr_cpu_core.c
4a2fec
@@ -19,6 +19,7 @@
4a2fec
 #include "target/ppc/mmu-hash64.h"
4a2fec
 #include "sysemu/numa.h"
4a2fec
 #include "qemu/error-report.h"
4a2fec
+#include "cpu-models.h"
4a2fec
 
4a2fec
 void spapr_cpu_parse_features(sPAPRMachineState *spapr)
4a2fec
 {
4a2fec
@@ -111,6 +112,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
4a2fec
                            Error **errp)
4a2fec
 {
4a2fec
     CPUPPCState *env = &cpu->env;
4a2fec
+    sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
4a2fec
 
4a2fec
     /* Set time-base frequency to 512 MHz */
4a2fec
     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
4a2fec
@@ -118,6 +120,17 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
4a2fec
     /* Enable PAPR mode in TCG or KVM */
4a2fec
     cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
4a2fec
 
4a2fec
+    if (!smc->has_power9_support &&
4a2fec
+        (((spapr->max_compat_pvr &&
4a2fec
+           ppc_compat_cmp(spapr->max_compat_pvr,
4a2fec
+                          CPU_POWERPC_LOGICAL_3_00) >= 0)) ||
4a2fec
+          (!spapr->max_compat_pvr &&
4a2fec
+           ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) {
4a2fec
+        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
4a2fec
+                  "POWER9 CPU is not supported by this machine class");
4a2fec
+        return;
4a2fec
+    }
4a2fec
+
4a2fec
     qemu_register_reset(spapr_cpu_reset, cpu);
4a2fec
     spapr_cpu_reset(cpu);
4a2fec
 }
4a2fec
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
4a2fec
index 3d0d206..d9e8e5a 100644
4a2fec
--- a/include/hw/ppc/spapr.h
4a2fec
+++ b/include/hw/ppc/spapr.h
4a2fec
@@ -62,6 +62,7 @@ struct sPAPRMachineClass {
4a2fec
     bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
4a2fec
     const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */
4a2fec
     bool pre_2_10_has_unused_icps;
4a2fec
+    bool has_power9_support;
4a2fec
     void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
4a2fec
                           uint64_t *buid, hwaddr *pio, 
4a2fec
                           hwaddr *mmio32, hwaddr *mmio64,
4a2fec
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
4a2fec
index f8729fe..540b4eb 100644
4a2fec
--- a/target/ppc/compat.c
4a2fec
+++ b/target/ppc/compat.c
4a2fec
@@ -89,6 +89,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
4a2fec
     return NULL;
4a2fec
 }
4a2fec
 
4a2fec
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2)
4a2fec
+{
4a2fec
+    const CompatInfo *compat1 = compat_by_pvr(pvr1);
4a2fec
+    const CompatInfo *compat2 = compat_by_pvr(pvr2);
4a2fec
+
4a2fec
+    g_assert(compat1);
4a2fec
+    g_assert(compat2);
4a2fec
+
4a2fec
+    return compat1 - compat2;
4a2fec
+}
4a2fec
+
4a2fec
 bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
4a2fec
                       uint32_t min_compat_pvr, uint32_t max_compat_pvr)
4a2fec
 {
4a2fec
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
4a2fec
index 46d3dd8..6c770a2 100644
4a2fec
--- a/target/ppc/cpu.h
4a2fec
+++ b/target/ppc/cpu.h
4a2fec
@@ -1367,6 +1367,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
4a2fec
 
4a2fec
 /* Compatibility modes */
4a2fec
 #if defined(TARGET_PPC64)
4a2fec
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2);
4a2fec
 bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
4a2fec
                       uint32_t min_compat_pvr, uint32_t max_compat_pvr);
4a2fec
 void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp);
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec