diff mbox series

[QEMU-PPC,13/13] target/ppc: Enable SPAPR_CAP_NESTED_KVM_HV under tcg

Message ID 20190503055316.6441-14-sjitindarsingh@gmail.com (mailing list archive)
State New, archived
Headers show
Series target/ppc: Implement KVM support under TCG | expand

Commit Message

Suraj Jitindar Singh May 3, 2019, 5:53 a.m. UTC
It is now possible to use nested kvm-hv under tcg, thus allow for it to
be enabled.

Note that nested kvm-hv requires that rc updates to ptes be done by
software, otherwise the page tables get out of sync. So disable hardware
rc updates when nested kvm-hv is enabled.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_caps.c      | 22 ++++++++++++++++++----
 target/ppc/cpu.h         |  1 +
 target/ppc/mmu-radix64.c |  4 ++--
 3 files changed, 21 insertions(+), 6 deletions(-)

Comments

David Gibson May 10, 2019, 6:34 a.m. UTC | #1
On Fri, May 03, 2019 at 03:53:16PM +1000, Suraj Jitindar Singh wrote:
> It is now possible to use nested kvm-hv under tcg, thus allow for it to
> be enabled.
> 
> Note that nested kvm-hv requires that rc updates to ptes be done by
> software, otherwise the page tables get out of sync. So disable hardware
> rc updates when nested kvm-hv is enabled.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  hw/ppc/spapr_caps.c      | 22 ++++++++++++++++++----
>  target/ppc/cpu.h         |  1 +
>  target/ppc/mmu-radix64.c |  4 ++--
>  3 files changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> index 3278c09b0f..7fe07d83dd 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -389,10 +389,7 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
>          return;
>      }
>  
> -    if (tcg_enabled()) {
> -        error_setg(errp,
> -                   "No Nested KVM-HV support in tcg, try cap-nested-hv=off");
> -    } else if (kvm_enabled()) {
> +    if (kvm_enabled()) {
>          if (!kvmppc_has_cap_nested_kvm_hv()) {
>              error_setg(errp,
>  "KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off");
> @@ -400,6 +397,22 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
>                  error_setg(errp,
>  "Error enabling cap-nested-hv with KVM, try cap-nested-hv=off");
>          }
> +    } /* else { nothing required for tcg } */
> +}
> +
> +static void cap_nested_kvm_hv_cpu_apply(SpaprMachineState *spapr,
> +                                        PowerPCCPU *cpu,
> +                                        uint8_t val, Error **errp)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (tcg_enabled() && val) {
> +        if (env->spr[SPR_PVR] != 0x004E1202) {

Hrm.  Something other than an explicit PVR check would be nice (or
we'll have to keep hacking this when DD2.3 arrives).

> +            error_setg(errp, "Nested KVM-HV only supported on POWER9 DD2.2, "
> +                             "try cap-nested-hv=off or -cpu power9_v2.2");
> +            return;
> +        }
> +        env->disable_hw_rc_updates = true;
>      }
>  }
>  
> @@ -544,6 +557,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>          .set = spapr_cap_set_bool,
>          .type = "bool",
>          .apply = cap_nested_kvm_hv_apply,
> +        .cpu_apply = cap_nested_kvm_hv_cpu_apply,
>      },
>      [SPAPR_CAP_LARGE_DECREMENTER] = {
>          .name = "large-decr",
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 426015c9cd..6502e0de82 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1237,6 +1237,7 @@ struct CPUPPCState {
>      target_ulong hv_ptr, regs_ptr;
>      struct hv_guest_state l2_hv, l1_saved_hv;
>      struct pt_regs l2_regs, l1_saved_regs;
> +    bool disable_hw_rc_updates;
>  };
>  
>  #define SET_FIT_PERIOD(a_, b_, c_, d_)          \
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index 2a8147fc38..cc06967dbe 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -31,9 +31,9 @@
>  static inline bool ppc_radix64_hw_rc_updates(CPUPPCState *env)
>  {
>  #ifdef CONFIG_ATOMIC64
> -    return true;
> +    return !env->disable_hw_rc_updates;
>  #else
> -    return !qemu_tcg_mttcg_enabled();
> +    return !qemu_tcg_mttcg_enabled() && !env->disable_hw_rc_updates;
>  #endif
>  }
>
diff mbox series

Patch

diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 3278c09b0f..7fe07d83dd 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -389,10 +389,7 @@  static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
         return;
     }
 
-    if (tcg_enabled()) {
-        error_setg(errp,
-                   "No Nested KVM-HV support in tcg, try cap-nested-hv=off");
-    } else if (kvm_enabled()) {
+    if (kvm_enabled()) {
         if (!kvmppc_has_cap_nested_kvm_hv()) {
             error_setg(errp,
 "KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off");
@@ -400,6 +397,22 @@  static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
                 error_setg(errp,
 "Error enabling cap-nested-hv with KVM, try cap-nested-hv=off");
         }
+    } /* else { nothing required for tcg } */
+}
+
+static void cap_nested_kvm_hv_cpu_apply(SpaprMachineState *spapr,
+                                        PowerPCCPU *cpu,
+                                        uint8_t val, Error **errp)
+{
+    CPUPPCState *env = &cpu->env;
+
+    if (tcg_enabled() && val) {
+        if (env->spr[SPR_PVR] != 0x004E1202) {
+            error_setg(errp, "Nested KVM-HV only supported on POWER9 DD2.2, "
+                             "try cap-nested-hv=off or -cpu power9_v2.2");
+            return;
+        }
+        env->disable_hw_rc_updates = true;
     }
 }
 
@@ -544,6 +557,7 @@  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .set = spapr_cap_set_bool,
         .type = "bool",
         .apply = cap_nested_kvm_hv_apply,
+        .cpu_apply = cap_nested_kvm_hv_cpu_apply,
     },
     [SPAPR_CAP_LARGE_DECREMENTER] = {
         .name = "large-decr",
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 426015c9cd..6502e0de82 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1237,6 +1237,7 @@  struct CPUPPCState {
     target_ulong hv_ptr, regs_ptr;
     struct hv_guest_state l2_hv, l1_saved_hv;
     struct pt_regs l2_regs, l1_saved_regs;
+    bool disable_hw_rc_updates;
 };
 
 #define SET_FIT_PERIOD(a_, b_, c_, d_)          \
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 2a8147fc38..cc06967dbe 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -31,9 +31,9 @@ 
 static inline bool ppc_radix64_hw_rc_updates(CPUPPCState *env)
 {
 #ifdef CONFIG_ATOMIC64
-    return true;
+    return !env->disable_hw_rc_updates;
 #else
-    return !qemu_tcg_mttcg_enabled();
+    return !qemu_tcg_mttcg_enabled() && !env->disable_hw_rc_updates;
 #endif
 }