From patchwork Fri Jan 18 11:42:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janosch Frank X-Patchwork-Id: 10769809 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 305191390 for ; Fri, 18 Jan 2019 11:43:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EC4C2D1D8 for ; Fri, 18 Jan 2019 11:43:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 131962E1F8; Fri, 18 Jan 2019 11:43:07 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 84CC02D1D8 for ; Fri, 18 Jan 2019 11:43:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727423AbfARLnF (ORCPT ); Fri, 18 Jan 2019 06:43:05 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:34686 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727440AbfARLnF (ORCPT ); Fri, 18 Jan 2019 06:43:05 -0500 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x0IBgbpk044786 for ; Fri, 18 Jan 2019 06:43:03 -0500 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0b-001b2d01.pphosted.com with ESMTP id 2q3e5k00jq-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 18 Jan 2019 06:43:03 -0500 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 18 Jan 2019 11:43:01 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 18 Jan 2019 11:43:00 -0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x0IBgxcg5374260 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 18 Jan 2019 11:42:59 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 02B9F4C046; Fri, 18 Jan 2019 11:42:59 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 64B3D4C040; Fri, 18 Jan 2019 11:42:58 +0000 (GMT) Received: from s38lp20.lnxne.boe (unknown [9.145.153.8]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 18 Jan 2019 11:42:58 +0000 (GMT) From: Janosch Frank To: kvm@vger.kernel.org Cc: linux-s390@vger.kernel.org, david@redhat.com, thuth@redhat.com Subject: [kvm-unit-tests PATCH v6 07/11] s390x: Use interrupts in SCLP and add locking Date: Fri, 18 Jan 2019 12:42:00 +0100 X-Mailer: git-send-email 2.14.3 In-Reply-To: <20190118114204.147868-1-frankja@linux.ibm.com> References: <20190118114204.147868-1-frankja@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 19011811-0016-0000-0000-0000024730F0 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19011811-0017-0000-0000-000032A1592B Message-Id: <20190118114204.147868-8-frankja@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-01-18_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 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901180088 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We need to properly implement interrupt handling for SCLP, because on z/VM and LPAR SCLP calls are not synchronous! Also with smp CPUs have to compete for sclp. Let's add some locking, so they execute sclp calls in an orderly fashion and don't compete for the data buffer. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth --- lib/s390x/asm/arch_def.h | 1 + lib/s390x/asm/interrupt.h | 2 ++ lib/s390x/interrupt.c | 12 +++++++++-- lib/s390x/sclp-console.c | 2 ++ lib/s390x/sclp.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-- lib/s390x/sclp.h | 3 +++ 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h index d2cd727..4bbb428 100644 --- a/lib/s390x/asm/arch_def.h +++ b/lib/s390x/asm/arch_def.h @@ -15,6 +15,7 @@ struct psw { uint64_t addr; }; +#define PSW_MASK_EXT 0x0100000000000000UL #define PSW_MASK_DAT 0x0400000000000000UL #define PSW_MASK_PSTATE 0x0001000000000000UL diff --git a/lib/s390x/asm/interrupt.h b/lib/s390x/asm/interrupt.h index 013709f..f485e96 100644 --- a/lib/s390x/asm/interrupt.h +++ b/lib/s390x/asm/interrupt.h @@ -11,6 +11,8 @@ #define _ASMS390X_IRQ_H_ #include +#define EXT_IRQ_SERVICE_SIG 0x2401 + void handle_pgm_int(void); void handle_ext_int(void); void handle_mcck_int(void); diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c index cf0a794..7832711 100644 --- a/lib/s390x/interrupt.c +++ b/lib/s390x/interrupt.c @@ -12,6 +12,7 @@ #include #include #include +#include static bool pgm_int_expected; static struct lowcore *lc; @@ -107,8 +108,15 @@ void handle_pgm_int(void) void handle_ext_int(void) { - report_abort("Unexpected external call interrupt: at %#lx", - lc->ext_old_psw.addr); + if (lc->ext_int_code != EXT_IRQ_SERVICE_SIG) { + report_abort("Unexpected external call interrupt: at %#lx", + lc->ext_old_psw.addr); + } else { + lc->ext_old_psw.mask &= ~PSW_MASK_EXT; + lc->sw_int_cr0 &= ~(1UL << 9); + sclp_handle_ext(); + lc->ext_int_code = 0; + } } void handle_mcck_int(void) diff --git a/lib/s390x/sclp-console.c b/lib/s390x/sclp-console.c index bc01f41..a5ef45f 100644 --- a/lib/s390x/sclp-console.c +++ b/lib/s390x/sclp-console.c @@ -17,6 +17,7 @@ static void sclp_set_write_mask(void) { WriteEventMask *sccb = (void *)_sccb; + sclp_mark_busy(); sccb->h.length = sizeof(WriteEventMask); sccb->mask_length = sizeof(unsigned int); sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII; @@ -37,6 +38,7 @@ void sclp_print(const char *str) int len = strlen(str); WriteEventData *sccb = (void *)_sccb; + sclp_mark_busy(); sccb->h.length = sizeof(WriteEventData) + len; sccb->h.function_code = SCLP_FC_NORMAL_WRITE; sccb->ebh.length = sizeof(EventBufferHeader) + len; diff --git a/lib/s390x/sclp.c b/lib/s390x/sclp.c index 7f556e5..9876db3 100644 --- a/lib/s390x/sclp.c +++ b/lib/s390x/sclp.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "sclp.h" #include @@ -24,6 +26,8 @@ static uint64_t max_ram_size; static uint64_t ram_size; char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096))); +static volatile bool sclp_busy; +static struct spinlock sclp_lock; static void mem_init(phys_addr_t mem_end) { @@ -32,17 +36,61 @@ static void mem_init(phys_addr_t mem_end) phys_alloc_init(freemem_start, mem_end - freemem_start); } +static void sclp_setup_int(void) +{ + uint64_t mask; + + ctl_set_bit(0, 9); + + mask = extract_psw_mask(); + mask |= PSW_MASK_EXT; + load_psw_mask(mask); +} + +void sclp_handle_ext(void) +{ + ctl_clear_bit(0, 9); + spin_lock(&sclp_lock); + sclp_busy = false; + spin_unlock(&sclp_lock); +} + +void sclp_wait_busy(void) +{ + while (sclp_busy) + mb(); +} + +void sclp_mark_busy(void) +{ + /* + * With multiple CPUs we might need to wait for another CPU's + * request before grabbing the busy indication. + */ +retry_wait: + sclp_wait_busy(); + spin_lock(&sclp_lock); + if (sclp_busy) { + spin_unlock(&sclp_lock); + goto retry_wait; + } + sclp_busy = true; + spin_unlock(&sclp_lock); +} + static void sclp_read_scp_info(ReadInfo *ri, int length) { unsigned int commands[] = { SCLP_CMDW_READ_SCP_INFO_FORCED, SCLP_CMDW_READ_SCP_INFO }; - int i; + int i, cc; for (i = 0; i < ARRAY_SIZE(commands); i++) { + sclp_mark_busy(); memset(&ri->h, 0, sizeof(ri->h)); ri->h.length = length; - if (sclp_service_call(commands[i], ri)) + cc = sclp_service_call(commands[i], ri); + if (cc) break; if (ri->h.response_code == SCLP_RC_NORMAL_READ_COMPLETION) return; @@ -57,12 +105,14 @@ int sclp_service_call(unsigned int command, void *sccb) { int cc; + sclp_setup_int(); asm volatile( " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ " ipm %0\n" " srl %0,28" : "=&d" (cc) : "d" (command), "a" (__pa(sccb)) : "cc", "memory"); + sclp_wait_busy(); if (cc == 3) return -1; if (cc == 2) diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h index 583c4e5..63cf609 100644 --- a/lib/s390x/sclp.h +++ b/lib/s390x/sclp.h @@ -213,6 +213,9 @@ typedef struct ReadEventData { } __attribute__((packed)) ReadEventData; extern char _sccb[]; +void sclp_handle_ext(void); +void sclp_wait_busy(void); +void sclp_mark_busy(void); void sclp_console_setup(void); void sclp_print(const char *str); int sclp_service_call(unsigned int command, void *sccb);