cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kup-booke.h (2023B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ASM_POWERPC_KUP_BOOKE_H_
      3#define _ASM_POWERPC_KUP_BOOKE_H_
      4
      5#include <asm/bug.h>
      6
      7#ifdef CONFIG_PPC_KUAP
      8
      9#ifdef __ASSEMBLY__
     10
     11.macro kuap_check_amr	gpr1, gpr2
     12.endm
     13
     14#else
     15
     16#include <linux/jump_label.h>
     17#include <linux/sched.h>
     18
     19#include <asm/reg.h>
     20
     21extern struct static_key_false disable_kuap_key;
     22
     23static __always_inline bool kuap_is_disabled(void)
     24{
     25	return static_branch_unlikely(&disable_kuap_key);
     26}
     27
     28static inline void __kuap_lock(void)
     29{
     30	mtspr(SPRN_PID, 0);
     31	isync();
     32}
     33
     34static inline void __kuap_save_and_lock(struct pt_regs *regs)
     35{
     36	regs->kuap = mfspr(SPRN_PID);
     37	mtspr(SPRN_PID, 0);
     38	isync();
     39}
     40
     41static inline void kuap_user_restore(struct pt_regs *regs)
     42{
     43	if (kuap_is_disabled())
     44		return;
     45
     46	mtspr(SPRN_PID, current->thread.pid);
     47
     48	/* Context synchronisation is performed by rfi */
     49}
     50
     51static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
     52{
     53	if (regs->kuap)
     54		mtspr(SPRN_PID, current->thread.pid);
     55
     56	/* Context synchronisation is performed by rfi */
     57}
     58
     59static inline unsigned long __kuap_get_and_assert_locked(void)
     60{
     61	unsigned long kuap = mfspr(SPRN_PID);
     62
     63	if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
     64		WARN_ON_ONCE(kuap);
     65
     66	return kuap;
     67}
     68
     69static inline void __allow_user_access(void __user *to, const void __user *from,
     70				       unsigned long size, unsigned long dir)
     71{
     72	mtspr(SPRN_PID, current->thread.pid);
     73	isync();
     74}
     75
     76static inline void __prevent_user_access(unsigned long dir)
     77{
     78	mtspr(SPRN_PID, 0);
     79	isync();
     80}
     81
     82static inline unsigned long __prevent_user_access_return(void)
     83{
     84	unsigned long flags = mfspr(SPRN_PID);
     85
     86	mtspr(SPRN_PID, 0);
     87	isync();
     88
     89	return flags;
     90}
     91
     92static inline void __restore_user_access(unsigned long flags)
     93{
     94	if (flags) {
     95		mtspr(SPRN_PID, current->thread.pid);
     96		isync();
     97	}
     98}
     99
    100static inline bool
    101__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
    102{
    103	return !regs->kuap;
    104}
    105
    106#endif /* !__ASSEMBLY__ */
    107
    108#endif /* CONFIG_PPC_KUAP */
    109
    110#endif /* _ASM_POWERPC_KUP_BOOKE_H_ */