powerpc/powernv: Tell OPAL about our MMU mode on POWER9
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 30 Jun 2017 22:37:32 +0000 (17:37 -0500)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 10 Jul 2017 11:12:27 +0000 (21:12 +1000)
That will allow OPAL to configure the CPU in an optimal way.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/opal-api.h
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/setup.c

index ef930ba500f9494316ae1d64e2bed31c201b7e65..3130a73652c70ac6bb89747b1e906b6b853f6aee 100644 (file)
@@ -876,6 +876,15 @@ struct OpalIoPhb4ErrorData {
 enum {
        OPAL_REINIT_CPUS_HILE_BE        = (1 << 0),
        OPAL_REINIT_CPUS_HILE_LE        = (1 << 1),
+
+       /* These two define the base MMU mode of the host on P9
+        *
+        * On P9 Nimbus DD2.0 and Cumlus (and later), KVM can still
+        * create hash guests in "radix" mode with care (full core
+        * switch only).
+        */
+       OPAL_REINIT_CPUS_MMU_HASH       = (1 << 2),
+       OPAL_REINIT_CPUS_MMU_RADIX      = (1 << 3),
 };
 
 typedef struct oppanel_line {
index 59684b4af4d1dfba4990ae73f63d03f77fc61f38..9b87abb178f02aaa0dd3afc757499df58bf133eb 100644 (file)
@@ -59,6 +59,8 @@ static struct task_struct *kopald_tsk;
 
 void opal_configure_cores(void)
 {
+       u64 reinit_flags = 0;
+
        /* Do the actual re-init, This will clobber all FPRs, VRs, etc...
         *
         * It will preserve non volatile GPRs and HSPRG0/1. It will
@@ -66,11 +68,24 @@ void opal_configure_cores(void)
         * but it might clobber a bunch.
         */
 #ifdef __BIG_ENDIAN__
-       opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);
+       reinit_flags |= OPAL_REINIT_CPUS_HILE_BE;
 #else
-       opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE);
+       reinit_flags |= OPAL_REINIT_CPUS_HILE_LE;
 #endif
 
+       /*
+        * POWER9 always support running hash:
+        *  ie. Host hash  supports  hash guests
+        *      Host radix supports  hash/radix guests
+        */
+       if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+               reinit_flags |= OPAL_REINIT_CPUS_MMU_HASH;
+               if (early_radix_enabled())
+                       reinit_flags |= OPAL_REINIT_CPUS_MMU_RADIX;
+       }
+
+       opal_reinit_cpus(reinit_flags);
+
        /* Restore some bits */
        if (cur_cpu_spec->cpu_restore)
                cur_cpu_spec->cpu_restore();
index 2dc7e5fb86c330df32d5c5bbb1af1e30042e122f..897aa1400eb833e944fabbc65840904006267a1f 100644 (file)
@@ -225,6 +225,8 @@ static void pnv_kexec_wait_secondaries_down(void)
 
 static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
 {
+       u64 reinit_flags;
+
        if (xive_enabled())
                xive_kexec_teardown_cpu(secondary);
        else
@@ -254,8 +256,15 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
                 * We might be running as little-endian - now that interrupts
                 * are disabled, reset the HILE bit to big-endian so we don't
                 * take interrupts in the wrong endian later
+                *
+                * We reinit to enable both radix and hash on P9 to ensure
+                * the mode used by the next kernel is always supported.
                 */
-               opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);
+               reinit_flags = OPAL_REINIT_CPUS_HILE_BE;
+               if (cpu_has_feature(CPU_FTR_ARCH_300))
+                       reinit_flags |= OPAL_REINIT_CPUS_MMU_RADIX |
+                               OPAL_REINIT_CPUS_MMU_HASH;
+               opal_reinit_cpus(reinit_flags);
        }
 }
 #endif /* CONFIG_KEXEC_CORE */