From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2461C43460 for ; Tue, 20 Apr 2021 15:48:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B8D3613C0 for ; Tue, 20 Apr 2021 15:48:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232951AbhDTPsv (ORCPT ); Tue, 20 Apr 2021 11:48:51 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:8964 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232996AbhDTPst (ORCPT ); Tue, 20 Apr 2021 11:48:49 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 13KFkpPx098231; Tue, 20 Apr 2021 11:48:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=date : from : to : cc : subject : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=pp1; bh=1bsj6pTzS2UDiJayMhgQAiQ7/psPt0xjwAZrrgFrCDs=; b=bRcyXaB/tj0Ab4DkqzWICSVNXvxbvPhUnhMRi8LJFR+Hu53A0jz04RZhJ/QC6AGjDhKa gDYPvPDSIl/gLOZzcErg8wt7sq6QKaTxyCEfF5d2xjKnDvLjCvsChSpMUv04sgf/Q0V/ 99jQP9wziGjYiDqOdV8jifvnQz/xHHpxh9esbGmcRB5EQ915c64aO9qNT7EDutpQ+V7s 9AsoNv6iYQBJ7uo2bvvF/9wgC4Snn7ItrkLo/YeeHWNkJjL70PSR4QCtTafCX6ZmQ3Z9 Qz8+k2C7aON5/6C0l0LWd9nqKDcpOZUCa7QVsnTnWXoIqJnMAGeUAs4IkBhdKvxdBXB/ aA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 382085upbj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 20 Apr 2021 11:48:17 -0400 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 13KFl6vE099632; Tue, 20 Apr 2021 11:48:17 -0400 Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 382085upaw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 20 Apr 2021 11:48:16 -0400 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.0.43/8.16.0.43) with SMTP id 13KFmEhP004436; Tue, 20 Apr 2021 15:48:14 GMT Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by ppma04ams.nl.ibm.com with ESMTP id 37yqa8htut-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 20 Apr 2021 15:48:14 +0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 13KFmCeF33816958 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 20 Apr 2021 15:48:12 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 529FA4C046; Tue, 20 Apr 2021 15:48:12 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F26954C040; Tue, 20 Apr 2021 15:48:11 +0000 (GMT) Received: from ibm-vm (unknown [9.145.0.91]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 20 Apr 2021 15:48:11 +0000 (GMT) Date: Tue, 20 Apr 2021 17:47:57 +0200 From: Claudio Imbrenda To: Janosch Frank Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org, thuth@redhat.com, david@redhat.com Subject: Re: [kvm-unit-tests PATCH 6/6] s390x: Add UV host test Message-ID: <20210420174757.49d3ed3a@ibm-vm> In-Reply-To: <20210316091654.1646-7-frankja@linux.ibm.com> References: <20210316091654.1646-1-frankja@linux.ibm.com> <20210316091654.1646-7-frankja@linux.ibm.com> Organization: IBM X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.32; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-GUID: JoaRwyQBBmj3Pga_5B2E3zo6zY1xHxl1 X-Proofpoint-ORIG-GUID: XY9g7hEd2KziH-vFtoyJnw1UXlV0BTOt X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.761 definitions=2021-04-20_07:2021-04-20,2021-04-20 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 bulkscore=0 spamscore=0 lowpriorityscore=0 impostorscore=0 malwarescore=0 priorityscore=1501 clxscore=1015 phishscore=0 adultscore=0 mlxlogscore=999 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104200114 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org On Tue, 16 Mar 2021 09:16:54 +0000 Janosch Frank wrote: > Let's also test the UV host interfaces. > > Signed-off-by: Janosch Frank Reviewed-by: Claudio Imbrenda the test is ok as is, but I do have a lot of ideas on how to improve/extend it further. Once this is merged (and once I have some time) I will send a few patches. > --- > s390x/Makefile | 1 + > s390x/uv-host.c | 513 > ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 514 > insertions(+) create mode 100644 s390x/uv-host.c > > diff --git a/s390x/Makefile b/s390x/Makefile > index bbf177fa..8de926ab 100644 > --- a/s390x/Makefile > +++ b/s390x/Makefile > @@ -21,6 +21,7 @@ tests += $(TEST_DIR)/css.elf > tests += $(TEST_DIR)/uv-guest.elf > tests += $(TEST_DIR)/sie.elf > tests += $(TEST_DIR)/mvpg.elf > +tests += $(TEST_DIR)/uv-host.elf > > tests_binary = $(patsubst %.elf,%.bin,$(tests)) > ifneq ($(HOST_KEY_DOCUMENT),) > diff --git a/s390x/uv-host.c b/s390x/uv-host.c > new file mode 100644 > index 00000000..746abd8e > --- /dev/null > +++ b/s390x/uv-host.c > @@ -0,0 +1,513 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Guest Ultravisor Call tests > + * > + * Copyright (c) 2021 IBM Corp > + * > + * Authors: > + * Janosch Frank > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static struct uv_cb_qui uvcb_qui; > +static struct uv_cb_init uvcb_init; > +static struct uv_cb_cgc uvcb_cgc; > +static struct uv_cb_csc uvcb_csc; > + > +extern int diag308_load_reset(u64 code); > + > +struct cmd_list{ > + const char *name; > + uint16_t cmd; > + uint16_t len; > +}; > + > +static void cpu_loop(void) > +{ > + for (;;) {} > +} > + > +static struct cmd_list cmds[] = { > + { "init", UVC_CMD_INIT_UV, sizeof(struct uv_cb_init) }, > + { "create conf", UVC_CMD_CREATE_SEC_CONF, sizeof(struct > uv_cb_cgc) }, > + { "destroy conf", UVC_CMD_DESTROY_SEC_CONF, sizeof(struct > uv_cb_nodata) }, > + { "create cpu", UVC_CMD_CREATE_SEC_CPU, sizeof(struct > uv_cb_csc) }, > + { "destroy cpu", UVC_CMD_DESTROY_SEC_CPU, sizeof(struct > uv_cb_nodata) }, > + { "conv to", UVC_CMD_CONV_TO_SEC_STOR, sizeof(struct > uv_cb_cts) }, > + { "conv from", UVC_CMD_CONV_FROM_SEC_STOR, sizeof(struct > uv_cb_cfs) }, > + { "set sec conf", UVC_CMD_SET_SEC_CONF_PARAMS, sizeof(struct > uv_cb_ssc) }, > + { "unpack", UVC_CMD_UNPACK_IMG, sizeof(struct uv_cb_unp) }, > + { "verify", UVC_CMD_VERIFY_IMG, sizeof(struct uv_cb_nodata) > }, > + { "cpu reset", UVC_CMD_CPU_RESET, sizeof(struct > uv_cb_nodata) }, > + { "cpu initial reset", UVC_CMD_CPU_RESET_INITIAL, > sizeof(struct uv_cb_nodata) }, > + { "conf clear reset", UVC_CMD_PERF_CONF_CLEAR_RESET, > sizeof(struct uv_cb_nodata) }, > + { "cpu clear reset", UVC_CMD_CPU_RESET_CLEAR, sizeof(struct > uv_cb_nodata) }, > + { "cpu set state", UVC_CMD_CPU_SET_STATE, sizeof(struct > uv_cb_cpu_set_state) }, > + { "pin shared", UVC_CMD_PIN_PAGE_SHARED, sizeof(struct > uv_cb_cfs) }, > + { "unpin shared", UVC_CMD_UNPIN_PAGE_SHARED, sizeof(struct > uv_cb_cts) }, > + { NULL, 0, 0 }, > +}; > + > +static void test_priv(void) > +{ > + struct uv_cb_header uvcb = {}; > + uint16_t pgm; > + int i; > + > + report_prefix_push("privileged"); > + for (i = 0; cmds[i].name; i++) { > + expect_pgm_int(); > + uvcb.cmd = cmds[i].cmd; > + uvcb.len = cmds[i].len; > + enter_pstate(); > + uv_call(0, (uint64_t)&uvcb); > + pgm = clear_pgm_int(); > + report(pgm == PGM_INT_CODE_PRIVILEGED_OPERATION, > "%s", cmds[i].name); > + } > + report_prefix_pop(); > +} > + > +static void test_config_destroy(void) > +{ > + int rc; > + struct uv_cb_nodata uvcb = { > + .header.cmd = UVC_CMD_DESTROY_SEC_CONF, > + .header.len = sizeof(uvcb), > + .handle = uvcb_cgc.guest_handle, > + }; > + > + report_prefix_push("dsc"); > + uvcb.header.len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 1 && uvcb.header.rc == UVC_RC_INV_LEN, > + "hdr invalid length"); > + uvcb.header.len += 8; > + > + uvcb.handle += 1; > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 1 && uvcb.header.rc == UVC_RC_INV_GHANDLE, > "invalid handle"); > + uvcb.handle -= 1; > + > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 0 && uvcb.header.rc == UVC_RC_EXECUTED, > "success"); > + report_prefix_pop(); > +} > + > +static void test_cpu_destroy(void) > +{ > + int rc; > + struct uv_cb_nodata uvcb = { > + .header.len = sizeof(uvcb), > + .header.cmd = UVC_CMD_DESTROY_SEC_CPU, > + .handle = uvcb_csc.cpu_handle, > + }; > + > + report_prefix_push("dcpu"); > + > + uvcb.header.len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 1 && uvcb.header.rc == UVC_RC_INV_LEN, > + "hdr invalid length"); > + uvcb.header.len += 8; > + > + uvcb.handle += 1; > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 1 && uvcb.header.rc == UVC_RC_INV_CHANDLE, > "invalid handle"); > + uvcb.handle -= 1; > + > + rc = uv_call(0, (uint64_t)&uvcb); > + report(rc == 0 && uvcb.header.rc == UVC_RC_EXECUTED, > "success"); + > + report_prefix_pop(); > +} > + > +static void test_cpu_create(void) > +{ > + int rc; > + unsigned long tmp; > + > + report_prefix_push("csc"); > + uvcb_csc.header.len = sizeof(uvcb_csc); > + uvcb_csc.header.cmd = UVC_CMD_CREATE_SEC_CPU; > + uvcb_csc.guest_handle = uvcb_cgc.guest_handle; > + uvcb_csc.stor_origin = (unsigned long)memalign(PAGE_SIZE, > uvcb_qui.cpu_stor_len); > + uvcb_csc.state_origin = (unsigned long)memalign(PAGE_SIZE, > PAGE_SIZE); + > + uvcb_csc.header.len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == UVC_RC_INV_LEN && rc == 1 && > + !uvcb_csc.cpu_handle, "hdr invalid length"); > + uvcb_csc.header.len += 8; > + > + uvcb_csc.guest_handle += 1; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == UVC_RC_INV_GHANDLE && rc == 1, > + "invalid guest handle"); > + uvcb_csc.guest_handle -= 1; > + > + uvcb_csc.num = uvcb_qui.max_guest_cpus + 1; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == 0x103 && rc == 1, > + "invalid cpu #"); > + uvcb_csc.num = 0; > + > + tmp = uvcb_csc.stor_origin; > + uvcb_csc.stor_origin = get_max_ram_size() + PAGE_SIZE; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == 0x105 && rc == 1, > + "cpu stor inaccessible"); > + uvcb_csc.stor_origin = tmp; > + > + tmp = uvcb_csc.stor_origin; > + uvcb_csc.stor_origin = 0; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == 0x106 && rc == 1, > + "cpu stor in lowcore"); > + uvcb_csc.stor_origin = tmp; > + > + tmp = uvcb_csc.state_origin; > + uvcb_csc.state_origin = get_max_ram_size() + PAGE_SIZE; > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(uvcb_csc.header.rc == 0x107 && rc == 1, > + "SIE SD inaccessible"); > + uvcb_csc.state_origin = tmp; > + > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(rc == 0 && uvcb_csc.header.rc == UVC_RC_EXECUTED && > + uvcb_csc.cpu_handle, "success"); > + > + tmp = uvcb_csc.stor_origin; > + uvcb_csc.stor_origin = (unsigned long)memalign(PAGE_SIZE, > uvcb_qui.cpu_stor_len); > + rc = uv_call(0, (uint64_t)&uvcb_csc); > + report(rc == 1 && uvcb_csc.header.rc == 0x104, "already > defined"); > + uvcb_csc.stor_origin = tmp; > + report_prefix_pop(); > +} > + > +static void test_config_create(void) > +{ > + int rc; > + unsigned long vsize, tmp; > + static struct uv_cb_cgc uvcb; > + > + uvcb_cgc.header.cmd = UVC_CMD_CREATE_SEC_CONF; > + uvcb_cgc.header.len = sizeof(uvcb_cgc); > + report_prefix_push("cgc"); > + > + uvcb_cgc.guest_stor_origin = 0; > + uvcb_cgc.guest_stor_len = 42 * (1UL << 20); > + vsize = uvcb_qui.conf_base_virt_stor_len + > + ((uvcb_cgc.guest_stor_len / (1UL << 20)) * > uvcb_qui.conf_virt_var_stor_len); + > + uvcb_cgc.conf_base_stor_origin = > (uint64_t)memalign(PAGE_SIZE * 4, uvcb_qui.conf_base_phys_stor_len); > + uvcb_cgc.conf_var_stor_origin = > (uint64_t)memalign(PAGE_SIZE, vsize); > + uvcb_cgc.guest_asce = (uint64_t)memalign(PAGE_SIZE, 4 * > PAGE_SIZE) | ASCE_DT_SEGMENT | REGION_TABLE_LENGTH | ASCE_P; > + uvcb_cgc.guest_sca = (uint64_t)memalign(PAGE_SIZE * 4, > PAGE_SIZE * 4); + > + uvcb_cgc.header.len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == UVC_RC_INV_LEN && rc == 1 && > + !uvcb_cgc.guest_handle, "hdr invalid length"); > + uvcb_cgc.header.len += 8; > + > + uvcb_cgc.guest_stor_origin = uvcb_qui.max_guest_stor_addr + > (1UL << 20) * 2 + 1; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x101 && rc == 1, > + "MSO > max guest addr"); > + uvcb_cgc.guest_stor_origin = 0; > + > + uvcb_cgc.guest_stor_origin = uvcb_qui.max_guest_stor_addr - > (1UL << 20); > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x102 && rc == 1, > + "MSO + MSL > max guest addr"); > + uvcb_cgc.guest_stor_origin = 0; > + > + uvcb_cgc.guest_asce &= ~ASCE_P; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x105 && rc == 1, > + "ASCE private bit missing"); > + uvcb_cgc.guest_asce |= ASCE_P; > + > + uvcb_cgc.guest_asce |= 0x20; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x105 && rc == 1, > + "ASCE bit 58 set"); > + uvcb_cgc.guest_asce &= ~0x20; > + > + tmp = uvcb_cgc.conf_base_stor_origin; > + uvcb_cgc.conf_base_stor_origin = get_max_ram_size() + 8; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x108 && rc == 1, > + "base storage origin > available memory"); > + uvcb_cgc.conf_base_stor_origin = tmp; > + > + tmp = uvcb_cgc.conf_base_stor_origin; > + uvcb_cgc.conf_base_stor_origin = 0x1000; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x109 && rc == 1, > + "base storage origin contains lowcore"); > + uvcb_cgc.conf_base_stor_origin = tmp; > + > + if (smp_query_num_cpus() == 1) { > + sigp_retry(1, SIGP_SET_PREFIX, > + uvcb_cgc.conf_var_stor_origin + > PAGE_SIZE, NULL); > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x10e && rc == 1 && > + !uvcb_cgc.guest_handle, "variable storage > area contains lowcore"); > + sigp_retry(1, SIGP_SET_PREFIX, 0x0, NULL); > + } > + > + tmp = uvcb_cgc.guest_sca; > + uvcb_cgc.guest_sca = 0; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x10c && rc == 1, > + "sca == 0"); > + uvcb_cgc.guest_sca = tmp; > + > + tmp = uvcb_cgc.guest_sca; > + uvcb_cgc.guest_sca = get_max_ram_size() + + PAGE_SIZE * 4; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc == 0x10d && rc == 1, > + "sca inaccessible"); > + uvcb_cgc.guest_sca = tmp; > + > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(rc == 0 && uvcb_cgc.header.rc == UVC_RC_EXECUTED, > "successful"); + > + uvcb_cgc.header.rc = 0; > + uvcb_cgc.header.rrc = 0; > + tmp = uvcb_cgc.guest_handle; > + uvcb_cgc.guest_handle = 0; > + rc = uv_call(0, (uint64_t)&uvcb_cgc); > + report(uvcb_cgc.header.rc >= 0x100 && rc == 1, "reuse uvcb"); > + uvcb_cgc.guest_handle = tmp; > + > + /* Copy over most data from uvcb_cgc, so we have the ASCE > that was used. */ > + memcpy(&uvcb, &uvcb_cgc, sizeof(uvcb)); > + > + /* Reset the header and handle */ > + uvcb.header.rc = 0; > + uvcb.header.rrc = 0; > + uvcb.guest_handle = 0; > + > + /* Use new storage areas. */ > + uvcb.conf_base_stor_origin = (uint64_t)memalign(PAGE_SIZE * > 4, uvcb_qui.conf_base_phys_stor_len); > + uvcb.conf_var_stor_origin = (uint64_t)memalign(PAGE_SIZE, > vsize); + > + rc = uv_call(0, (uint64_t)&uvcb); > + report(uvcb.header.rc >= 0x104 && rc == 1 && > !uvcb.guest_handle, > + "reuse ASCE"); > + free((void *)uvcb.conf_base_stor_origin); > + free((void *)uvcb.conf_var_stor_origin); > + > + > + /* Missing: 106, 10a, a0b */ > + report_prefix_pop(); > +} > + > +static void test_init(void) > +{ > + int rc; > + uint64_t mem; > + struct psw psw; > + > + /* Donated storage needs to be over 2GB */ > + mem = (uint64_t)memalign(1UL << 31, > uvcb_qui.uv_base_stor_len); + > + uvcb_init.header.len = sizeof(uvcb_init); > + uvcb_init.header.cmd = UVC_CMD_INIT_UV; > + uvcb_init.stor_origin = mem; > + uvcb_init.stor_len = uvcb_qui.uv_base_stor_len; > + > + report_prefix_push("init"); > + uvcb_init.header.len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == UVC_RC_INV_LEN, > + "hdr invalid length"); > + uvcb_init.header.len += 8; > + > + uvcb_init.stor_len -= 8; > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x103, > + "storage invalid length"); > + uvcb_init.stor_len += 8; > + > + uvcb_init.stor_origin = get_max_ram_size() + 8; > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x104, > + "storage origin invalid"); > + uvcb_init.stor_origin = mem; > + > + uvcb_init.stor_origin = get_max_ram_size() - 8; > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x105, > + "storage + length invalid"); > + uvcb_init.stor_origin = mem; > + > + uvcb_init.stor_origin = 1UL << 30; > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x108, > + "storage below 2GB"); > + uvcb_init.stor_origin = mem; > + > + psw.mask = extract_psw_mask(); > + psw.addr = (unsigned long)cpu_loop; > + smp_cpu_setup(1, psw); > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x102, > + "too many running cpus"); > + smp_cpu_stop(1); > + > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 0 && uvcb_init.header.rc == UVC_RC_EXECUTED, > "successful"); + > + mem = (uint64_t)memalign(1UL << 31, > uvcb_qui.uv_base_stor_len); > + rc = uv_call(0, (uint64_t)&uvcb_init); > + report(rc == 1 && uvcb_init.header.rc == 0x101, "double > init"); > + free((void *)mem); > + > + report_prefix_pop(); > +} > + > +static void test_query(void) > +{ > + uvcb_qui.header.cmd = UVC_CMD_QUI; > + uvcb_qui.header.len = sizeof(uvcb_qui); > + uint64_t *call_list = &uvcb_qui.inst_calls_list[0]; > + > + report_prefix_push("query"); > + uvcb_qui.header.len = 0xa0; > + uv_call(0, (uint64_t)&uvcb_qui); > + report(uvcb_qui.header.rc == UVC_RC_INV_LEN, "length"); > + > + uvcb_qui.header.len = 0xa8; > + uv_call(0, (uint64_t)&uvcb_qui); > + report(uvcb_qui.header.rc == 0x100, "insf length"); > + > + uvcb_qui.header.len = sizeof(uvcb_qui); > + uv_call(0, (uint64_t)&uvcb_qui); > + report(uvcb_qui.header.rc == UVC_RC_EXECUTED, "successful > query"); + > + report(test_bit_inv(BIT_UVC_CMD_QUI, call_list) && > + test_bit_inv(BIT_UVC_CMD_INIT_UV, call_list), > + "query and init indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_CREATE_SEC_CONF, call_list) > && > + test_bit_inv(BIT_UVC_CMD_DESTROY_SEC_CONF, call_list), > + "create/destroy vm indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_CREATE_SEC_CPU, call_list) && > + test_bit_inv(BIT_UVC_CMD_DESTROY_SEC_CPU, call_list), > + "create/destroy cpu indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_CONV_TO_SEC_STOR, call_list) > && > + test_bit_inv(BIT_UVC_CMD_CONV_FROM_SEC_STOR, > call_list), > + "convert to/from secure storage indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_SET_SEC_PARMS, call_list) && > + test_bit_inv(BIT_UVC_CMD_UNPACK_IMG, call_list) && > + test_bit_inv(BIT_UVC_CMD_CPU_SET_STATE, call_list) && > + test_bit_inv(BIT_UVC_CMD_VERIFY_IMG, call_list), > + "set sec parm, setcpu state, unpack and verify > indicated"); + > + report(test_bit_inv(BIT_UVC_CMD_CPU_RESET, call_list) && > + test_bit_inv(BIT_UVC_CMD_CPU_RESET_INITIAL, > call_list) && > + test_bit_inv(BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET, > call_list), > + "resets indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_PREPARE_CLEAR_RESET, > call_list) && > + test_bit_inv(BIT_UVC_CMD_UNSHARE_ALL, call_list), > + "prepare reset and unshare all indicated"); > + > + report(test_bit_inv(BIT_UVC_CMD_PIN_PAGE_SHARED, call_list) > && > + test_bit_inv(BIT_UVC_CMD_UNPIN_PAGE_SHARED, > call_list), > + "(un)pin shared page indicated"); > + > + report(!test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, > call_list) && > + !test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, > call_list), > + "(un)share not indicated"); > + > + report_prefix_pop(); > +} > + > +static struct cmd_list invalid_cmds[] = { > + { "bogus", 0x4242, sizeof(struct uv_cb_header) }, > + { "share", UVC_CMD_SET_SHARED_ACCESS, sizeof(struct > uv_cb_share) }, > + { "unshare", UVC_CMD_REMOVE_SHARED_ACCESS, sizeof(struct > uv_cb_share) }, > + { NULL, 0, 0 }, > +}; > + > +static void test_invalid(void) > +{ > + struct uv_cb_header hdr = {}; > + int i, cc; > + > + report_prefix_push("invalid"); > + for (i = 0; invalid_cmds[i].name; i++) { > + hdr.cmd = invalid_cmds[i].cmd; > + hdr.len = invalid_cmds[i].len; > + cc = uv_call(0, (uint64_t)&hdr); > + report(cc == 1 && hdr.rc == UVC_RC_INV_CMD, "%s", > + invalid_cmds[i].name); > + } > + report_prefix_pop(); > +} > + > +static void test_clear(void) > +{ > + uint64_t *tmp = (void *)uvcb_init.stor_origin; > + > + diag308_load_reset(1); > + sclp_console_setup(); > + report(!*tmp, "memory cleared after reset 1"); > +} > + > +static void setup_vmem(void) > +{ > + uint64_t asce, mask; > + > + setup_mmu(get_max_ram_size()); > + asce = stctg(1); > + lctlg(13, asce); > + mask = extract_psw_mask() | 0x0000C00000000000UL; > + load_psw_mask(mask); > +} > + > +int main(void) > +{ > + bool has_uvc = test_facility(158); > + > + report_prefix_push("uvc"); > + if (!has_uvc) { > + report_skip("Ultravisor call facility is not > available"); > + goto done; > + } > + > + test_priv(); > + test_invalid(); > + test_query(); > + test_init(); > + > + setup_vmem(); > + test_config_create(); > + test_cpu_create(); > + test_cpu_destroy(); > + test_config_destroy(); > + test_clear(); > + > +done: > + return report_summary(); > +}