26ba25
From 3c8c0e5bae7be14972cd38c470227d7037892a2c Mon Sep 17 00:00:00 2001
26ba25
From: David Gibson <dgibson@redhat.com>
26ba25
Date: Mon, 12 Nov 2018 01:28:35 +0000
26ba25
Subject: [PATCH 04/16] ppc/spapr_caps: Add SPAPR_CAP_NESTED_KVM_HV
26ba25
26ba25
RH-Author: David Gibson <dgibson@redhat.com>
26ba25
Message-id: <20181112012835.21863-5-dgibson@redhat.com>
26ba25
Patchwork-id: 82980
26ba25
O-Subject: [RHEL-8 qemu-kvm PATCH 4/4] ppc/spapr_caps: Add SPAPR_CAP_NESTED_KVM_HV
26ba25
Bugzilla: 1639069
26ba25
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
26ba25
RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
26ba25
RH-Acked-by: Thomas Huth <thuth@redhat.com>
26ba25
26ba25
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
26ba25
26ba25
Add the spapr cap SPAPR_CAP_NESTED_KVM_HV to be used to control the
26ba25
availability of nested kvm-hv to the level 1 (L1) guest.
26ba25
26ba25
Assuming a hypervisor with support enabled an L1 guest can be allowed to
26ba25
use the kvm-hv module (and thus run it's own kvm-hv guests) by setting:
26ba25
-machine pseries,cap-nested-hv=true
26ba25
or disabled with:
26ba25
-machine pseries,cap-nested-hv=false
26ba25
26ba25
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
26ba25
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
26ba25
(cherry picked from commit b9a477b725788e47bf653eab36e64f232d259f2a)
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
26ba25
Conflicts:
26ba25
	hw/ppc/spapr.c
26ba25
	hw/ppc/spapr_caps.c
26ba25
	include/hw/ppc/spapr.h
26ba25
26ba25
We need some tweaks to renumber the nested KVM cap from upstream,
26ba25
because we don't have the maximum page size capability downstream and
26ba25
the code doesn't like sparse cap numbers.  This is safe, because the
26ba25
cap number does not appear in the migration stream, so it's strictly
26ba25
local (the cap name is used for migration).
26ba25
26ba25
We also work around a contextual conflict.
26ba25
26ba25
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1639069
26ba25
26ba25
Signed-off-by: David Gibson <dgibson@redhat.com>
26ba25
---
26ba25
 hw/ppc/spapr.c         |  2 ++
26ba25
 hw/ppc/spapr_caps.c    | 32 ++++++++++++++++++++++++++++++++
26ba25
 include/hw/ppc/spapr.h |  5 ++++-
26ba25
 target/ppc/kvm.c       | 12 ++++++++++++
26ba25
 target/ppc/kvm_ppc.h   | 12 ++++++++++++
26ba25
 5 files changed, 62 insertions(+), 1 deletion(-)
26ba25
26ba25
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
26ba25
index a61dafd..ea72782 100644
26ba25
--- a/hw/ppc/spapr.c
26ba25
+++ b/hw/ppc/spapr.c
26ba25
@@ -1816,6 +1816,7 @@ static const VMStateDescription vmstate_spapr = {
26ba25
         &vmstate_spapr_cap_cfpc,
26ba25
         &vmstate_spapr_cap_sbbc,
26ba25
         &vmstate_spapr_cap_ibs,
26ba25
+        &vmstate_spapr_cap_nested_kvm_hv,
26ba25
         NULL
26ba25
     }
26ba25
 };
26ba25
@@ -3922,6 +3923,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
26ba25
     smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
26ba25
     smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
26ba25
     smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
26ba25
+    smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
26ba25
     spapr_caps_add_properties(smc, &error_abort);
26ba25
     smc->has_power9_support = true;
26ba25
 }
26ba25
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
26ba25
index 00e43a9..86a7947 100644
26ba25
--- a/hw/ppc/spapr_caps.c
26ba25
+++ b/hw/ppc/spapr_caps.c
26ba25
@@ -265,6 +265,28 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
26ba25
 
26ba25
 #define VALUE_DESC_TRISTATE     " (broken, workaround, fixed)"
26ba25
 
26ba25
+static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
26ba25
+                                    uint8_t val, Error **errp)
26ba25
+{
26ba25
+    if (!val) {
26ba25
+        /* capability disabled by default */
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    if (tcg_enabled()) {
26ba25
+        error_setg(errp,
26ba25
+                   "No Nested KVM-HV support in tcg, try cap-nested-hv=off");
26ba25
+    } else if (kvm_enabled()) {
26ba25
+        if (!kvmppc_has_cap_nested_kvm_hv()) {
26ba25
+            error_setg(errp,
26ba25
+"KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off");
26ba25
+        } else if (kvmppc_set_cap_nested_kvm_hv(val) < 0) {
26ba25
+                error_setg(errp,
26ba25
+"Error enabling cap-nested-hv with KVM, try cap-nested-hv=off");
26ba25
+        }
26ba25
+    }
26ba25
+}
26ba25
+
26ba25
 sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
26ba25
     [SPAPR_CAP_HTM] = {
26ba25
         .name = "htm",
26ba25
@@ -324,6 +346,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
26ba25
         .possible = &cap_ibs_possible,
26ba25
         .apply = cap_safe_indirect_branch_apply,
26ba25
     },
26ba25
+    [SPAPR_CAP_NESTED_KVM_HV] = {
26ba25
+        .name = "nested-hv",
26ba25
+        .description = "Allow Nested KVM-HV",
26ba25
+        .index = SPAPR_CAP_NESTED_KVM_HV,
26ba25
+        .get = spapr_cap_get_bool,
26ba25
+        .set = spapr_cap_set_bool,
26ba25
+        .type = "bool",
26ba25
+        .apply = cap_nested_kvm_hv_apply,
26ba25
+    },
26ba25
 };
