Skip to content

Commit 589944b

Browse files
Ram Paitorvalds
authored andcommitted
selftests/vm/pkeys: introduce powerpc support
This makes use of the abstractions added earlier and introduces support for powerpc. For powerpc, after receiving the SIGSEGV, the signal handler must explicitly restore access permissions for the faulting pkey to allow the test to continue. As this makes use of pkey_access_allow(), all of its dependencies and other similar functions have been moved ahead of the signal handler. [[email protected]: fix powerpc access right updates] Link: http://lkml.kernel.org/r/5f65cf37be993760de8112a88da194e3ccbb2bf8.1588959697.git.sandipan@linux.ibm.com Signed-off-by: Ram Pai <[email protected]> Signed-off-by: Sandipan Das <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Acked-by: Dave Hansen <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Florian Weimer <[email protected]> Cc: "Desnes A. Nunes do Rosario" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Thiago Jung Bauermann <[email protected]> Cc: "Aneesh Kumar K.V" <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Michal Suchanek <[email protected]> Cc: Shuah Khan <[email protected]> Link: http://lkml.kernel.org/r/b121e9fd33789ed9195276e32fe4e80bb6b88a31.1585646528.git.sandipan@linux.ibm.com Signed-off-by: Linus Torvalds <[email protected]>
1 parent 604c496 commit 589944b

File tree

3 files changed

+234
-128
lines changed

3 files changed

+234
-128
lines changed

tools/testing/selftests/vm/pkey-helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ void expected_pkey_fault(int pkey);
7979

8080
#if defined(__i386__) || defined(__x86_64__) /* arch */
8181
#include "pkey-x86.h"
82+
#elif defined(__powerpc64__) /* arch */
83+
#include "pkey-powerpc.h"
8284
#else /* arch */
8385
#error Architecture not supported
8486
#endif /* arch */
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef _PKEYS_POWERPC_H
4+
#define _PKEYS_POWERPC_H
5+
6+
#ifndef SYS_mprotect_key
7+
# define SYS_mprotect_key 386
8+
#endif
9+
#ifndef SYS_pkey_alloc
10+
# define SYS_pkey_alloc 384
11+
# define SYS_pkey_free 385
12+
#endif
13+
#define REG_IP_IDX PT_NIP
14+
#define REG_TRAPNO PT_TRAP
15+
#define gregs gp_regs
16+
#define fpregs fp_regs
17+
#define si_pkey_offset 0x20
18+
19+
#ifndef PKEY_DISABLE_ACCESS
20+
# define PKEY_DISABLE_ACCESS 0x3 /* disable read and write */
21+
#endif
22+
23+
#ifndef PKEY_DISABLE_WRITE
24+
# define PKEY_DISABLE_WRITE 0x2
25+
#endif
26+
27+
#define NR_PKEYS 32
28+
#define NR_RESERVED_PKEYS_4K 27 /* pkey-0, pkey-1, exec-only-pkey
29+
and 24 other keys that cannot be
30+
represented in the PTE */
31+
#define NR_RESERVED_PKEYS_64K 3 /* pkey-0, pkey-1 and exec-only-pkey */
32+
#define PKEY_BITS_PER_PKEY 2
33+
#define HPAGE_SIZE (1UL << 24)
34+
#define PAGE_SIZE (1UL << 16)
35+
36+
static inline u32 pkey_bit_position(int pkey)
37+
{
38+
return (NR_PKEYS - pkey - 1) * PKEY_BITS_PER_PKEY;
39+
}
40+
41+
static inline u64 __read_pkey_reg(void)
42+
{
43+
u64 pkey_reg;
44+
45+
asm volatile("mfspr %0, 0xd" : "=r" (pkey_reg));
46+
47+
return pkey_reg;
48+
}
49+
50+
static inline void __write_pkey_reg(u64 pkey_reg)
51+
{
52+
u64 amr = pkey_reg;
53+
54+
dprintf4("%s() changing %016llx to %016llx\n",
55+
__func__, __read_pkey_reg(), pkey_reg);
56+
57+
asm volatile("isync; mtspr 0xd, %0; isync"
58+
: : "r" ((unsigned long)(amr)) : "memory");
59+
60+
dprintf4("%s() pkey register after changing %016llx to %016llx\n",
61+
__func__, __read_pkey_reg(), pkey_reg);
62+
}
63+
64+
static inline int cpu_has_pku(void)
65+
{
66+
return 1;
67+
}
68+
69+
static inline int get_arch_reserved_keys(void)
70+
{
71+
if (sysconf(_SC_PAGESIZE) == 4096)
72+
return NR_RESERVED_PKEYS_4K;
73+
else
74+
return NR_RESERVED_PKEYS_64K;
75+
}
76+
77+
void expect_fault_on_read_execonly_key(void *p1, int pkey)
78+
{
79+
/*
80+
* powerpc does not allow userspace to change permissions of exec-only
81+
* keys since those keys are not allocated by userspace. The signal
82+
* handler wont be able to reset the permissions, which means the code
83+
* will infinitely continue to segfault here.
84+
*/
85+
return;
86+
}
87+
88+
/* 4-byte instructions * 16384 = 64K page */
89+
#define __page_o_noops() asm(".rept 16384 ; nop; .endr")
90+
91+
#endif /* _PKEYS_POWERPC_H */

0 commit comments

Comments
 (0)