Re: [kvm-unit-tests PATCH v3 6/7] s390x: pv: Add IPL reset tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 21 Apr 2023 11:36:46 +0000
Janosch Frank <frankja@xxxxxxxxxxxxx> wrote:

> The diag308 requires extensive cooperation between the hypervisor and
> the Ultravisor so the Ultravisor can make sure all necessary reset
> steps have been done.
> 
> Let's check if we get the correct validity errors.
> 
> Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx>
> ---
>  s390x/Makefile      |   2 +
>  s390x/pv-ipl.c      | 145 ++++++++++++++++++++++++++++++++++++++++++++
>  s390x/unittests.cfg |   4 ++
>  3 files changed, 151 insertions(+)
>  create mode 100644 s390x/pv-ipl.c
> 
> diff --git a/s390x/Makefile b/s390x/Makefile
> index 67be5360..b5b94810 100644
> --- a/s390x/Makefile
> +++ b/s390x/Makefile
> @@ -43,6 +43,7 @@ tests += $(TEST_DIR)/ex.elf
>  
>  pv-tests += $(TEST_DIR)/pv-diags.elf
>  pv-tests += $(TEST_DIR)/pv-icptcode.elf
> +pv-tests += $(TEST_DIR)/pv-ipl.elf
>  
>  ifneq ($(HOST_KEY_DOCUMENT),)
>  ifneq ($(GEN_SE_HEADER),)
> @@ -130,6 +131,7 @@ $(TEST_DIR)/pv-icptcode.elf: pv-snippets += $(SNIPPET_DIR)/asm/pv-icpt-112.gbin
>  $(TEST_DIR)/pv-icptcode.elf: pv-snippets += $(SNIPPET_DIR)/asm/icpt-loop.gbin
>  $(TEST_DIR)/pv-icptcode.elf: pv-snippets += $(SNIPPET_DIR)/asm/loop.gbin
>  $(TEST_DIR)/pv-icptcode.elf: pv-snippets += $(SNIPPET_DIR)/asm/pv-icpt-vir-timing.gbin
> +$(TEST_DIR)/pv-ipl.elf: pv-snippets += $(SNIPPET_DIR)/asm/pv-diag-308.gbin
>  
>  ifneq ($(GEN_SE_HEADER),)
>  snippets += $(pv-snippets)
> diff --git a/s390x/pv-ipl.c b/s390x/pv-ipl.c
> new file mode 100644
> index 00000000..aad1275e
> --- /dev/null
> +++ b/s390x/pv-ipl.c
> @@ -0,0 +1,145 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * PV diagnose 308 (IPL) tests
> + *
> + * Copyright (c) 2023 IBM Corp
> + *
> + * Authors:
> + *  Janosch Frank <frankja@xxxxxxxxxxxxx>
> + */
> +#include <libcflat.h>
> +#include <sie.h>
> +#include <sclp.h>
> +#include <snippet.h>
> +#include <pv_icptdata.h>
> +#include <asm/facility.h>
> +#include <asm/uv.h>
> +
> +static struct vm vm;
> +
> +static void test_diag_308(int subcode)
> +{
> +	extern const char SNIPPET_NAME_START(asm, pv_diag_308)[];
> +	extern const char SNIPPET_NAME_END(asm, pv_diag_308)[];
> +	extern const char SNIPPET_HDR_START(asm, pv_diag_308)[];
> +	extern const char SNIPPET_HDR_END(asm, pv_diag_308)[];
> +	int size_hdr = SNIPPET_HDR_LEN(asm, pv_diag_308);
> +	int size_gbin = SNIPPET_LEN(asm, pv_diag_308);
> +	uint16_t rc, rrc;
> +	char prefix[10];
> +	int cc;
> +
> +	snprintf(prefix, sizeof(prefix), "subcode %d", subcode);
> +
> +	report_prefix_push(prefix);

report_prefix_pushf

> +	snippet_pv_init(&vm, SNIPPET_NAME_START(asm, pv_diag_308),
> +			SNIPPET_HDR_START(asm, pv_diag_308),
> +			size_gbin, size_hdr, SNIPPET_UNPACK_OFF);
> +
> +	/* First exit is a diag 0x500 */
> +	sie(&vm);
> +	assert(pv_icptdata_check_diag(&vm, 0x500));
> +
> +	/*
> +	 * The snippet asked us for the subcode and we answer with 0 in gr2

not always 0 I guess?

> +	 * SIE will copy gr2 to the guest
> +	 */
> +	vm.save_area.guest.grs[2] = subcode;
> +
> +	/* Continue after diag 0x500, next icpt should be the 0x308 */
> +	sie(&vm);
> +	assert(pv_icptdata_check_diag(&vm, 0x308));
> +	assert(vm.save_area.guest.grs[2] == subcode);
> +
> +	/*
> +	 * We need to perform several UV calls to emulate the subcode
> +	 * 0/1. Failing to do that should result in a validity.
> +	 *
> +	 * - Mark all cpus as stopped
> +	 * - Unshare all memory
> +	 * - Prepare the reset
> +	 * - Reset the cpus
> +	 * - Load the reset PSW
> +	 */
> +	sie_expect_validity(&vm);
> +	sie(&vm);
> +	report(uv_validity_check(&vm), "validity, no action");
> +
> +	/* Mark the CPU as stopped so we can unshare and reset */
> +	cc = uv_set_cpu_state(vm.sblk->pv_handle_cpu, PV_CPU_STATE_STP);
> +	report(!cc, "Set cpu stopped");
> +
> +	sie_expect_validity(&vm);
> +	sie(&vm);
> +	report(uv_validity_check(&vm), "validity, stopped");
> +
> +	/* Unshare all memory */
> +	cc = uv_cmd_nodata(vm.sblk->pv_handle_config,
> +			   UVC_CMD_SET_UNSHARED_ALL, &rc, &rrc);
> +	report(cc == 0 && rc == 1, "Unshare all");
> +
> +	sie_expect_validity(&vm);
> +	sie(&vm);
> +	report(uv_validity_check(&vm), "validity, stopped, unshared");
> +
> +	/* Prepare the CPU reset */
> +	cc = uv_cmd_nodata(vm.sblk->pv_handle_config,
> +			   UVC_CMD_PREPARE_RESET, &rc, &rrc);
> +	report(cc == 0 && rc == 1, "Prepare reset call");
> +
> +	sie_expect_validity(&vm);
> +	sie(&vm);
> +	report(uv_validity_check(&vm), "validity, stopped, unshared, prep reset");
> +
> +	/*
> +	 * Do the reset on the initiating cpu
> +	 *
> +	 * Reset clear for subcode 0
> +	 * Reset initial for subcode 1
> +	 */
> +	if (subcode == 0) {
> +		cc = uv_cmd_nodata(vm.sblk->pv_handle_cpu,
> +				   UVC_CMD_CPU_RESET_CLEAR, &rc, &rrc);
> +		report(cc == 0 && rc == 1, "Clear reset cpu");
> +	} else {
> +		cc = uv_cmd_nodata(vm.sblk->pv_handle_cpu,
> +				   UVC_CMD_CPU_RESET_INITIAL, &rc, &rrc);
> +		report(cc == 0 && rc == 1, "Initial reset cpu");
> +	}
> +
> +	sie_expect_validity(&vm);
> +	sie(&vm);
> +	report(uv_validity_check(&vm), "validity, stopped, unshared, prep reset, cpu reset");
> +
> +	/* Load the PSW from 0x0 */
> +	cc = uv_set_cpu_state(vm.sblk->pv_handle_cpu, PV_CPU_STATE_OPR_LOAD);
> +	report(!cc, "Set cpu load");
> +
> +	/*
> +	 * Check if we executed the iaddr of the reset PSW, we should
> +	 * see a diagnose 0x9c PV instruction notification.
> +	 */
> +	sie(&vm);
> +	report(pv_icptdata_check_diag(&vm, 0x9c) &&
> +	       vm.save_area.guest.grs[0] == 42,
> +	       "continue after load");
> +
> +	uv_destroy_guest(&vm);
> +	report_prefix_pop();
> +}
> +
> +int main(void)
> +{
> +	report_prefix_push("uv-sie");
> +	if (!uv_guest_requirement_checks())
> +		goto done;
> +
> +	snippet_setup_guest(&vm, true);
> +	test_diag_308(0);
> +	test_diag_308(1);
> +	sie_guest_destroy(&vm);
> +
> +done:
> +	report_prefix_pop();
> +	return report_summary();
> +}
> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
> index e2d3478e..e08e5c84 100644
> --- a/s390x/unittests.cfg
> +++ b/s390x/unittests.cfg
> @@ -223,3 +223,7 @@ file = ex.elf
>  file = pv-icptcode.elf
>  smp = 3
>  extra_params = -m 2200
> +
> +[pv-ipl]
> +file = pv-ipl.elf
> +extra_params = -m 2200




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux