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.h (4899B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ASM_POWERPC_KUP_H_
      3#define _ASM_POWERPC_KUP_H_
      4
      5#define KUAP_READ	1
      6#define KUAP_WRITE	2
      7#define KUAP_READ_WRITE	(KUAP_READ | KUAP_WRITE)
      8
      9#ifdef CONFIG_PPC_BOOK3S_64
     10#include <asm/book3s/64/kup.h>
     11#endif
     12
     13#ifdef CONFIG_PPC_8xx
     14#include <asm/nohash/32/kup-8xx.h>
     15#endif
     16
     17#ifdef CONFIG_BOOKE_OR_40x
     18#include <asm/nohash/kup-booke.h>
     19#endif
     20
     21#ifdef CONFIG_PPC_BOOK3S_32
     22#include <asm/book3s/32/kup.h>
     23#endif
     24
     25#ifdef __ASSEMBLY__
     26#ifndef CONFIG_PPC_KUAP
     27.macro kuap_check_amr	gpr1, gpr2
     28.endm
     29
     30#endif
     31
     32#else /* !__ASSEMBLY__ */
     33
     34extern bool disable_kuep;
     35extern bool disable_kuap;
     36
     37#include <linux/pgtable.h>
     38
     39void setup_kup(void);
     40void setup_kuep(bool disabled);
     41
     42#ifdef CONFIG_PPC_KUAP
     43void setup_kuap(bool disabled);
     44#else
     45static inline void setup_kuap(bool disabled) { }
     46
     47static __always_inline bool kuap_is_disabled(void) { return true; }
     48
     49static inline bool
     50__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
     51{
     52	return false;
     53}
     54
     55static inline void __kuap_lock(void) { }
     56static inline void __kuap_save_and_lock(struct pt_regs *regs) { }
     57static inline void kuap_user_restore(struct pt_regs *regs) { }
     58static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
     59
     60static inline unsigned long __kuap_get_and_assert_locked(void)
     61{
     62	return 0;
     63}
     64
     65/*
     66 * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
     67 * the L1D cache after user accesses. Only include the empty stubs for other
     68 * platforms.
     69 */
     70#ifndef CONFIG_PPC_BOOK3S_64
     71static inline void __allow_user_access(void __user *to, const void __user *from,
     72				       unsigned long size, unsigned long dir) { }
     73static inline void __prevent_user_access(unsigned long dir) { }
     74static inline unsigned long __prevent_user_access_return(void) { return 0UL; }
     75static inline void __restore_user_access(unsigned long flags) { }
     76#endif /* CONFIG_PPC_BOOK3S_64 */
     77#endif /* CONFIG_PPC_KUAP */
     78
     79static __always_inline bool
     80bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
     81{
     82	if (kuap_is_disabled())
     83		return false;
     84
     85	return __bad_kuap_fault(regs, address, is_write);
     86}
     87
     88static __always_inline void kuap_assert_locked(void)
     89{
     90	if (kuap_is_disabled())
     91		return;
     92
     93	if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
     94		__kuap_get_and_assert_locked();
     95}
     96
     97static __always_inline void kuap_lock(void)
     98{
     99	if (kuap_is_disabled())
    100		return;
    101
    102	__kuap_lock();
    103}
    104
    105static __always_inline void kuap_save_and_lock(struct pt_regs *regs)
    106{
    107	if (kuap_is_disabled())
    108		return;
    109
    110	__kuap_save_and_lock(regs);
    111}
    112
    113static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr)
    114{
    115	if (kuap_is_disabled())
    116		return;
    117
    118	__kuap_kernel_restore(regs, amr);
    119}
    120
    121static __always_inline unsigned long kuap_get_and_assert_locked(void)
    122{
    123	if (kuap_is_disabled())
    124		return 0;
    125
    126	return __kuap_get_and_assert_locked();
    127}
    128
    129#ifndef CONFIG_PPC_BOOK3S_64
    130static __always_inline void allow_user_access(void __user *to, const void __user *from,
    131				     unsigned long size, unsigned long dir)
    132{
    133	if (kuap_is_disabled())
    134		return;
    135
    136	__allow_user_access(to, from, size, dir);
    137}
    138
    139static __always_inline void prevent_user_access(unsigned long dir)
    140{
    141	if (kuap_is_disabled())
    142		return;
    143
    144	__prevent_user_access(dir);
    145}
    146
    147static __always_inline unsigned long prevent_user_access_return(void)
    148{
    149	if (kuap_is_disabled())
    150		return 0;
    151
    152	return __prevent_user_access_return();
    153}
    154
    155static __always_inline void restore_user_access(unsigned long flags)
    156{
    157	if (kuap_is_disabled())
    158		return;
    159
    160	__restore_user_access(flags);
    161}
    162#endif /* CONFIG_PPC_BOOK3S_64 */
    163
    164static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
    165{
    166	barrier_nospec();
    167	allow_user_access(NULL, from, size, KUAP_READ);
    168}
    169
    170static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
    171{
    172	allow_user_access(to, NULL, size, KUAP_WRITE);
    173}
    174
    175static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
    176						  unsigned long size)
    177{
    178	barrier_nospec();
    179	allow_user_access(to, from, size, KUAP_READ_WRITE);
    180}
    181
    182static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
    183{
    184	prevent_user_access(KUAP_READ);
    185}
    186
    187static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
    188{
    189	prevent_user_access(KUAP_WRITE);
    190}
    191
    192static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
    193						    unsigned long size)
    194{
    195	prevent_user_access(KUAP_READ_WRITE);
    196}
    197
    198static __always_inline void prevent_current_access_user(void)
    199{
    200	prevent_user_access(KUAP_READ_WRITE);
    201}
    202
    203static __always_inline void prevent_current_read_from_user(void)
    204{
    205	prevent_user_access(KUAP_READ);
    206}
    207
    208static __always_inline void prevent_current_write_to_user(void)
    209{
    210	prevent_user_access(KUAP_WRITE);
    211}
    212
    213#endif /* !__ASSEMBLY__ */
    214
    215#endif /* _ASM_POWERPC_KUAP_H_ */