From patchwork Thu Jul 21 14:06:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudio Imbrenda X-Patchwork-Id: 12925235 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01A7AC433EF for ; Thu, 21 Jul 2022 14:08:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231383AbiGUOII (ORCPT ); Thu, 21 Jul 2022 10:08:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47272 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231284AbiGUOIE (ORCPT ); Thu, 21 Jul 2022 10:08:04 -0400 Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D76CC7CB69 for ; Thu, 21 Jul 2022 07:07:56 -0700 (PDT) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26LDVHCk029869 for ; Thu, 21 Jul 2022 14:07:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=LHvaQ1NymMFU1CAqNETUmxgyQ8RcPfBa2G+0smqWSGI=; b=NQyges0DwYOoDz8j5uumzdcy4FLyaWQiizBAod20LC0ieVawOAU399hU+6WcY9Un9qqb LW/YbTB6l9LP1AEXB8FtKpvQ+Ar/EG+p6TVZUH86F4CojjO9F36suhchlg1M6E5SfeiY KWu8CK0oSaY/RZH3B8hLVZteKs7RYNGMZEwlEMnHpdxHxd7eQedH6INXg9WIXZwABJB0 2/BVuJXQbuXUqWtbBLZWfk+y8+Te1T/bnj/c6h3sQW6cFzi+DgMjIK7haSqojjcif9Z7 AsyEr0jhloLUbZTnCdIpK7Lm8JPr030gg5DkdFUN9eD9vHTPYm/xbZ2l+WOyVoe4SrZX Ig== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3hf7rrscgn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 21 Jul 2022 14:07:54 +0000 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 26LDVt8Z032378 for ; Thu, 21 Jul 2022 14:07:31 GMT Received: from ppma01fra.de.ibm.com (46.49.7a9f.ip4.static.sl-reverse.com [159.122.73.70]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3hf7rrsc0j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 Jul 2022 14:07:31 +0000 Received: from pps.filterd (ppma01fra.de.ibm.com [127.0.0.1]) by ppma01fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 26LE77uG014661; Thu, 21 Jul 2022 14:07:07 GMT Received: from b06avi18626390.portsmouth.uk.ibm.com (b06avi18626390.portsmouth.uk.ibm.com [9.149.26.192]) by ppma01fra.de.ibm.com with ESMTP id 3hbmy8y56b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 Jul 2022 14:07:06 +0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06avi18626390.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 26LE5F1I23200060 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 21 Jul 2022 14:05:15 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A87474C050; Thu, 21 Jul 2022 14:07:03 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 537B24C044; Thu, 21 Jul 2022 14:07:03 +0000 (GMT) Received: from p-imbrenda.ibmuc.com (unknown [9.145.4.232]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 21 Jul 2022 14:07:03 +0000 (GMT) From: Claudio Imbrenda To: pbonzini@redhat.com Cc: kvm@vger.kernel.org, thuth@redhat.com, frankja@linux.ibm.com, Janis Schoetterl-Glausch Subject: [kvm-unit-tests GIT PULL 05/12] s390x: Test effect of storage keys on some more instructions Date: Thu, 21 Jul 2022 16:06:54 +0200 Message-Id: <20220721140701.146135-6-imbrenda@linux.ibm.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220721140701.146135-1-imbrenda@linux.ibm.com> References: <20220721140701.146135-1-imbrenda@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: iNT-rg579JuGdUIb2t8mKxXzn7DsxAQp X-Proofpoint-GUID: 6-O2Jxv9GnslDNFIdV7ThHrG9Cwh3U_j X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-21_18,2022-07-20_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 mlxscore=0 mlxlogscore=999 impostorscore=0 adultscore=0 suspectscore=0 spamscore=0 lowpriorityscore=0 clxscore=1015 bulkscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2206140000 definitions=main-2207210057 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Janis Schoetterl-Glausch Test correctness of some instructions handled by user space instead of KVM with regards to storage keys. Test success and error conditions, including coverage of storage and fetch protection override. Signed-off-by: Janis Schoetterl-Glausch Reviewed-by: Claudio Imbrenda Message-Id: <20220621143609.753452-3-scgl@linux.ibm.com> Signed-off-by: Claudio Imbrenda --- s390x/skey.c | 275 ++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 1 + 2 files changed, 276 insertions(+) diff --git a/s390x/skey.c b/s390x/skey.c index efce1fc3..aa9b4dcd 100644 --- a/s390x/skey.c +++ b/s390x/skey.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,115 @@ static void test_store_cpu_address(void) report_prefix_pop(); } +/* + * Perform CHANNEL SUBSYSTEM CALL (CHSC) instruction while temporarily executing + * with access key 1. + */ +static unsigned int chsc_key_1(void *comm_block) +{ + uint32_t program_mask; + + asm volatile ( + "spka 0x10\n\t" + ".insn rre,0xb25f0000,%[comm_block],0\n\t" + "spka 0\n\t" + "ipm %[program_mask]\n" + : [program_mask] "=d" (program_mask) + : [comm_block] "d" (comm_block) + : "memory" + ); + return program_mask >> 28; +} + +static const char chsc_msg[] = "Performed store-channel-subsystem-characteristics"; +static void init_comm_block(uint16_t *comm_block) +{ + memset(comm_block, 0, PAGE_SIZE); + /* store-channel-subsystem-characteristics command */ + comm_block[0] = 0x10; + comm_block[1] = 0x10; + comm_block[9] = 0; +} + +static void test_channel_subsystem_call(void) +{ + uint16_t *comm_block = (uint16_t *)&pagebuf; + unsigned int cc; + + report_prefix_push("CHANNEL SUBSYSTEM CALL"); + + report_prefix_push("zero key"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x10, 0); + asm volatile ( + ".insn rre,0xb25f0000,%[comm_block],0\n\t" + "ipm %[cc]\n" + : [cc] "=d" (cc) + : [comm_block] "d" (comm_block) + : "memory" + ); + cc = cc >> 28; + report(cc == 0 && comm_block[9], chsc_msg); + report_prefix_pop(); + + report_prefix_push("matching key"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x10, 0); + cc = chsc_key_1(comm_block); + report(cc == 0 && comm_block[9], chsc_msg); + report_prefix_pop(); + + report_prefix_push("mismatching key"); + + report_prefix_push("no fetch protection"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x20, 0); + expect_pgm_int(); + chsc_key_1(comm_block); + check_key_prot_exc(ACC_UPDATE, PROT_STORE); + report_prefix_pop(); + + report_prefix_push("fetch protection"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x28, 0); + expect_pgm_int(); + chsc_key_1(comm_block); + check_key_prot_exc(ACC_UPDATE, PROT_FETCH_STORE); + report_prefix_pop(); + + ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE); + + report_prefix_push("storage-protection override, invalid key"); + set_storage_key(comm_block, 0x20, 0); + init_comm_block(comm_block); + expect_pgm_int(); + chsc_key_1(comm_block); + check_key_prot_exc(ACC_UPDATE, PROT_STORE); + report_prefix_pop(); + + report_prefix_push("storage-protection override, override key"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x90, 0); + cc = chsc_key_1(comm_block); + report(cc == 0 && comm_block[9], chsc_msg); + report_prefix_pop(); + + ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE); + + report_prefix_push("storage-protection override disabled, override key"); + init_comm_block(comm_block); + set_storage_key(comm_block, 0x90, 0); + expect_pgm_int(); + chsc_key_1(comm_block); + check_key_prot_exc(ACC_UPDATE, PROT_STORE); + report_prefix_pop(); + + report_prefix_pop(); + + set_storage_key(comm_block, 0x00, 0); + report_prefix_pop(); +} + /* * Perform SET PREFIX (SPX) instruction while temporarily executing * with access key 1. @@ -428,6 +538,169 @@ static void test_set_prefix(void) report_prefix_pop(); } +/* + * Perform MODIFY SUBCHANNEL (MSCH) instruction while temporarily executing + * with access key 1. + */ +static uint32_t modify_subchannel_key_1(uint32_t sid, struct schib *schib) +{ + uint32_t program_mask; + + asm volatile ( + "lr %%r1,%[sid]\n\t" + "spka 0x10\n\t" + "msch %[schib]\n\t" + "spka 0\n\t" + "ipm %[program_mask]\n" + : [program_mask] "=d" (program_mask) + : [sid] "d" (sid), + [schib] "Q" (*schib) + : "%r1" + ); + return program_mask >> 28; +} + +static void test_msch(void) +{ + struct schib *schib = (struct schib *)pagebuf; + struct schib *no_override_schib; + int test_device_sid; + pgd_t *root; + int cc; + + report_prefix_push("MSCH"); + root = (pgd_t *)(stctg(1) & PAGE_MASK); + test_device_sid = css_enumerate(); + + if (!(test_device_sid & SCHID_ONE)) { + report_fail("no I/O device found"); + return; + } + + cc = stsch(test_device_sid, schib); + if (cc) { + report_fail("could not store SCHIB"); + return; + } + + report_prefix_push("zero key"); + schib->pmcw.intparm = 100; + set_storage_key(schib, 0x28, 0); + cc = msch(test_device_sid, schib); + if (!cc) { + WRITE_ONCE(schib->pmcw.intparm, 0); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 100, "fetched from SCHIB"); + } else { + report_fail("MSCH cc != 0"); + } + report_prefix_pop(); + + report_prefix_push("matching key"); + schib->pmcw.intparm = 200; + set_storage_key(schib, 0x18, 0); + cc = modify_subchannel_key_1(test_device_sid, schib); + if (!cc) { + WRITE_ONCE(schib->pmcw.intparm, 0); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 200, "fetched from SCHIB"); + } else { + report_fail("MSCH cc != 0"); + } + report_prefix_pop(); + + report_prefix_push("mismatching key"); + + report_prefix_push("no fetch protection"); + schib->pmcw.intparm = 300; + set_storage_key(schib, 0x20, 0); + cc = modify_subchannel_key_1(test_device_sid, schib); + if (!cc) { + WRITE_ONCE(schib->pmcw.intparm, 0); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 300, "fetched from SCHIB"); + } else { + report_fail("MSCH cc != 0"); + } + report_prefix_pop(); + + schib->pmcw.intparm = 0; + if (!msch(test_device_sid, schib)) { + report_prefix_push("fetch protection"); + schib->pmcw.intparm = 400; + set_storage_key(schib, 0x28, 0); + expect_pgm_int(); + modify_subchannel_key_1(test_device_sid, schib); + check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); + report_prefix_pop(); + } else { + report_fail("could not reset SCHIB"); + } + + register_pgm_cleanup_func(dat_fixup_pgm_int); + + schib->pmcw.intparm = 0; + if (!msch(test_device_sid, schib)) { + report_prefix_push("remapped page, fetch protection"); + schib->pmcw.intparm = 500; + set_storage_key(pagebuf, 0x28, 0); + expect_pgm_int(); + install_page(root, virt_to_pte_phys(root, pagebuf), 0); + modify_subchannel_key_1(test_device_sid, (struct schib *)0); + install_page(root, 0, 0); + check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); + report_prefix_pop(); + } else { + report_fail("could not reset SCHIB"); + } + + ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); + + report_prefix_push("fetch-protection override applies"); + schib->pmcw.intparm = 600; + set_storage_key(pagebuf, 0x28, 0); + install_page(root, virt_to_pte_phys(root, pagebuf), 0); + cc = modify_subchannel_key_1(test_device_sid, (struct schib *)0); + install_page(root, 0, 0); + if (!cc) { + WRITE_ONCE(schib->pmcw.intparm, 0); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 600, "fetched from SCHIB"); + } else { + report_fail("MSCH cc != 0"); + } + report_prefix_pop(); + + schib->pmcw.intparm = 0; + if (!msch(test_device_sid, schib)) { + report_prefix_push("fetch-protection override does not apply"); + schib->pmcw.intparm = 700; + no_override_schib = (struct schib *)(pagebuf + 2048); + memcpy(no_override_schib, schib, sizeof(struct schib)); + set_storage_key(pagebuf, 0x28, 0); + expect_pgm_int(); + install_page(root, virt_to_pte_phys(root, pagebuf), 0); + modify_subchannel_key_1(test_device_sid, OPAQUE_PTR(2048)); + install_page(root, 0, 0); + check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); + cc = stsch(test_device_sid, schib); + report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); + report_prefix_pop(); + } else { + report_fail("could not reset SCHIB"); + } + + ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); + register_pgm_cleanup_func(NULL); + report_prefix_pop(); + set_storage_key(schib, 0x00, 0); + report_prefix_pop(); +} + int main(void) { report_prefix_push("skey"); @@ -442,9 +715,11 @@ int main(void) test_chg(); test_test_protection(); test_store_cpu_address(); + test_channel_subsystem_call(); setup_vm(); test_set_prefix(); + test_msch(); done: report_prefix_pop(); return report_summary(); diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index 8e52f560..f7b1fc3d 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -41,6 +41,7 @@ file = sthyi.elf [skey] file = skey.elf +extra_params = -device virtio-net-ccw [diag10] file = diag10.elf