/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Tests guarded storage support.
 *
 * Copyright 2018 IBM Corp.
 *
 * Authors:
 *    Martin Schwidefsky <schwidefsky@de.ibm.com>
 *    Janosch Frank <frankja@de.ibm.com>
 */
#include <libcflat.h>
#include <asm/page.h>
#include <asm/facility.h>
#include <asm/interrupt.h>
#include <asm-generic/barrier.h>

struct gs_cb {
	uint64_t reserved;
	uint64_t gsd;
	uint64_t gssm;
	uint64_t gs_epl_a;
};

struct gs_epl {
	uint8_t pad1;
	union {
		uint8_t gs_eam;
		struct {
			uint8_t		: 6;
			uint8_t e	: 1;
			uint8_t b	: 1;
		};
	};
	union {
		uint8_t gs_eci;
		struct {
			uint8_t tx	: 1;
			uint8_t cx	: 1;
			uint8_t		: 5;
			uint8_t in	: 1;
		};
	};
	union {
		uint8_t gs_eai;
		struct {
			uint8_t		: 1;
			uint8_t t	: 1;
			uint8_t as	: 2;
			uint8_t ar	: 4;
		};
	};
	uint32_t pad2;
	uint64_t gs_eha;
	uint64_t gs_eia;
	uint64_t gs_eoa;
	uint64_t gs_eir;
	uint64_t gs_era;
};

static volatile int guarded = 0;
static struct gs_cb gs_cb;
static struct gs_epl gs_epl;
static unsigned long gs_area = 0x2000000;

void gs_handler(struct gs_cb *this_cb);

static inline void load_gs_cb(struct gs_cb *gs_cb)
{
	asm volatile(".insn rxy,0xe3000000004d,0,%0" : : "Q" (*gs_cb));
}

static inline void store_gs_cb(struct gs_cb *gs_cb)
{
	asm volatile(".insn rxy,0xe30000000049,0,%0" : : "Q" (*gs_cb));
}

static inline unsigned long load_guarded(unsigned long *p)
{
	unsigned long v;

	asm(".insn rxy,0xe3000000004c, %0,%1"
	    : "=d" (v)
	    : "m" (*p)
	    : "r14", "memory");
	return v;
}

/* guarded-storage event handler and finally it calls gs_handler */
extern void gs_handler_asm(void);
	asm(".globl gs_handler_asm\n"
	    "gs_handler_asm:\n"
	    "	    lgr	    %r14,%r15\n" 		/* Save current stack address in r14 */
	    "	    aghi    %r15,-320\n" 		/* Allocate stack frame */
	    "	    stmg    %r0,%r13,192(%r15)\n" 	/* Store regs to save area */
	    "	    stg	    %r14,312(%r15)\n"
	    "	    la	    %r2,160(%r15)\n" 		/* Store gscb address in this_cb */
	    "	    .insn   rxy,0xe30000000049,0,160(%r15)\n" /* stgsc */
	    "	    lg	    %r14,24(%r2)\n" 		/* Get GSEPLA from GSCB*/
	    "	    lg	    %r14,40(%r14)\n" 		/* Get GSERA from GSEPL*/
	    "	    stg	    %r14,304(%r15)\n" 		/* Store GSERA in r14 of reg save area */
	    "	    brasl   %r14,gs_handler\n" 		/* Jump to gs_handler */
	    "	    lmg	    %r0,%r15,192(%r15)\n" 	/* Restore regs */
	    "	    aghi    %r14, 6\n" 			/* Add lgg instr len to GSERA */
	    "	    br	    %r14\n" 			/* Jump to next instruction after lgg */
	    "	    .size gs_handler_asm,.-gs_handler_asm\n");

void gs_handler(struct gs_cb *this_cb)
{
	guarded = 1;
	struct gs_epl *gs_epl = (struct gs_epl *) this_cb->gs_epl_a;
	printf("gs_handler called for %016lx at %016lx\n",
	       gs_epl->gs_eir, gs_epl->gs_eia);
}

/* Test if load guarded gets intercepted. */
static void test_load(void)
{
	unsigned long v;

	guarded = 0;
	v = load_guarded(&gs_area);
	report(guarded, "load guarded %ld", v);
	guarded = 0;
}

/* Test gs instructions without enablement resulting in an exception */
static void test_special(void)
{
	report_prefix_push("disabled gs");
	report_prefix_push("load gs");
	expect_pgm_int();
	load_gs_cb(&gs_cb);
	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
	report_prefix_pop();

	report_prefix_push("store gs");
	expect_pgm_int();
	store_gs_cb(&gs_cb);
	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
	report_prefix_pop();

	report_prefix_pop();
}

static void init(void)
{
	/* Enable control bit for gs */
	ctl_set_bit(2, 4);

	/* Setup gs registers to guard the gs_area */
	gs_cb.gsd = gs_area | 25;

	/* Check all 512kb slots for events */
	gs_cb.gssm = 0xffffffffffffffffULL;
	gs_cb.gs_epl_a =  (unsigned long) &gs_epl;

	/* Register handler */
	gs_epl.gs_eha = (unsigned long) gs_handler_asm;
	load_gs_cb(&gs_cb);
}

int main(void)
{
	bool has_gs = test_facility(133);

	report_prefix_push("gs");
	if (!has_gs) {
		report_skip("Guarded storage is not available");
		goto done;
	}

	test_special();
	init();
	test_load();

done:
	report_prefix_pop();
	return report_summary();
}
