This source file includes following definitions.
- BEGIN_MMU_FTR_SECTION_NESTED
- allow_user_access
- prevent_user_access
- bad_kuap_fault
1
2 #ifndef _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H
3 #define _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H
4
5 #include <linux/const.h>
6
7 #define AMR_KUAP_BLOCK_READ UL(0x4000000000000000)
8 #define AMR_KUAP_BLOCK_WRITE UL(0x8000000000000000)
9 #define AMR_KUAP_BLOCKED (AMR_KUAP_BLOCK_READ | AMR_KUAP_BLOCK_WRITE)
10 #define AMR_KUAP_SHIFT 62
11
12 #ifdef __ASSEMBLY__
13
14 .macro kuap_restore_amr gpr
15 #ifdef CONFIG_PPC_KUAP
16 BEGIN_MMU_FTR_SECTION_NESTED(67)
17 ld \gpr, STACK_REGS_KUAP(r1)
18 mtspr SPRN_AMR, \gpr
19 END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67)
20 #endif
21 .endm
22
23 .macro kuap_check_amr gpr1, gpr2
24 #ifdef CONFIG_PPC_KUAP_DEBUG
25 BEGIN_MMU_FTR_SECTION_NESTED(67)
26 mfspr \gpr1, SPRN_AMR
27 li \gpr2, (AMR_KUAP_BLOCKED >> AMR_KUAP_SHIFT)
28 sldi \gpr2, \gpr2, AMR_KUAP_SHIFT
29 999: tdne \gpr1, \gpr2
30 EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE)
31 END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67)
32 #endif
33 .endm
34
35 .macro kuap_save_amr_and_lock gpr1, gpr2, use_cr, msr_pr_cr
36 #ifdef CONFIG_PPC_KUAP
37 BEGIN_MMU_FTR_SECTION_NESTED(67)
38 .ifnb \msr_pr_cr
39 bne \msr_pr_cr, 99f
40 .endif
41 mfspr \gpr1, SPRN_AMR
42 std \gpr1, STACK_REGS_KUAP(r1)
43 li \gpr2, (AMR_KUAP_BLOCKED >> AMR_KUAP_SHIFT)
44 sldi \gpr2, \gpr2, AMR_KUAP_SHIFT
45 cmpd \use_cr, \gpr1, \gpr2
46 beq \use_cr, 99f
47
48 mtspr SPRN_AMR, \gpr2
49 isync
50 99:
51 END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67)
52 #endif
53 .endm
54
55 #else
56
57 #ifdef CONFIG_PPC_KUAP
58
59 #include <asm/reg.h>
60
61
62
63
64
65
66 static inline void set_kuap(unsigned long value)
67 {
68 if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP))
69 return;
70
71
72
73
74
75 isync();
76 mtspr(SPRN_AMR, value);
77 isync();
78 }
79
80 static __always_inline void allow_user_access(void __user *to, const void __user *from,
81 unsigned long size, unsigned long dir)
82 {
83
84 BUILD_BUG_ON(!__builtin_constant_p(dir));
85 if (dir == KUAP_READ)
86 set_kuap(AMR_KUAP_BLOCK_WRITE);
87 else if (dir == KUAP_WRITE)
88 set_kuap(AMR_KUAP_BLOCK_READ);
89 else
90 set_kuap(0);
91 }
92
93 static inline void prevent_user_access(void __user *to, const void __user *from,
94 unsigned long size, unsigned long dir)
95 {
96 set_kuap(AMR_KUAP_BLOCKED);
97 }
98
99 static inline bool
100 bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
101 {
102 return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) &&
103 (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)),
104 "Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read");
105 }
106 #endif
107
108 #endif
109
110 #endif