/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Storage key tests
 *
 * Copyright (c) 2018 IBM Corp
 *
 * Authors:
 *  Janosch Frank <frankja@linux.vnet.ibm.com>
 */
#include <libcflat.h>
#include <asm/asm-offsets.h>
#include <asm/interrupt.h>
#include <asm/page.h>
#include <asm/facility.h>
#include <asm/mem.h>


static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));

static void test_set_mb(void)
{
	union skey skey, ret1, ret2;
	void *addr = (void *)0x10000 - 2 * PAGE_SIZE;
	void *end = (void *)0x10000;

	/* Multi block support came with EDAT 1 */
	if (!test_facility(8))
		return;

	skey.val = 0x30;
	while (addr < end)
		addr = set_storage_key_mb(addr, skey.val);

	ret1.val = get_storage_key(end - PAGE_SIZE) & (SKEY_ACC | SKEY_FP);
	ret2.val = get_storage_key(end - PAGE_SIZE * 2) & (SKEY_ACC | SKEY_FP);
	report(ret1.val == ret2.val && ret1.val == skey.val, "multi block");
}

static void test_chg(void)
{
	union skey skey1, skey2;

	skey1.val = 0x30;
	set_storage_key(pagebuf, skey1.val, 0);
	skey1.val = get_storage_key(pagebuf);
	pagebuf[0] = 3;
	skey2.val = get_storage_key(pagebuf);
	report(!skey1.str.ch && skey2.str.ch, "chg bit test");
}

static void test_set(void)
{
	union skey skey, ret;

	skey.val = 0x30;
	ret.val = get_storage_key(pagebuf);
	set_storage_key(pagebuf, skey.val, 0);
	ret.val = get_storage_key(pagebuf);
	/*
	 * For all set tests we only test the ACC and FP bits. RF and
	 * CH are set by the machine for memory references and changes
	 * and hence might change between a set and a get.
	 */
	report(skey.str.acc == ret.str.acc && skey.str.fp == ret.str.fp,
	       "set key test");
}

static void test_priv(void)
{
	union skey skey;

	memset(pagebuf, 0, PAGE_SIZE * 2);
	report_prefix_push("privileged");
	report_prefix_push("sske");
	expect_pgm_int();
	enter_pstate();
	set_storage_key(pagebuf, 0x30, 0);
	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
	report_prefix_pop();

	skey.val = get_storage_key(pagebuf);
	report(skey.str.acc != 3, "skey did not change on exception");

	report_prefix_push("iske");
	expect_pgm_int();
	enter_pstate();
	get_storage_key(pagebuf);
	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
	report_prefix_pop();

	report_prefix_pop();
}

static void test_invalid_address(void)
{
	void *inv_addr = (void *)-1ull;

	report_prefix_push("invalid address");

	report_prefix_push("sske");
	expect_pgm_int();
	set_storage_key(inv_addr, 0, 0);
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
	report_prefix_pop();

	report_prefix_push("iske");
	expect_pgm_int();
	get_storage_key(inv_addr);
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
	report_prefix_pop();

	report_prefix_push("rrbe");
	expect_pgm_int();
	reset_reference_bit(inv_addr);
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
	report_prefix_pop();

	report_prefix_pop();
}

int main(void)
{
	report_prefix_push("skey");
	if (test_facility(169)) {
		report_skip("storage key removal facility is active");
		goto done;
	}
	test_priv();
	test_invalid_address();
	test_set();
	test_set_mb();
	test_chg();
done:
	report_prefix_pop();
	return report_summary();
}