26ba25
 
26ba25
 static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
26ba25
@@ -439,6 +470,7 @@ SPAPR_CAP_MIG_STATE(dfp, SPAPR_CAP_DFP);
26ba25
 SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
26ba25
 SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
26ba25
 SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
26ba25
+SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
26ba25
 
26ba25
 void spapr_caps_reset(sPAPRMachineState *spapr)
26ba25
 {
26ba25
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
26ba25
index 5118af6..beb42bc 100644
26ba25
--- a/include/hw/ppc/spapr.h
26ba25
+++ b/include/hw/ppc/spapr.h
26ba25
@@ -66,8 +66,10 @@ typedef enum {
26ba25
 #define SPAPR_CAP_SBBC                  0x04
26ba25
 /* Indirect Branch Serialisation */
26ba25
 #define SPAPR_CAP_IBS                   0x05
26ba25
+/* Nested KVM-HV */
26ba25
+#define SPAPR_CAP_NESTED_KVM_HV         0x06
26ba25
 /* Num Caps */
26ba25
-#define SPAPR_CAP_NUM                   (SPAPR_CAP_IBS + 1)
26ba25
+#define SPAPR_CAP_NUM                   (SPAPR_CAP_NESTED_KVM_HV + 1)
26ba25
 
26ba25
 /*
26ba25
  * Capability Values
26ba25
@@ -794,6 +796,7 @@ extern const VMStateDescription vmstate_spapr_cap_dfp;
26ba25
 extern const VMStateDescription vmstate_spapr_cap_cfpc;
26ba25
 extern const VMStateDescription vmstate_spapr_cap_sbbc;
26ba25
 extern const VMStateDescription vmstate_spapr_cap_ibs;
26ba25
+extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
26ba25
 
26ba25
 static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
26ba25
 {
26ba25
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
26ba25
index 192c40d..058dcbe 100644
26ba25
--- a/target/ppc/kvm.c
26ba25
+++ b/target/ppc/kvm.c
26ba25
@@ -92,6 +92,7 @@ static int cap_ppc_pvr_compat;
26ba25
 static int cap_ppc_safe_cache;
26ba25
 static int cap_ppc_safe_bounds_check;
26ba25
 static int cap_ppc_safe_indirect_branch;
26ba25
+static int cap_ppc_nested_kvm_hv;
26ba25
 
26ba25
 static uint32_t debug_inst_opcode;
26ba25
 
26ba25
@@ -152,6 +153,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
26ba25
     cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
26ba25
     cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
26ba25
     kvmppc_get_cpu_characteristics(s);
26ba25
+    cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
26ba25
     /*
26ba25
      * Note: setting it to false because there is not such capability
26ba25
      * in KVM at this moment.
26ba25
@@ -2552,6 +2554,16 @@ int kvmppc_get_cap_safe_indirect_branch(void)
26ba25
     return cap_ppc_safe_indirect_branch;
26ba25
 }
26ba25
 
26ba25
+bool kvmppc_has_cap_nested_kvm_hv(void)
26ba25
+{
26ba25
+    return !!cap_ppc_nested_kvm_hv;
26ba25
+}
26ba25
+
26ba25
+int kvmppc_set_cap_nested_kvm_hv(int enable)
26ba25
+{
26ba25
+    return kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_NESTED_HV, 0, enable);
26ba25
+}
26ba25
+
26ba25
 bool kvmppc_has_cap_spapr_vfio(void)
26ba25
 {
26ba25
     return cap_spapr_vfio;
26ba25
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
26ba25
index 4d2789e..dc86eff 100644
26ba25
--- a/target/ppc/kvm_ppc.h
26ba25
+++ b/target/ppc/kvm_ppc.h
26ba25
@@ -63,6 +63,8 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
26ba25
 int kvmppc_get_cap_safe_cache(void);
26ba25
 int kvmppc_get_cap_safe_bounds_check(void);
26ba25
 int kvmppc_get_cap_safe_indirect_branch(void);
26ba25
+bool kvmppc_has_cap_nested_kvm_hv(void);
26ba25
+int kvmppc_set_cap_nested_kvm_hv(int enable);
26ba25
 int kvmppc_enable_hwrng(void);
26ba25
 int kvmppc_put_books_sregs(PowerPCCPU *cpu);
26ba25
 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
26ba25
@@ -314,6 +316,16 @@ static inline int kvmppc_get_cap_safe_indirect_branch(void)
26ba25
     return 0;
26ba25
 }
26ba25
 
26ba25
+static inline bool kvmppc_has_cap_nested_kvm_hv(void)
26ba25
+{
26ba25
+    return false;
26ba25
+}
26ba25
+
26ba25
+static inline int kvmppc_set_cap_nested_kvm_hv(int enable)
26ba25
+{
26ba25
+    return -1;
26ba25
+}
26ba25
+
26ba25
 static inline int kvmppc_enable_hwrng(void)
26ba25
 {
26ba25
     return -1;
26ba25
-- 
26ba25
1.8.3.1
26ba25