1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H
3 #define _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H
5 #include <linux/const.h>
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
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
)
19 END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP
, 67)
23 .macro kuap_check_amr gpr1
, gpr2
24 #ifdef CONFIG_PPC_KUAP_DEBUG
25 BEGIN_MMU_FTR_SECTION_NESTED(67)
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)
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)
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
47 // We don't isync here because we very recently entered via rfid
51 END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP
, 67)
55 #else /* !__ASSEMBLY__ */
57 #ifdef CONFIG_PPC_KUAP
62 * We support individually allowing read or write, but we don't support nesting
63 * because that would require an expensive read/modify write of the AMR.
66 static inline void set_kuap(unsigned long value
)
68 if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP
))
72 * ISA v3.0B says we need a CSI (Context Synchronising Instruction) both
73 * before and after the move to AMR. See table 6 on page 1134.
76 mtspr(SPRN_AMR
, value
);
80 static inline void allow_user_access(void __user
*to
, const void __user
*from
,
83 // This is written so we can resolve to a single case at build time
84 if (__builtin_constant_p(to
) && to
== NULL
)
85 set_kuap(AMR_KUAP_BLOCK_WRITE
);
86 else if (__builtin_constant_p(from
) && from
== NULL
)
87 set_kuap(AMR_KUAP_BLOCK_READ
);
92 static inline void prevent_user_access(void __user
*to
, const void __user
*from
,
95 set_kuap(AMR_KUAP_BLOCKED
);
98 static inline bool bad_kuap_fault(struct pt_regs
*regs
, bool is_write
)
100 return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP
) &&
101 (regs
->kuap
& (is_write
? AMR_KUAP_BLOCK_WRITE
: AMR_KUAP_BLOCK_READ
)),
102 "Bug: %s fault blocked by AMR!", is_write
? "Write" : "Read");
104 #endif /* CONFIG_PPC_KUAP */
106 #endif /* __ASSEMBLY__ */
108 #endif /* _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H */