From patchwork Tue Mar 20 11:19:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janosch Frank X-Patchwork-Id: 10296905 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 26DD660385 for ; Tue, 20 Mar 2018 11:20:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 168D628CD4 for ; Tue, 20 Mar 2018 11:20:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0B9D229323; Tue, 20 Mar 2018 11:20:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 85A2F28CD4 for ; Tue, 20 Mar 2018 11:20:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752900AbeCTLUf (ORCPT ); Tue, 20 Mar 2018 07:20:35 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:33622 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752879AbeCTLU1 (ORCPT ); Tue, 20 Mar 2018 07:20:27 -0400 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w2KBKDfu023029 for ; Tue, 20 Mar 2018 07:20:27 -0400 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gu0x1s5s5-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Tue, 20 Mar 2018 07:20:27 -0400 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 20 Mar 2018 11:20:24 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 20 Mar 2018 11:20:22 -0000 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w2KBKLal44433644; Tue, 20 Mar 2018 11:20:21 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 18DEA52041; Tue, 20 Mar 2018 10:11:46 +0000 (GMT) Received: from s38lp20.boeblingen.de.ibm.com (unknown [9.152.224.155]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id DC30D52043; Tue, 20 Mar 2018 10:11:45 +0000 (GMT) From: Janosch Frank To: kvm@vger.kernel.org Cc: thuth@redhat.com, david@redhat.com Subject: [kvm-unit-tests PATCH v2 8/8] s390x: Add simple guarded storage tests Date: Tue, 20 Mar 2018 12:19:36 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521544776-149935-1-git-send-email-frankja@linux.vnet.ibm.com> References: <1521544776-149935-1-git-send-email-frankja@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18032011-0020-0000-0000-000004074274 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18032011-0021-0000-0000-0000429B5B91 Message-Id: <1521544776-149935-9-git-send-email-frankja@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-20_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1803200133 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Guarded storage was introduced with IBM z14. Loads with the special instruction LOAD GUARDED are suspect to access controls if they fall into a guarded area. A handler is called if such an access is detected. The test checks for exceptions if the instructions are executed without cr2 enablement and tests handler execution on load guarded. The initial test case is once again from Martin Schwidefsky with minor adaptions by me for kvm-unit-tests. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth --- s390x/Makefile | 1 + s390x/gs.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 + 3 files changed, 174 insertions(+) create mode 100644 s390x/gs.c diff --git a/s390x/Makefile b/s390x/Makefile index 47013d1..b44efb5 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -8,6 +8,7 @@ tests += $(TEST_DIR)/diag10.elf tests += $(TEST_DIR)/pfmf.elf tests += $(TEST_DIR)/cmm.elf tests += $(TEST_DIR)/vector.elf +tests += $(TEST_DIR)/gs.elf all: directories test_cases diff --git a/s390x/gs.c b/s390x/gs.c new file mode 100644 index 0000000..ea66697 --- /dev/null +++ b/s390x/gs.c @@ -0,0 +1,170 @@ +/* + * Tests guarded storage support. + * + * Copyright 2018 IBM Corp. + * + * Authors: + * Martin Schwidefsky + * Janosch Frank + * + * 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 +#include +#include +#include +#include + +struct gs_cb { + uint64_t reserved; + uint64_t gsd; + uint64_t gssm; + uint64_t gs_epl_a; +}; + +struct gs_epl { + uint8_t pad1; + union { + uint8_t gs_eam; + struct { + uint8_t : 6; + uint8_t e : 1; + uint8_t b : 1; + }; + }; + union { + uint8_t gs_eci; + struct { + uint8_t tx : 1; + uint8_t cx : 1; + uint8_t : 5; + uint8_t in : 1; + }; + }; + union { + uint8_t gs_eai; + struct { + uint8_t : 1; + uint8_t t : 1; + uint8_t as : 2; + uint8_t ar : 4; + }; + }; + uint32_t pad2; + uint64_t gs_eha; + uint64_t gs_eia; + uint64_t gs_eoa; + uint64_t gs_eir; + uint64_t gs_era; +}; + +static volatile int guarded = 0; +static struct gs_cb gs_cb; +static struct gs_epl gs_epl; +static unsigned long gs_area = 0x2000000; + +static inline void load_gs_cb(struct gs_cb *gs_cb) +{ + asm volatile(".insn rxy,0xe3000000004d,0,%0" : : "Q" (*gs_cb)); +} + +static inline void store_gs_cb(struct gs_cb *gs_cb) +{ + asm volatile(".insn rxy,0xe30000000049,0,%0" : : "Q" (*gs_cb)); +} + +static inline unsigned long load_guarded(unsigned long *p) +{ + unsigned long v; + + asm(".insn rxy,0xe3000000004c, %0,%1" + : "=d" (v) + : "m" (*p) + : "r14", "memory"); + return v; +} + +/* guarded-storage event handler and finally it calls gs_handler */ +extern void gs_handler_asm(void); + asm(".globl gs_handler_asm\n" + "gs_handler_asm:\n" + " lgr %r14,%r15\n" /* Save current stack address in r14 */ + " aghi %r15,-320\n" /* Allocate stack frame */ + " stmg %r0,%r14,192(%r15)\n" /* Store regs to save area */ + " stg %r14,312(%r15)\n" + " la %r2,160(%r15)\n" /* Store gscb address in this_cb */ + " .insn rxy,0xe30000000049,0,160(%r15)\n" /* stgsc */ + " lg %r14,24(%r2)\n" /* Get GSEPLA from GSCB*/ + " lg %r14,40(%r14)\n" /* Get GSERA from GSEPL*/ + " stg %r14,304(%r15)\n" /* Store GSEPL in r14 of reg save area */ + " brasl %r14,gs_handler\n" /* Jump to gs_handler */ + " lmg %r0,%r15,192(%r15)\n" /* Restore regs */ + " aghi %r14, 6\n" /* Add lgg instr len to GSERA */ + " br %r14\n" /* Jump to next instruction after lgg */ + " .size gs_handler_asm,.-gs_handler_asm\n"); + +void gs_handler(struct gs_cb *this_cb) +{ + guarded = 1; + struct gs_epl *gs_epl = (struct gs_epl *) this_cb->gs_epl_a; + printf("gs_handler called for %016lx at %016lx\n", + gs_epl->gs_eir, gs_epl->gs_eia); +} + +/* Test if load guarded gets intercepted. */ +static void test_load(void) +{ + unsigned long v; + + guarded = 0; + v = load_guarded(&gs_area); + report("load guarded %ld", guarded, v); + guarded = 0; +} + +/* Test gs instructions without enablement resulting in an exception */ +static void test_special(void) +{ + expect_pgm_int(); + load_gs_cb(&gs_cb); + check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); + expect_pgm_int(); + store_gs_cb(&gs_cb); + check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); +} + +static void init(void) +{ + /* Enable control bit for gs */ + ctl_set_bit(2, 4); + + /* Setup gs registers to guard the gs_area */ + gs_cb.gsd = gs_area | 25; + + /* Check all 512kb slots for events */ + gs_cb.gssm = 0xFFFFFFFFFFFFFFFF; + gs_cb.gs_epl_a = (unsigned long) &gs_epl; + + /* Register handler */ + gs_epl.gs_eha = (unsigned long) gs_handler_asm; + load_gs_cb(&gs_cb); +} + +int main(void) +{ + bool has_gs = test_facility(133); + + report_prefix_push("gs"); + report_xfail("Guarded storage available", !has_gs, has_gs); + if (!has_gs) + goto done; + + test_special(); + init(); + test_load(); + +done: + report_prefix_pop(); + return report_summary(); +} diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index 2ea2bf9..e3c3b2b 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -53,3 +53,6 @@ file = cmm.elf [vector] file = vector.elf + +[gs] +file = gs.elf