/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2020, Sandipan Das, IBM Corp.
 */

#ifndef _SELFTESTS_POWERPC_PKEYS_H
#define _SELFTESTS_POWERPC_PKEYS_H

#include <sys/mman.h>

#include "reg.h"
#include "utils.h"

/*
 * Older versions of libc use the Intel-specific access rights.
 * Hence, override the definitions as they might be incorrect.
 */
#undef PKEY_DISABLE_ACCESS
#define PKEY_DISABLE_ACCESS	0x3

#undef PKEY_DISABLE_WRITE
#define PKEY_DISABLE_WRITE	0x2

#undef PKEY_DISABLE_EXECUTE
#define PKEY_DISABLE_EXECUTE	0x4

/* Older versions of libc do not not define this */
#ifndef SEGV_PKUERR
#define SEGV_PKUERR	4
#endif

#define SI_PKEY_OFFSET	0x20

#define __NR_pkey_mprotect	386
#define __NR_pkey_alloc		384
#define __NR_pkey_free		385

#define PKEY_BITS_PER_PKEY	2
#define NR_PKEYS		32
#define PKEY_BITS_MASK		((1UL << PKEY_BITS_PER_PKEY) - 1)

inline unsigned long pkeyreg_get(void)
{
	return mfspr(SPRN_AMR);
}

inline void pkeyreg_set(unsigned long amr)
{
	set_amr(amr);
}

void pkey_set_rights(int pkey, unsigned long rights)
{
	unsigned long amr, shift;

	shift = (NR_PKEYS - pkey - 1) * PKEY_BITS_PER_PKEY;
	amr = pkeyreg_get();
	amr &= ~(PKEY_BITS_MASK << shift);
	amr |= (rights & PKEY_BITS_MASK) << shift;
	pkeyreg_set(amr);
}

int sys_pkey_mprotect(void *addr, size_t len, int prot, int pkey)
{
	return syscall(__NR_pkey_mprotect, addr, len, prot, pkey);
}

int sys_pkey_alloc(unsigned long flags, unsigned long rights)
{
	return syscall(__NR_pkey_alloc, flags, rights);
}

int sys_pkey_free(int pkey)
{
	return syscall(__NR_pkey_free, pkey);
}

int pkeys_unsupported(void)
{
	bool hash_mmu = false;
	int pkey;

	/* Protection keys are currently supported on Hash MMU only */
	FAIL_IF(using_hash_mmu(&hash_mmu));
	SKIP_IF(!hash_mmu);

	/* Check if the system call is supported */
	pkey = sys_pkey_alloc(0, 0);
	SKIP_IF(pkey < 0);
	sys_pkey_free(pkey);

	return 0;
}

int siginfo_pkey(siginfo_t *si)
{
	/*
	 * In older versions of libc, siginfo_t does not have si_pkey as
	 * a member.
	 */
#ifdef si_pkey
	return si->si_pkey;
#else
	return *((int *)(((char *) si) + SI_PKEY_OFFSET));
#endif
}

#define pkey_rights(r) ({						\
	static char buf[4] = "rwx";					\
	unsigned int amr_bits;						\
	if ((r) & PKEY_DISABLE_EXECUTE)					\
		buf[2] = '-';						\
	amr_bits = (r) & PKEY_BITS_MASK;				\
	if (amr_bits & PKEY_DISABLE_WRITE)				\
		buf[1] = '-';						\
	if (amr_bits & PKEY_DISABLE_ACCESS & ~PKEY_DISABLE_WRITE)	\
		buf[0] = '-';						\
	buf;								\
})

unsigned long next_pkey_rights(unsigned long rights)
{
	if (rights == PKEY_DISABLE_ACCESS)
		return PKEY_DISABLE_EXECUTE;
	else if (rights == (PKEY_DISABLE_ACCESS | PKEY_DISABLE_EXECUTE))
		return 0;

	if ((rights & PKEY_BITS_MASK) == 0)
		rights |= PKEY_DISABLE_WRITE;
	else if ((rights & PKEY_BITS_MASK) == PKEY_DISABLE_WRITE)
		rights |= PKEY_DISABLE_ACCESS;

	return rights;
}

#endif /* _SELFTESTS_POWERPC_PKEYS_H */
