/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_BOOK3S_32_KUP_H
#define _ASM_POWERPC_BOOK3S_32_KUP_H

#include <asm/bug.h>
#include <asm/book3s/32/mmu-hash.h>
#include <asm/mmu.h>
#include <asm/synch.h>

#ifndef __ASSEMBLY__

#include <linux/jump_label.h>

extern struct static_key_false disable_kuap_key;
extern struct static_key_false disable_kuep_key;

static __always_inline bool kuap_is_disabled(void)
{
	return !IS_ENABLED(CONFIG_PPC_KUAP) || static_branch_unlikely(&disable_kuap_key);
}

static __always_inline bool kuep_is_disabled(void)
{
	return !IS_ENABLED(CONFIG_PPC_KUEP) || static_branch_unlikely(&disable_kuep_key);
}

static inline void kuep_lock(void)
{
	if (kuep_is_disabled())
		return;

	update_user_segments(mfsr(0) | SR_NX);
	/*
	 * This isync() shouldn't be necessary as the kernel is not excepted to
	 * run any instruction in userspace soon after the update of segments,
	 * but hash based cores (at least G3) seem to exhibit a random
	 * behaviour when the 'isync' is not there. 603 cores don't have this
	 * behaviour so don't do the 'isync' as it saves several CPU cycles.
	 */
	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
		isync();	/* Context sync required after mtsr() */
}

static inline void kuep_unlock(void)
{
	if (kuep_is_disabled())
		return;

	update_user_segments(mfsr(0) & ~SR_NX);
	/*
	 * This isync() shouldn't be necessary as a 'rfi' will soon be executed
	 * to return to userspace, but hash based cores (at least G3) seem to
	 * exhibit a random behaviour when the 'isync' is not there. 603 cores
	 * don't have this behaviour so don't do the 'isync' as it saves several
	 * CPU cycles.
	 */
	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
		isync();	/* Context sync required after mtsr() */
}

#ifdef CONFIG_PPC_KUAP

#include <linux/sched.h>

#define KUAP_NONE	(~0UL)
#define KUAP_ALL	(~1UL)

static inline void kuap_lock_one(unsigned long addr)
{
	mtsr(mfsr(addr) | SR_KS, addr);
	isync();	/* Context sync required after mtsr() */
}

static inline void kuap_unlock_one(unsigned long addr)
{
	mtsr(mfsr(addr) & ~SR_KS, addr);
	isync();	/* Context sync required after mtsr() */
}

static inline void kuap_lock_all(void)
{
	update_user_segments(mfsr(0) | SR_KS);
	isync();	/* Context sync required after mtsr() */
}

static inline void kuap_unlock_all(void)
{
	update_user_segments(mfsr(0) & ~SR_KS);
	isync();	/* Context sync required after mtsr() */
}

void kuap_lock_all_ool(void);
void kuap_unlock_all_ool(void);

static inline void kuap_lock(unsigned long addr, bool ool)
{
	if (likely(addr != KUAP_ALL))
		kuap_lock_one(addr);
	else if (!ool)
		kuap_lock_all();
	else
		kuap_lock_all_ool();
}

static inline void kuap_unlock(unsigned long addr, bool ool)
{
	if (likely(addr != KUAP_ALL))
		kuap_unlock_one(addr);
	else if (!ool)
		kuap_unlock_all();
	else
		kuap_unlock_all_ool();
}

static inline void kuap_save_and_lock(struct pt_regs *regs)
{
	unsigned long kuap = current->thread.kuap;

	if (kuap_is_disabled())
		return;

	regs->kuap = kuap;
	if (unlikely(kuap == KUAP_NONE))
		return;

	current->thread.kuap = KUAP_NONE;
	kuap_lock(kuap, false);
}

static inline void kuap_user_restore(struct pt_regs *regs)
{
}

static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
{
	if (kuap_is_disabled())
		return;

	current->thread.kuap = regs->kuap;

	kuap_unlock(regs->kuap, false);
}

static inline unsigned long kuap_get_and_assert_locked(void)
{
	unsigned long kuap = current->thread.kuap;

	if (kuap_is_disabled())
		return KUAP_NONE;

	WARN_ON_ONCE(IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && kuap != KUAP_NONE);

	return kuap;
}

static inline void kuap_assert_locked(void)
{
	kuap_get_and_assert_locked();
}

static __always_inline void allow_user_access(void __user *to, const void __user *from,
					      u32 size, unsigned long dir)
{
	if (kuap_is_disabled())
		return;

	BUILD_BUG_ON(!__builtin_constant_p(dir));

	if (!(dir & KUAP_WRITE))
		return;

	current->thread.kuap = (__force u32)to;
	kuap_unlock_one((__force u32)to);
}

static __always_inline void prevent_user_access(unsigned long dir)
{
	u32 kuap = current->thread.kuap;

	if (kuap_is_disabled())
		return;

	BUILD_BUG_ON(!__builtin_constant_p(dir));

	if (!(dir & KUAP_WRITE))
		return;

	current->thread.kuap = KUAP_NONE;
	kuap_lock(kuap, true);
}

static inline unsigned long prevent_user_access_return(void)
{
	unsigned long flags = current->thread.kuap;

	if (kuap_is_disabled())
		return KUAP_NONE;

	if (flags != KUAP_NONE) {
		current->thread.kuap = KUAP_NONE;
		kuap_lock(flags, true);
	}

	return flags;
}

static inline void restore_user_access(unsigned long flags)
{
	if (kuap_is_disabled())
		return;

	if (flags != KUAP_NONE) {
		current->thread.kuap = flags;
		kuap_unlock(flags, true);
	}
}

static inline bool
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
{
	unsigned long kuap = regs->kuap;

	if (kuap_is_disabled())
		return false;

	if (!is_write || kuap == KUAP_ALL)
		return false;
	if (kuap == KUAP_NONE)
		return true;

	/* If faulting address doesn't match unlocked segment, unlock all */
	if ((kuap ^ address) & 0xf0000000)
		regs->kuap = KUAP_ALL;

	return false;
}

#endif /* CONFIG_PPC_KUAP */

#endif /* __ASSEMBLY__ */

#endif /* _ASM_POWERPC_BOOK3S_32_KUP_H */
