From patchwork Thu Feb 12 17:09:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 439281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 54F42140146 for ; Fri, 13 Feb 2015 04:22:51 +1100 (AEDT) Received: from localhost ([::1]:51415 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLxTV-0007Hk-41 for incoming@patchwork.ozlabs.org; Thu, 12 Feb 2015 12:22:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44814) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLxHn-0003pN-Ak for qemu-devel@nongnu.org; Thu, 12 Feb 2015 12:10:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YLxHh-0008Iu-Dd for qemu-devel@nongnu.org; Thu, 12 Feb 2015 12:10:43 -0500 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:42084) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLxHh-0008Ig-5h for qemu-devel@nongnu.org; Thu, 12 Feb 2015 12:10:37 -0500 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 12 Feb 2015 17:10:36 -0000 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 12 Feb 2015 17:10:33 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 8F0E217D806C for ; Thu, 12 Feb 2015 17:10:44 +0000 (GMT) Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1CH9mNU1245532 for ; Thu, 12 Feb 2015 17:09:48 GMT Received: from d06av01.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1CH9kcF025369 for ; Thu, 12 Feb 2015 10:09:47 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1CH9kR9025356; Thu, 12 Feb 2015 10:09:46 -0700 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 1122) id B3A91122446B; Thu, 12 Feb 2015 18:09:45 +0100 (CET) From: Jens Freimann To: Christian Borntraeger , Alexander Graf , Cornelia Huck Date: Thu, 12 Feb 2015 18:09:37 +0100 Message-Id: <1423760982-8474-21-git-send-email-jfrei@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1423760982-8474-1-git-send-email-jfrei@linux.vnet.ibm.com> References: <1423760982-8474-1-git-send-email-jfrei@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15021217-0009-0000-0000-000003217081 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.108 Cc: Jens Freimann , qemu-devel@nongnu.org, Thomas Huth Subject: [Qemu-devel] [PATCH 20/25] s390x/ioinst: Rework memory access in TSCH instruction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Thomas Huth Change the TSCH handler to use the new logical memory access functions. Since the channel should not be updated in case of a protection or access exception while writing to the guest memory, the css_do_tsch() has to be split up into two parts, one for retrieving the IRB and one for the update. Signed-off-by: Thomas Huth Signed-off-by: Jens Freimann Reviewed-by: Cornelia Huck --- hw/s390x/css.c | 38 +++++++++++++++++++++++--------------- target-s390x/cpu.h | 3 ++- target-s390x/ioinst.c | 33 +++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 65e6b71..f6d0c0a 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -801,7 +801,8 @@ out: return ret; } -static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) +static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw, + int *irb_len) { int i; uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL; @@ -815,6 +816,8 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) { dest->ecw[i] = cpu_to_be32(src->ecw[i]); } + *irb_len = sizeof(*dest) - sizeof(dest->emw); + /* extended measurements enabled? */ if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) || !(pmcw->flags & PMCW_FLAGS_MASK_TF) || @@ -832,26 +835,21 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) dest->emw[i] = cpu_to_be32(src->emw[i]); } } + *irb_len = sizeof(*dest); } -int css_do_tsch(SubchDev *sch, IRB *target_irb) +int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; uint16_t stctl; - uint16_t fctl; - uint16_t actl; IRB irb; - int ret; if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) { - ret = 3; - goto out; + return 3; } stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; - fctl = s->ctrl & SCSW_CTRL_MASK_FCTL; - actl = s->ctrl & SCSW_CTRL_MASK_ACTL; /* Prepare the irb for the guest. */ memset(&irb, 0, sizeof(IRB)); @@ -876,7 +874,22 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb) } } /* Store the irb to the guest. */ - copy_irb_to_guest(target_irb, &irb, p); + copy_irb_to_guest(target_irb, &irb, p, irb_len); + + return ((stctl & SCSW_STCTL_STATUS_PEND) == 0); +} + +void css_do_tsch_update_subch(SubchDev *sch) +{ + SCSW *s = &sch->curr_status.scsw; + PMCW *p = &sch->curr_status.pmcw; + uint16_t stctl; + uint16_t fctl; + uint16_t actl; + + stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; + fctl = s->ctrl & SCSW_CTRL_MASK_FCTL; + actl = s->ctrl & SCSW_CTRL_MASK_ACTL; /* Clear conditions on subchannel, if applicable. */ if (stctl & SCSW_STCTL_STATUS_PEND) { @@ -913,11 +926,6 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb) memset(sch->sense_data, 0 , sizeof(sch->sense_data)); } } - - ret = ((stctl & SCSW_STCTL_STATUS_PEND) == 0); - -out: - return ret; } static void copy_crw_to_guest(CRW *dest, const CRW *src) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 7180d68..7c07ca6 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -455,7 +455,8 @@ int css_do_xsch(SubchDev *sch); int css_do_csch(SubchDev *sch); int css_do_hsch(SubchDev *sch); int css_do_ssch(SubchDev *sch, ORB *orb); -int css_do_tsch(SubchDev *sch, IRB *irb); +int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len); +void css_do_tsch_update_subch(SubchDev *sch); int css_do_stcrw(CRW *crw); int css_do_tpi(IOIntCode *int_code, int lowcore); int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c index 8052886..aa55ca8 100644 --- a/target-s390x/ioinst.c +++ b/target-s390x/ioinst.c @@ -341,10 +341,9 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb) CPUS390XState *env = &cpu->env; int cssid, ssid, schid, m; SubchDev *sch; - IRB *irb; + IRB irb; uint64_t addr; - int cc; - hwaddr len = sizeof(*irb); + int cc, irb_len; if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { program_interrupt(env, PGM_OPERAND, 2); @@ -356,23 +355,29 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb) program_interrupt(env, PGM_SPECIFICATION, 2); return -EIO; } - irb = s390_cpu_physical_memory_map(env, addr, &len, 1); - if (!irb || len != sizeof(*irb)) { - program_interrupt(env, PGM_ADDRESSING, 2); - cc = -EIO; - goto out; - } + sch = css_find_subch(m, cssid, ssid, schid); if (sch && css_subch_visible(sch)) { - cc = css_do_tsch(sch, irb); - /* 0 - status pending, 1 - not status pending */ + cc = css_do_tsch_get_irb(sch, &irb, &irb_len); } else { cc = 3; } + /* 0 - status pending, 1 - not status pending, 3 - not operational */ + if (cc != 3) { + if (s390_cpu_virt_mem_write(cpu, addr, &irb, irb_len) != 0) { + return -EFAULT; + } + css_do_tsch_update_subch(sch); + } else { + irb_len = sizeof(irb) - sizeof(irb.emw); + /* Access exceptions have a higher priority than cc3 */ + if (s390_cpu_virt_mem_check_write(cpu, addr, irb_len) != 0) { + return -EFAULT; + } + } + setcc(cpu, cc); -out: - s390_cpu_physical_memory_unmap(env, irb, sizeof(*irb), 1); - return cc; + return 0; } typedef struct ChscReq {