Let's add some tests for the diag10 "Release pages" instruction. Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxxxxxxx> --- s390x/Makefile | 1 + s390x/diag10.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 ++ 3 files changed, 85 insertions(+) create mode 100644 s390x/diag10.c diff --git a/s390x/Makefile b/s390x/Makefile index b73031d..bc5dd91 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -4,6 +4,7 @@ tests += $(TEST_DIR)/emulator.elf tests += $(TEST_DIR)/sieve.elf tests += $(TEST_DIR)/sthyi.elf tests += $(TEST_DIR)/skey.elf +tests += $(TEST_DIR)/diag10.elf all: directories test_cases diff --git a/s390x/diag10.c b/s390x/diag10.c new file mode 100644 index 0000000..ed94ffd --- /dev/null +++ b/s390x/diag10.c @@ -0,0 +1,81 @@ +/* + * Release pages hypercall tests (DIAG 10) + * + * Copyright (c) 2017 IBM Corp + * + * Authors: + * Janosch Frank <frankja@xxxxxxxxxxxxxxxxxx> + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License version 2. + */ + +#include <libcflat.h> +#include <asm/asm-offsets.h> +#include <asm/interrupt.h> +#include <asm/page.h> + +static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); +const unsigned long page0 = (unsigned long)pagebuf; +const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE); + +/* Tells the host to release pages from guest real addresses start to + * end. Parameters have to be page aligned, instruction is privileged. + */ +static inline void diag10(unsigned long start, unsigned long end) +{ + asm volatile ( + "diag %0,%1,0x10\n" + : : "a" (start), "a" (end)); +} + +/* Try freeing the prefix */ +static void test_prefix(void) +{ + expect_pgm_int(); + diag10(0, 0); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); + + expect_pgm_int(); + diag10(0x1000, 0x1000); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); + + expect_pgm_int(); + diag10(0, 0x1000); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); +} + +static void test_params(void) +{ + /* end < start */ + expect_pgm_int(); + diag10(page1, page0); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); + + /* Unaligned start */ + expect_pgm_int(); + diag10((unsigned long) pagebuf + 42, page1); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); + + /* Unaligned end */ + expect_pgm_int(); + diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42); + check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); +} + +static void test_priv(void) +{ + expect_pgm_int(); + enter_pstate(); + diag10(page0, page0); + check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); +} + +int main(void) +{ + report_prefix_push("diag10"); + test_prefix(); + test_params(); + test_priv(); + return report_summary(); +} diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index 8321e9b..5531590 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -41,3 +41,6 @@ accel = kvm [skey] file = skey.elf + +[diag10] +file = diag10.elf -- 2.7.4