]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - arch/powerpc/platforms/powernv/opal.c
powerpc/powernv: Fix boot on Power8 bare metal due to opal_configure_cores()
[mirror_ubuntu-zesty-kernel.git] / arch / powerpc / platforms / powernv / opal.c
index 86d9fde93c175f86dac6f40de0d68aff2455b0c6..26b290c1c91674eeeb05b3067487e7e34433b8a6 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 (early_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();
@@ -395,7 +410,6 @@ static int opal_recover_mce(struct pt_regs *regs,
                                        struct machine_check_event *evt)
 {
        int recovered = 0;
-       uint64_t ea = get_mce_fault_addr(evt);
 
        if (!(regs->msr & MSR_RI)) {
                /* If MSR_RI isn't set, we cannot recover */
@@ -404,26 +418,18 @@ static int opal_recover_mce(struct pt_regs *regs,
        } else if (evt->disposition == MCE_DISPOSITION_RECOVERED) {
                /* Platform corrected itself */
                recovered = 1;
-       } else if (ea && !is_kernel_addr(ea)) {
+       } else if (evt->severity == MCE_SEV_FATAL) {
+               /* Fatal machine check */
+               pr_err("Machine check interrupt is fatal\n");
+               recovered = 0;
+       } else if ((evt->severity == MCE_SEV_ERROR_SYNC) &&
+                       (user_mode(regs) && !is_global_init(current))) {
                /*
-                * Faulting address is not in kernel text. We should be fine.
-                * We need to find which process uses this address.
                 * For now, kill the task if we have received exception when
                 * in userspace.
                 *
                 * TODO: Queue up this address for hwpoisioning later.
                 */
-               if (user_mode(regs) && !is_global_init(current)) {
-                       _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
-                       recovered = 1;
-               } else
-                       recovered = 0;
-       } else if (user_mode(regs) && !is_global_init(current) &&
-               evt->severity == MCE_SEV_ERROR_SYNC) {
-               /*
-                * If we have received a synchronous error when in userspace
-                * kill the task.
-                */
                _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
                recovered = 1;
        }