blob: d84bf55369a3a54ad662971ee1edd81976acb3c8 [file] [log] [blame]
Ram Pai92e3da32018-01-18 17:50:24 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PowerPC Memory Protection Keys management
4 *
5 * Copyright 2017, Ram Pai, IBM Corporation.
6 */
7
Ram Pai2ddc53f2018-01-18 17:50:29 -08008#include <asm/mman.h>
Breno Leitao71432ce2018-10-22 11:54:20 -03009#include <asm/mmu_context.h>
Michael Ellerman890274c2019-04-18 16:51:24 +100010#include <asm/mmu.h>
Ram Paicf43d3b2018-01-18 17:50:44 -080011#include <asm/setup.h>
Ram Pai92e3da32018-01-18 17:50:24 -080012#include <linux/pkeys.h>
Ram Paicf43d3b2018-01-18 17:50:44 -080013#include <linux/of_device.h>
Ram Pai92e3da32018-01-18 17:50:24 -080014
Aneesh Kumar K.Va4678d42020-07-09 08:59:32 +053015DEFINE_STATIC_KEY_FALSE(pkey_disabled);
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +053016int num_pkey; /* Max number of pkeys supported */
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053017/*
18 * Keys marked in the reservation list cannot be allocated by userspace
19 */
Aneesh Kumar K.V3c8ab472020-07-09 08:59:34 +053020u32 reserved_allocation_mask __ro_after_init;
21
22/* Bits set for the initially allocated keys */
23static u32 initial_allocation_mask __ro_after_init;
24
Breno Leitao71432ce2018-10-22 11:54:20 -030025static bool pkey_execute_disable_supported;
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053026/*
27 * Even if we allocate keys with sys_pkey_alloc(), we need to make sure
28 * other thread still find the access denied using the same keys.
29 */
30static u64 default_amr = ~0x0UL;
31static u64 default_iamr = 0x5555555555555555UL;
32
33/* Allow all keys to be modified by default */
34static u64 default_uamor = ~0x0UL;
35/*
36 * Key used to implement PROT_EXEC mmap. Denies READ/WRITE
37 * We pick key 2 because 0 is special key and 1 is reserved as per ISA.
38 */
Breno Leitao71432ce2018-10-22 11:54:20 -030039static int execute_only_key = 2;
Ram Pai92e3da32018-01-18 17:50:24 -080040
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053041
Ram Pai4d70b692018-01-18 17:50:27 -080042#define AMR_BITS_PER_PKEY 2
Ram Pai2ddc53f2018-01-18 17:50:29 -080043#define AMR_RD_BIT 0x1UL
44#define AMR_WR_BIT 0x2UL
45#define IAMR_EX_BIT 0x1UL
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053046#define PKEY_REG_BITS (sizeof(u64) * 8)
Ram Pai4d70b692018-01-18 17:50:27 -080047#define pkeyshift(pkey) (PKEY_REG_BITS - ((pkey+1) * AMR_BITS_PER_PKEY))
48
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053049static int scan_pkey_feature(void)
Ram Paicf43d3b2018-01-18 17:50:44 -080050{
51 u32 vals[2];
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053052 int pkeys_total = 0;
Ram Paicf43d3b2018-01-18 17:50:44 -080053 struct device_node *cpu;
54
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053055 /*
56 * Pkey is not supported with Radix translation.
57 */
58 if (radix_enabled())
59 return 0;
60
Ram Paicf43d3b2018-01-18 17:50:44 -080061 cpu = of_find_node_by_type(NULL, "cpu");
62 if (!cpu)
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053063 return 0;
Ram Paicf43d3b2018-01-18 17:50:44 -080064
65 if (of_property_read_u32_array(cpu,
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053066 "ibm,processor-storage-keys", vals, 2) == 0) {
67 /*
68 * Since any pkey can be used for data or execute, we will
69 * just treat all keys as equal and track them as one entity.
70 */
71 pkeys_total = vals[0];
72 } else {
73
74 /*
75 * Let's assume 32 pkeys on P8/P9 bare metal, if its not defined by device
76 * tree. We make this exception since some version of skiboot forgot to
77 * expose this property on power8/9.
78 */
79 if (!firmware_has_feature(FW_FEATURE_LPAR)) {
80 unsigned long pvr = mfspr(SPRN_PVR);
81
82 if (PVR_VER(pvr) == PVR_POWER8 || PVR_VER(pvr) == PVR_POWER8E ||
83 PVR_VER(pvr) == PVR_POWER8NVL || PVR_VER(pvr) == PVR_POWER9)
84 pkeys_total = 32;
85 }
86 }
Ram Paicf43d3b2018-01-18 17:50:44 -080087
88 /*
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053089 * Adjust the upper limit, based on the number of bits supported by
90 * arch-neutral code.
Ram Paicf43d3b2018-01-18 17:50:44 -080091 */
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +053092 pkeys_total = min_t(int, pkeys_total,
93 ((ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) + 1));
94 return pkeys_total;
Ram Paicf43d3b2018-01-18 17:50:44 -080095}
96
Breno Leitao71432ce2018-10-22 11:54:20 -030097static int pkey_initialize(void)
Ram Pai92e3da32018-01-18 17:50:24 -080098{
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +053099 int pkeys_total, i;
Ram Pai4fb158f2018-01-18 17:50:25 -0800100
Ram Pai92e3da32018-01-18 17:50:24 -0800101 /*
Ram Paidcf87292018-01-18 17:50:30 -0800102 * We define PKEY_DISABLE_EXECUTE in addition to the arch-neutral
103 * generic defines for PKEY_DISABLE_ACCESS and PKEY_DISABLE_WRITE.
104 * Ensure that the bits a distinct.
105 */
106 BUILD_BUG_ON(PKEY_DISABLE_EXECUTE &
107 (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
108
109 /*
Ram Pai013a91b2018-01-18 17:50:33 -0800110 * pkey_to_vmflag_bits() assumes that the pkey bits are contiguous
111 * in the vmaflag. Make sure that is really the case.
112 */
113 BUILD_BUG_ON(__builtin_clzl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) +
114 __builtin_popcountl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT)
115 != (sizeof(u64) * BITS_PER_BYTE));
116
Ram Paicf43d3b2018-01-18 17:50:44 -0800117 /* scan the device tree for pkey feature */
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530118 pkeys_total = scan_pkey_feature();
Aneesh Kumar K.Va4678d42020-07-09 08:59:32 +0530119 if (!pkeys_total) {
120 /* No support for pkey. Mark it disabled */
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530121 static_branch_enable(&pkey_disabled);
Ram Paicf43d3b2018-01-18 17:50:44 -0800122 return 0;
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530123 }
Ram Paicf43d3b2018-01-18 17:50:44 -0800124
Ram Pai92e3da32018-01-18 17:50:24 -0800125 /*
Ram Paicf43d3b2018-01-18 17:50:44 -0800126 * The device tree cannot be relied to indicate support for
127 * execute_disable support. Instead we use a PVR check.
Ram Pai92e3da32018-01-18 17:50:24 -0800128 */
Ram Paicf43d3b2018-01-18 17:50:44 -0800129 if (pvr_version_is(PVR_POWER7) || pvr_version_is(PVR_POWER7p))
130 pkey_execute_disable_supported = false;
131 else
132 pkey_execute_disable_supported = true;
Ram Pai4fb158f2018-01-18 17:50:25 -0800133
134#ifdef CONFIG_PPC_4K_PAGES
135 /*
136 * The OS can manage only 8 pkeys due to its inability to represent them
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530137 * in the Linux 4K PTE. Mark all other keys reserved.
Ram Pai4fb158f2018-01-18 17:50:25 -0800138 */
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +0530139 num_pkey = min(8, pkeys_total);
Ram Pai4fb158f2018-01-18 17:50:25 -0800140#else
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +0530141 num_pkey = pkeys_total;
Ram Pai4fb158f2018-01-18 17:50:25 -0800142#endif
Ram Paia57a04c2018-07-17 06:51:02 -0700143
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +0530144 if (unlikely(num_pkey <= execute_only_key)) {
Ram Paia4fcc872018-07-17 06:51:07 -0700145 /*
146 * Insufficient number of keys to support
147 * execute only key. Mark it unavailable.
Ram Paia4fcc872018-07-17 06:51:07 -0700148 */
149 execute_only_key = -1;
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530150 } else {
151 /*
152 * Mark the execute_only_pkey as not available for
153 * user allocation via pkey_alloc.
154 */
155 reserved_allocation_mask |= (0x1 << execute_only_key);
156
157 /*
158 * Deny READ/WRITE for execute_only_key.
159 * Allow execute in IAMR.
160 */
161 default_amr |= (0x3ul << pkeyshift(execute_only_key));
162 default_iamr &= ~(0x1ul << pkeyshift(execute_only_key));
163
164 /*
165 * Clear the uamor bits for this key.
166 */
167 default_uamor &= ~(0x3ul << pkeyshift(execute_only_key));
Ram Paia4fcc872018-07-17 06:51:07 -0700168 }
169
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530170 /*
171 * Allow access for only key 0. And prevent any other modification.
172 */
173 default_amr &= ~(0x3ul << pkeyshift(0));
174 default_iamr &= ~(0x1ul << pkeyshift(0));
175 default_uamor &= ~(0x3ul << pkeyshift(0));
176 /*
177 * key 0 is special in that we want to consider it an allocated
178 * key which is preallocated. We don't allow changing AMR bits
179 * w.r.t key 0. But one can pkey_free(key0)
180 */
181 initial_allocation_mask |= (0x1 << 0);
182
183 /*
184 * key 1 is recommended not to be used. PowerISA(3.0) page 1015,
185 * programming note.
186 */
187 reserved_allocation_mask |= (0x1 << 1);
Aneesh Kumar K.V718d9b32020-07-09 08:59:30 +0530188 default_uamor &= ~(0x3ul << pkeyshift(1));
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530189
190 /*
Aneesh Kumar K.Vc529afd2020-07-09 08:59:33 +0530191 * Prevent the usage of OS reserved keys. Update UAMOR
Aneesh Kumar K.V3e4352a2020-07-09 08:59:35 +0530192 * for those keys. Also mark the rest of the bits in the
193 * 32 bit mask as reserved.
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530194 */
Aneesh Kumar K.V3e4352a2020-07-09 08:59:35 +0530195 for (i = num_pkey; i < 32 ; i++) {
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530196 reserved_allocation_mask |= (0x1 << i);
197 default_uamor &= ~(0x3ul << pkeyshift(i));
198 }
199 /*
200 * Prevent the allocation of reserved keys too.
201 */
202 initial_allocation_mask |= reserved_allocation_mask;
203
Ram Pai92e3da32018-01-18 17:50:24 -0800204 return 0;
205}
206
207arch_initcall(pkey_initialize);
Ram Pai4fb158f2018-01-18 17:50:25 -0800208
209void pkey_mm_init(struct mm_struct *mm)
210{
211 if (static_branch_likely(&pkey_disabled))
212 return;
213 mm_pkey_allocation_map(mm) = initial_allocation_mask;
Ram Paia4fcc872018-07-17 06:51:07 -0700214 mm->context.execute_only_pkey = execute_only_key;
Ram Pai4fb158f2018-01-18 17:50:25 -0800215}
Ram Pai1b4037d2018-01-18 17:50:26 -0800216
217static inline u64 read_amr(void)
218{
219 return mfspr(SPRN_AMR);
220}
221
222static inline void write_amr(u64 value)
223{
224 mtspr(SPRN_AMR, value);
225}
226
227static inline u64 read_iamr(void)
228{
229 if (!likely(pkey_execute_disable_supported))
230 return 0x0UL;
231
232 return mfspr(SPRN_IAMR);
233}
234
235static inline void write_iamr(u64 value)
236{
237 if (!likely(pkey_execute_disable_supported))
238 return;
239
240 mtspr(SPRN_IAMR, value);
241}
242
243static inline u64 read_uamor(void)
244{
245 return mfspr(SPRN_UAMOR);
246}
247
248static inline void write_uamor(u64 value)
249{
250 mtspr(SPRN_UAMOR, value);
251}
Ram Pai4d70b692018-01-18 17:50:27 -0800252
Ram Pai2ddc53f2018-01-18 17:50:29 -0800253static bool is_pkey_enabled(int pkey)
254{
255 u64 uamor = read_uamor();
256 u64 pkey_bits = 0x3ul << pkeyshift(pkey);
257 u64 uamor_pkey_bits = (uamor & pkey_bits);
258
259 /*
260 * Both the bits in UAMOR corresponding to the key should be set or
261 * reset.
262 */
263 WARN_ON(uamor_pkey_bits && (uamor_pkey_bits != pkey_bits));
264 return !!(uamor_pkey_bits);
265}
266
Ram Pai4d70b692018-01-18 17:50:27 -0800267static inline void init_amr(int pkey, u8 init_bits)
268{
269 u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey));
270 u64 old_amr = read_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
271
272 write_amr(old_amr | new_amr_bits);
273}
274
275static inline void init_iamr(int pkey, u8 init_bits)
276{
277 u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey));
278 u64 old_iamr = read_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
279
280 write_iamr(old_iamr | new_iamr_bits);
281}
282
Ram Pai2ddc53f2018-01-18 17:50:29 -0800283/*
284 * Set the access rights in AMR IAMR and UAMOR registers for @pkey to that
285 * specified in @init_val.
286 */
287int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
288 unsigned long init_val)
289{
290 u64 new_amr_bits = 0x0ul;
Ram Paidcf87292018-01-18 17:50:30 -0800291 u64 new_iamr_bits = 0x0ul;
Ram Pai2ddc53f2018-01-18 17:50:29 -0800292
293 if (!is_pkey_enabled(pkey))
294 return -EINVAL;
295
Ram Paidcf87292018-01-18 17:50:30 -0800296 if (init_val & PKEY_DISABLE_EXECUTE) {
297 if (!pkey_execute_disable_supported)
298 return -EINVAL;
299 new_iamr_bits |= IAMR_EX_BIT;
300 }
301 init_iamr(pkey, new_iamr_bits);
302
Ram Pai2ddc53f2018-01-18 17:50:29 -0800303 /* Set the bits we need in AMR: */
304 if (init_val & PKEY_DISABLE_ACCESS)
305 new_amr_bits |= AMR_RD_BIT | AMR_WR_BIT;
306 else if (init_val & PKEY_DISABLE_WRITE)
307 new_amr_bits |= AMR_WR_BIT;
308
309 init_amr(pkey, new_amr_bits);
310 return 0;
311}
Ram Pai06bb53b2018-01-18 17:50:31 -0800312
313void thread_pkey_regs_save(struct thread_struct *thread)
314{
315 if (static_branch_likely(&pkey_disabled))
316 return;
317
318 /*
319 * TODO: Skip saving registers if @thread hasn't used any keys yet.
320 */
321 thread->amr = read_amr();
322 thread->iamr = read_iamr();
323 thread->uamor = read_uamor();
324}
325
326void thread_pkey_regs_restore(struct thread_struct *new_thread,
327 struct thread_struct *old_thread)
328{
329 if (static_branch_likely(&pkey_disabled))
330 return;
331
Ram Pai06bb53b2018-01-18 17:50:31 -0800332 if (old_thread->amr != new_thread->amr)
333 write_amr(new_thread->amr);
334 if (old_thread->iamr != new_thread->iamr)
335 write_iamr(new_thread->iamr);
336 if (old_thread->uamor != new_thread->uamor)
337 write_uamor(new_thread->uamor);
338}
339
340void thread_pkey_regs_init(struct thread_struct *thread)
341{
342 if (static_branch_likely(&pkey_disabled))
343 return;
344
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530345 thread->amr = default_amr;
346 thread->iamr = default_iamr;
347 thread->uamor = default_uamor;
Ram Paia57a04c2018-07-17 06:51:02 -0700348
Aneesh Kumar K.Vf491fe32020-07-09 08:59:29 +0530349 write_amr(default_amr);
350 write_iamr(default_iamr);
351 write_uamor(default_uamor);
Ram Pai06bb53b2018-01-18 17:50:31 -0800352}
Ram Pai5586cf62018-01-18 17:50:32 -0800353
Ram Pai5586cf62018-01-18 17:50:32 -0800354int __execute_only_pkey(struct mm_struct *mm)
355{
Ram Paia4fcc872018-07-17 06:51:07 -0700356 return mm->context.execute_only_pkey;
Ram Pai5586cf62018-01-18 17:50:32 -0800357}
Ram Pai87bbabb2018-01-18 17:50:34 -0800358
359static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
360{
361 /* Do this check first since the vm_flags should be hot */
Anshuman Khandual6cb4d9a2020-04-10 14:33:09 -0700362 if ((vma->vm_flags & VM_ACCESS_FLAGS) != VM_EXEC)
Ram Pai87bbabb2018-01-18 17:50:34 -0800363 return false;
364
365 return (vma_pkey(vma) == vma->vm_mm->context.execute_only_pkey);
366}
367
368/*
369 * This should only be called for *plain* mprotect calls.
370 */
371int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot,
372 int pkey)
373{
374 /*
375 * If the currently associated pkey is execute-only, but the requested
Ram Paieabdb8c2018-05-04 13:01:51 -0700376 * protection is not execute-only, move it back to the default pkey.
Ram Pai87bbabb2018-01-18 17:50:34 -0800377 */
Ram Paieabdb8c2018-05-04 13:01:51 -0700378 if (vma_is_pkey_exec_only(vma) && (prot != PROT_EXEC))
Ram Pai87bbabb2018-01-18 17:50:34 -0800379 return 0;
380
381 /*
382 * The requested protection is execute-only. Hence let's use an
383 * execute-only pkey.
384 */
385 if (prot == PROT_EXEC) {
386 pkey = execute_only_pkey(vma->vm_mm);
387 if (pkey > 0)
388 return pkey;
389 }
390
391 /* Nothing to override. */
392 return vma_pkey(vma);
393}
Ram Paif2407ef2018-01-18 17:50:37 -0800394
395static bool pkey_access_permitted(int pkey, bool write, bool execute)
396{
397 int pkey_shift;
398 u64 amr;
399
Ram Paif2407ef2018-01-18 17:50:37 -0800400 pkey_shift = pkeyshift(pkey);
Aneesh Kumar K.V192b6a72020-07-12 18:50:47 +0530401 if (execute)
402 return !(read_iamr() & (IAMR_EX_BIT << pkey_shift));
Ram Paif2407ef2018-01-18 17:50:37 -0800403
Aneesh Kumar K.V192b6a72020-07-12 18:50:47 +0530404 amr = read_amr();
405 if (write)
406 return !(amr & (AMR_WR_BIT << pkey_shift));
407
408 return !(amr & (AMR_RD_BIT << pkey_shift));
Ram Paif2407ef2018-01-18 17:50:37 -0800409}
410
411bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
412{
413 if (static_branch_likely(&pkey_disabled))
414 return true;
415
416 return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute);
417}
Ram Pai11375732018-01-18 17:50:39 -0800418
419/*
420 * We only want to enforce protection keys on the current thread because we
421 * effectively have no access to AMR/IAMR for other threads or any way to tell
422 * which AMR/IAMR in a threaded process we could use.
423 *
424 * So do not enforce things if the VMA is not from the current mm, or if we are
425 * in a kernel thread.
426 */
Ram Pai11375732018-01-18 17:50:39 -0800427bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
428 bool execute, bool foreign)
429{
430 if (static_branch_likely(&pkey_disabled))
431 return true;
432 /*
433 * Do not enforce our key-permissions on a foreign vma.
434 */
435 if (foreign || vma_is_foreign(vma))
436 return true;
437
438 return pkey_access_permitted(vma_pkey(vma), write, execute);
439}
Ram Pai2cd4bd12018-12-20 12:03:30 -0800440
441void arch_dup_pkeys(struct mm_struct *oldmm, struct mm_struct *mm)
442{
443 if (static_branch_likely(&pkey_disabled))
444 return;
445
446 /* Duplicate the oldmm pkey state in mm: */
447 mm_pkey_allocation_map(mm) = mm_pkey_allocation_map(oldmm);
448 mm->context.execute_only_pkey = oldmm->context.execute_only_pkey;
449}