summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm/book3s64/pkeys.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>2020-07-09 08:59:36 +0530
committerMichael Ellerman <mpe@ellerman.id.au>2020-07-20 22:57:58 +1000
commitd3cd91fb8d2e202cf8ebb6f271898aaf37ecda8f (patch)
tree437b21687e27c4730add32f1ac70f54bff231024 /arch/powerpc/mm/book3s64/pkeys.c
parent3e4352aeb8b17eb1040ba288f586620e8294389d (diff)
powerpc/book3s64/pkeys: Add MMU_FTR_PKEY
Parse storage keys related device tree entry in early_init_devtree and enable MMU feature MMU_FTR_PKEY if pkeys are supported. MMU feature is used instead of CPU feature because this enables us to group MMU_FTR_KUAP and MMU_FTR_PKEY in asm feature fixup code. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200709032946.881753-14-aneesh.kumar@linux.ibm.com
Diffstat (limited to 'arch/powerpc/mm/book3s64/pkeys.c')
-rw-r--r--arch/powerpc/mm/book3s64/pkeys.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c
index d84bf55369a3..028b17c2c511 100644
--- a/arch/powerpc/mm/book3s64/pkeys.c
+++ b/arch/powerpc/mm/book3s64/pkeys.c
@@ -10,7 +10,8 @@
#include <asm/mmu.h>
#include <asm/setup.h>
#include <linux/pkeys.h>
-#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+
DEFINE_STATIC_KEY_FALSE(pkey_disabled);
int num_pkey; /* Max number of pkeys supported */
@@ -46,31 +47,38 @@ static int execute_only_key = 2;
#define PKEY_REG_BITS (sizeof(u64) * 8)
#define pkeyshift(pkey) (PKEY_REG_BITS - ((pkey+1) * AMR_BITS_PER_PKEY))
+static int __init dt_scan_storage_keys(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const __be32 *prop;
+ int *pkeys_total = (int *) data;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "ibm,processor-storage-keys", NULL);
+ if (!prop)
+ return 0;
+ *pkeys_total = be32_to_cpu(prop[0]);
+ return 1;
+}
+
static int scan_pkey_feature(void)
{
- u32 vals[2];
+ int ret;
int pkeys_total = 0;
- struct device_node *cpu;
/*
* Pkey is not supported with Radix translation.
*/
- if (radix_enabled())
- return 0;
-
- cpu = of_find_node_by_type(NULL, "cpu");
- if (!cpu)
+ if (early_radix_enabled())
return 0;
- if (of_property_read_u32_array(cpu,
- "ibm,processor-storage-keys", vals, 2) == 0) {
- /*
- * Since any pkey can be used for data or execute, we will
- * just treat all keys as equal and track them as one entity.
- */
- pkeys_total = vals[0];
- } else {
-
+ ret = of_scan_flat_dt(dt_scan_storage_keys, &pkeys_total);
+ if (ret == 0) {
/*
* Let's assume 32 pkeys on P8/P9 bare metal, if its not defined by device
* tree. We make this exception since some version of skiboot forgot to
@@ -94,7 +102,7 @@ static int scan_pkey_feature(void)
return pkeys_total;
}
-static int pkey_initialize(void)
+void __init pkey_early_init_devtree(void)
{
int pkeys_total, i;
@@ -119,9 +127,11 @@ static int pkey_initialize(void)
if (!pkeys_total) {
/* No support for pkey. Mark it disabled */
static_branch_enable(&pkey_disabled);
- return 0;
+ return;
}
+ cur_cpu_spec->mmu_features |= MMU_FTR_PKEY;
+
/*
* The device tree cannot be relied to indicate support for
* execute_disable support. Instead we use a PVR check.
@@ -201,11 +211,9 @@ static int pkey_initialize(void)
*/
initial_allocation_mask |= reserved_allocation_mask;
- return 0;
+ return;
}
-arch_initcall(pkey_initialize);
-
void pkey_mm_init(struct mm_struct *mm)
{
if (static_branch_likely(&pkey_disabled))