Commit 18569c1f authored by Paul Mackerras's avatar Paul Mackerras Committed by Michael Ellerman

powerpc/64: Don't try to use radix MMU under a hypervisor

Currently, if the kernel is running on a POWER9 processor under a
hypervisor, it will try to use the radix MMU even though it doesn't have
the necessary code to use radix under a hypervisor (it doesn't negotiate
use of radix, and it doesn't do the H_REGISTER_PROC_TBL hcall). The
result is that the guest kernel will crash when it tries to turn on the
MMU.

This fixes it by looking for the /chosen/ibm,architecture-vec-5
property, and if it exists, clears the radix MMU feature bit, before we
decide whether to initialize for radix or HPT. This property is created
by the hypervisor as a result of the guest calling the
ibm,client-architecture-support method to indicate its capabilities, so
it will indicate whether the hypervisor agreed to us using radix.

Systems without a hypervisor may have this property also (for example,
skiboot creates it), so we check the HV bit in the MSR to see whether we
are running as a guest or not. If we are in hypervisor mode, then we can
do whatever we like including using the radix MMU.

The reason for using this property is that in future, when we have
support for using radix under a hypervisor, we will need to check this
property to see whether the hypervisor agreed to us using radix.

Fixes: 2bfd65e4 ("powerpc/mm/radix: Add radix callbacks for early init routines")
Cc: stable@vger.kernel.org # v4.7+
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent a97a65d5
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -344,12 +346,43 @@ static int __init parse_disable_radix(char *p) ...@@ -344,12 +346,43 @@ static int __init parse_disable_radix(char *p)
} }
early_param("disable_radix", parse_disable_radix); early_param("disable_radix", parse_disable_radix);
/*
* If we're running under a hypervisor, we currently can't do radix
* since we don't have the code to do the H_REGISTER_PROC_TBL hcall.
* We tell that we're running under a hypervisor by looking for the
* /chosen/ibm,architecture-vec-5 property.
*/
static void early_check_vec5(void)
{
unsigned long root, chosen;
int size;
const u8 *vec5;
root = of_get_flat_dt_root();
chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
if (chosen == -FDT_ERR_NOTFOUND)
return;
vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
if (!vec5)
return;
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
}
void __init mmu_early_init_devtree(void) void __init mmu_early_init_devtree(void)
{ {
/* Disable radix mode based on kernel command line. */ /* Disable radix mode based on kernel command line. */
if (disable_radix) if (disable_radix)
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX; cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
/*
* Check /chosen/ibm,architecture-vec-5 if running as a guest.
* When running bare-metal, we can use radix if we like
* even though the ibm,architecture-vec-5 property created by
* skiboot doesn't have the necessary bits set.
*/
if (early_radix_enabled() && !(mfmsr() & MSR_HV))
early_check_vec5();
if (early_radix_enabled()) if (early_radix_enabled())
radix__early_init_devtree(); radix__early_init_devtree();
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment