/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _PKEYS_HELPER_H
#define _PKEYS_HELPER_H
#define _GNU_SOURCE
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <signal.h>
#include <assert.h>
#include <stdlib.h>
#include <ucontext.h>
#include <sys/mman.h>

#define NR_PKEYS 16
#define PKRU_BITS_PER_PKEY 2

#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL 0
#endif
#define DPRINT_IN_SIGNAL_BUF_SIZE 4096
extern int dprint_in_signal;
extern char dprint_in_signal_buffer[DPRINT_IN_SIGNAL_BUF_SIZE];
static inline void sigsafe_printf(const char *format, ...)
{
	va_list ap;

	va_start(ap, format);
	if (!dprint_in_signal) {
		vprintf(format, ap);
	} else {
		int len = vsnprintf(dprint_in_signal_buffer,
				    DPRINT_IN_SIGNAL_BUF_SIZE,
				    format, ap);
		/*
		 * len is amount that would have been printed,
		 * but actual write is truncated at BUF_SIZE.
		 */
		if (len > DPRINT_IN_SIGNAL_BUF_SIZE)
			len = DPRINT_IN_SIGNAL_BUF_SIZE;
		write(1, dprint_in_signal_buffer, len);
	}
	va_end(ap);
}
#define dprintf_level(level, args...) do {	\
	if (level <= DEBUG_LEVEL)		\
		sigsafe_printf(args);		\
	fflush(NULL);				\
} while (0)
#define dprintf0(args...) dprintf_level(0, args)
#define dprintf1(args...) dprintf_level(1, args)
#define dprintf2(args...) dprintf_level(2, args)
#define dprintf3(args...) dprintf_level(3, args)
#define dprintf4(args...) dprintf_level(4, args)

extern unsigned int shadow_pkru;
static inline unsigned int __rdpkru(void)
{
	unsigned int eax, edx;
	unsigned int ecx = 0;
	unsigned int pkru;

	asm volatile(".byte 0x0f,0x01,0xee\n\t"
		     : "=a" (eax), "=d" (edx)
		     : "c" (ecx));
	pkru = eax;
	return pkru;
}

static inline unsigned int _rdpkru(int line)
{
	unsigned int pkru = __rdpkru();

	dprintf4("rdpkru(line=%d) pkru: %x shadow: %x\n",
			line, pkru, shadow_pkru);
	assert(pkru == shadow_pkru);

	return pkru;
}

#define rdpkru() _rdpkru(__LINE__)

static inline void __wrpkru(unsigned int pkru)
{
	unsigned int eax = pkru;
	unsigned int ecx = 0;
	unsigned int edx = 0;

	dprintf4("%s() changing %08x to %08x\n", __func__, __rdpkru(), pkru);
	asm volatile(".byte 0x0f,0x01,0xef\n\t"
		     : : "a" (eax), "c" (ecx), "d" (edx));
	assert(pkru == __rdpkru());
}

static inline void wrpkru(unsigned int pkru)
{
	dprintf4("%s() changing %08x to %08x\n", __func__, __rdpkru(), pkru);
	/* will do the shadow check for us: */
	rdpkru();
	__wrpkru(pkru);
	shadow_pkru = pkru;
	dprintf4("%s(%08x) pkru: %08x\n", __func__, pkru, __rdpkru());
}

/*
 * These are technically racy. since something could
 * change PKRU between the read and the write.
 */
static inline void __pkey_access_allow(int pkey, int do_allow)
{
	unsigned int pkru = rdpkru();
	int bit = pkey * 2;

	if (do_allow)
		pkru &= (1<<bit);
	else
		pkru |= (1<<bit);

	dprintf4("pkru now: %08x\n", rdpkru());
	wrpkru(pkru);
}

static inline void __pkey_write_allow(int pkey, int do_allow_write)
{
	long pkru = rdpkru();
	int bit = pkey * 2 + 1;

	if (do_allow_write)
		pkru &= (1<<bit);
	else
		pkru |= (1<<bit);

	wrpkru(pkru);
	dprintf4("pkru now: %08x\n", rdpkru());
}

#define PROT_PKEY0     0x10            /* protection key value (bit 0) */
#define PROT_PKEY1     0x20            /* protection key value (bit 1) */
#define PROT_PKEY2     0x40            /* protection key value (bit 2) */
#define PROT_PKEY3     0x80            /* protection key value (bit 3) */

#define PAGE_SIZE 4096
#define MB	(1<<20)

static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
		unsigned int *ecx, unsigned int *edx)
{
	/* ecx is often an input as well as an output. */
	asm volatile(
		"cpuid;"
		: "=a" (*eax),
		  "=b" (*ebx),
		  "=c" (*ecx),
		  "=d" (*edx)
		: "0" (*eax), "2" (*ecx));
}

/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
#define X86_FEATURE_PKU        (1<<3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE      (1<<4) /* OS Protection Keys Enable */

static inline int cpu_has_pku(void)
{
	unsigned int eax;
	unsigned int ebx;
	unsigned int ecx;
	unsigned int edx;

	eax = 0x7;
	ecx = 0x0;
	__cpuid(&eax, &ebx, &ecx, &edx);

	if (!(ecx & X86_FEATURE_PKU)) {
		dprintf2("cpu does not have PKU\n");
		return 0;
	}
	if (!(ecx & X86_FEATURE_OSPKE)) {
		dprintf2("cpu does not have OSPKE\n");
		return 0;
	}
	return 1;
}

#define XSTATE_PKRU_BIT	(9)
#define XSTATE_PKRU	0x200

int pkru_xstate_offset(void)
{
	unsigned int eax;
	unsigned int ebx;
	unsigned int ecx;
	unsigned int edx;
	int xstate_offset;
	int xstate_size;
	unsigned long XSTATE_CPUID = 0xd;
	int leaf;

	/* assume that XSTATE_PKRU is set in XCR0 */
	leaf = XSTATE_PKRU_BIT;
	{
		eax = XSTATE_CPUID;
		ecx = leaf;
		__cpuid(&eax, &ebx, &ecx, &edx);

		if (leaf == XSTATE_PKRU_BIT) {
			xstate_offset = ebx;
			xstate_size = eax;
		}
	}

	if (xstate_size == 0) {
		printf("could not find size/offset of PKRU in xsave state\n");
		return 0;
	}

	return xstate_offset;
}

#endif /* _PKEYS_HELPER_H */
