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