From patchwork Fri Feb 23 17:42:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudio Imbrenda X-Patchwork-Id: 877229 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3znz9D4W6Dz9sW7 for ; Sat, 24 Feb 2018 04:43:44 +1100 (AEDT) Received: from localhost ([::1]:46379 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHNm-0003ho-LF for incoming@patchwork.ozlabs.org; Fri, 23 Feb 2018 12:43:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43202) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHNG-0003gZ-7F for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1epHNB-0008H3-2D for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:10 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:42108 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1epHNA-0008G0-LV for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:04 -0500 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1NHe7xI112920 for ; Fri, 23 Feb 2018 12:43:04 -0500 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0b-001b2d01.pphosted.com with ESMTP id 2gaphvapds-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 23 Feb 2018 12:43:03 -0500 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 23 Feb 2018 17:43:02 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 23 Feb 2018 17:43:00 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1NHgxHG37879966; Fri, 23 Feb 2018 17:43:00 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BAADB11C052; Fri, 23 Feb 2018 17:35:59 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7A78911C050; Fri, 23 Feb 2018 17:35:59 +0000 (GMT) Received: from p-imbrenda.boeblingen.de.ibm.com (unknown [9.152.224.168]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Fri, 23 Feb 2018 17:35:59 +0000 (GMT) From: Claudio Imbrenda To: cohuck@redhat.com Date: Fri, 23 Feb 2018 18:42:56 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> References: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18022317-0040-0000-0000-0000043716C7 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022317-0041-0000-0000-000020D93587 Message-Id: <1519407778-23095-2-git-send-email-imbrenda@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-23_06:, , 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-1802230217 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v4 1/3] s390x/sclp: proper support of larger send and receive masks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: borntraeger@de.ibm.com, qemu-s390x@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Until 67915de9f0383ccf4a ("s390x/event-facility: variable-length event masks") we only supported sclp event masks with a size of exactly 4 bytes, even though the architecture allows the guests to set up sclp event masks from 1 to 1021 bytes in length. After that patch, the behaviour was almost compliant, but some issues were still remaining, in particular regarding the handling of selective reads and migration. When setting the sclp event mask, a mask size is also specified. Until now we only considered the size in order to decide which bits to save in the internal state. On the other hand, when a guest performs a selective read, it sends a mask, but it does not specify a size; the implied size is the size of the last mask that has been set. Specifying bits in the mask of selective read that are not available in the internal mask should return an error, and bits past the end of the mask should obviously be ignored. This can only be achieved by keeping track of the lenght of the mask. The mask length is thus now part of the internal state that needs to be migrated. This patch fixes the handling of selective reads, whose size will now match the length of the event mask, as per architecture. While the default behaviour is to be compliant with the architecture, when using older machine models the old broken behaviour is selected (allowing only masks of size exactly 4), in order to be able to migrate toward older versions. Fixes: 67915de9f0383ccf4a ("s390x/event-facility: variable-length event masks") Signed-off-by: Claudio Imbrenda Reviewed-by: Christian Borntraeger --- hw/s390x/event-facility.c | 81 ++++++++++++++++++++++++++++++++++++++-------- hw/s390x/s390-virtio-ccw.c | 8 ++++- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 155a694..9233892 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -31,6 +31,15 @@ struct SCLPEventFacility { SCLPEventsBus sbus; /* guest' receive mask */ unsigned int receive_mask; + /* + * when false, we keep the same broken, backwards compatible behaviour as + * before, allowing only masks of size exactly 4; when true, we implement + * the architecture correctly, allowing all valid mask sizes. Needed for + * migration toward older versions. + */ + bool allow_all_mask_sizes; + /* length of the receive mask */ + uint16_t mask_length; }; /* return true if any child has event pending set */ @@ -220,6 +229,17 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, return rc; } +/* copy up to src_len bytes and fill the rest of dst with zeroes */ +static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len, + uint16_t src_len) +{ + int i; + + for (i = 0; i < dst_len; i++) { + dst[i] = i < src_len ? src[i] : 0; + } +} + static void read_event_data(SCLPEventFacility *ef, SCCB *sccb) { unsigned int sclp_active_selection_mask; @@ -240,7 +260,9 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb) sclp_active_selection_mask = sclp_cp_receive_mask; break; case SCLP_SELECTIVE_READ: - sclp_active_selection_mask = be32_to_cpu(red->mask); + copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask, + sizeof(sclp_active_selection_mask), ef->mask_length); + sclp_active_selection_mask = be32_to_cpu(sclp_active_selection_mask); if (!sclp_cp_receive_mask || (sclp_active_selection_mask & ~sclp_cp_receive_mask)) { sccb->h.response_code = @@ -259,24 +281,14 @@ out: return; } -/* copy up to dst_len bytes and fill the rest of dst with zeroes */ -static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len, - uint16_t src_len) -{ - int i; - - for (i = 0; i < dst_len; i++) { - dst[i] = i < src_len ? src[i] : 0; - } -} - static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb) { WriteEventMask *we_mask = (WriteEventMask *) sccb; uint16_t mask_length = be16_to_cpu(we_mask->mask_length); uint32_t tmp_mask; - if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX)) { + if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) || + ((mask_length != 4) && !ef->allow_all_mask_sizes)) { sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH); goto out; } @@ -301,6 +313,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb) mask_length, sizeof(tmp_mask)); sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION); + ef->mask_length = mask_length; out: return; @@ -356,6 +369,24 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } +static bool vmstate_event_facility_mask_length_needed(void *opaque) +{ + SCLPEventFacility *ef = opaque; + + return ef->allow_all_mask_sizes; +} + +static const VMStateDescription vmstate_event_facility_mask_length = { + .name = "vmstate-event-facility/mask_length", + .version_id = 0, + .minimum_version_id = 0, + .needed = vmstate_event_facility_mask_length_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT16(mask_length, SCLPEventFacility), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_event_facility = { .name = "vmstate-event-facility", .version_id = 0, @@ -363,15 +394,39 @@ static const VMStateDescription vmstate_event_facility = { .fields = (VMStateField[]) { VMSTATE_UINT32(receive_mask, SCLPEventFacility), VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &vmstate_event_facility_mask_length, + NULL } }; +static void sclp_event_set_allow_all_mask_sizes(Object *obj, bool value, + Error **errp) +{ + SCLPEventFacility *ef = (SCLPEventFacility *)obj; + + ef->allow_all_mask_sizes = value; +} + +static bool sclp_event_get_allow_all_mask_sizes(Object *obj, Error **e) +{ + SCLPEventFacility *ef = (SCLPEventFacility *)obj; + + return ef->allow_all_mask_sizes; +} + static void init_event_facility(Object *obj) { SCLPEventFacility *event_facility = EVENT_FACILITY(obj); DeviceState *sdev = DEVICE(obj); Object *new; + event_facility->mask_length = 4; + event_facility->allow_all_mask_sizes = true; + object_property_add_bool(obj, "allow_all_mask_sizes", + sclp_event_get_allow_all_mask_sizes, + sclp_event_set_allow_all_mask_sizes, NULL); /* Spawn a new bus for SCLP events */ qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus), TYPE_SCLP_EVENTS_BUS, sdev, NULL); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 8b3053f..e9309fd 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -29,6 +29,7 @@ #include "s390-pci-bus.h" #include "hw/s390x/storage-keys.h" #include "hw/s390x/storage-attributes.h" +#include "hw/s390x/event-facility.h" #include "hw/compat.h" #include "ipl.h" #include "hw/s390x/s390-virtio-ccw.h" @@ -671,7 +672,12 @@ bool css_migration_enabled(void) type_init(ccw_machine_register_##suffix) #define CCW_COMPAT_2_11 \ - HW_COMPAT_2_11 + HW_COMPAT_2_11 \ + {\ + .driver = TYPE_SCLP_EVENT_FACILITY,\ + .property = "allow_all_mask_sizes",\ + .value = "off",\ + }, #define CCW_COMPAT_2_10 \ HW_COMPAT_2_10 From patchwork Fri Feb 23 17:42:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudio Imbrenda X-Patchwork-Id: 877228 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3znz9C117sz9sW7 for ; Sat, 24 Feb 2018 04:43:43 +1100 (AEDT) Received: from localhost ([::1]:46376 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHNl-0003hJ-6h for incoming@patchwork.ozlabs.org; Fri, 23 Feb 2018 12:43:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43207) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHNG-0003ga-JP for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1epHNC-0008Ji-Jq for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:10 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:53868 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1epHNC-0008Ic-Ez for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:43:06 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1NHe3Oq131013 for ; Fri, 23 Feb 2018 12:43:05 -0500 Received: from e06smtp10.uk.ibm.com (e06smtp10.uk.ibm.com [195.75.94.106]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gapm4thtn-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 23 Feb 2018 12:43:05 -0500 Received: from localhost by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 23 Feb 2018 17:43:04 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 23 Feb 2018 17:43:01 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1NHh1HA45744240; Fri, 23 Feb 2018 17:43:01 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0ADF411C050; Fri, 23 Feb 2018 17:36:01 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C927511C04A; Fri, 23 Feb 2018 17:36:00 +0000 (GMT) Received: from p-imbrenda.boeblingen.de.ibm.com (unknown [9.152.224.168]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Fri, 23 Feb 2018 17:36:00 +0000 (GMT) From: Claudio Imbrenda To: cohuck@redhat.com Date: Fri, 23 Feb 2018 18:42:57 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> References: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18022317-0040-0000-0000-000004160D3E X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022317-0041-0000-0000-0000261927E1 Message-Id: <1519407778-23095-3-git-send-email-imbrenda@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-23_06:, , 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-1802230217 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v4 2/3] s390x/sclp: clean up sclp masks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: borntraeger@de.ibm.com, qemu-s390x@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Introduce an sccb_mask_t to be used for SCLP event masks instead of just unsigned int or uint32_t. This will allow later to extend the mask with more ease. Signed-off-by: Claudio Imbrenda Reviewed-by: Christian Borntraeger --- hw/char/sclpconsole-lm.c | 4 ++-- hw/char/sclpconsole.c | 4 ++-- hw/s390x/event-facility.c | 20 ++++++++++---------- hw/s390x/sclpcpu.c | 4 ++-- hw/s390x/sclpquiesce.c | 4 ++-- include/hw/s390x/event-facility.h | 22 +++++++++++++--------- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index c500bda..cc4d70a 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -102,12 +102,12 @@ static bool can_handle_event(uint8_t type) return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD; } -static unsigned int send_mask(void) +static sccb_mask_t send_mask(void) { return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD; } -static unsigned int receive_mask(void) +static sccb_mask_t receive_mask(void) { return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD; } diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index d0265df..ec9db13 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -83,12 +83,12 @@ static bool can_handle_event(uint8_t type) return type == SCLP_EVENT_ASCII_CONSOLE_DATA; } -static unsigned int send_mask(void) +static sccb_mask_t send_mask(void) { return SCLP_EVENT_MASK_MSG_ASCII; } -static unsigned int receive_mask(void) +static sccb_mask_t receive_mask(void) { return SCLP_EVENT_MASK_MSG_ASCII; } diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 9233892..e04ed9f 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -29,8 +29,8 @@ typedef struct SCLPEventsBus { struct SCLPEventFacility { SysBusDevice parent_obj; SCLPEventsBus sbus; - /* guest' receive mask */ - unsigned int receive_mask; + /* guest's receive mask */ + sccb_mask_t receive_mask; /* * when false, we keep the same broken, backwards compatible behaviour as * before, allowing only masks of size exactly 4; when true, we implement @@ -61,9 +61,9 @@ static bool event_pending(SCLPEventFacility *ef) return false; } -static unsigned int get_host_send_mask(SCLPEventFacility *ef) +static sccb_mask_t get_host_send_mask(SCLPEventFacility *ef) { - unsigned int mask; + sccb_mask_t mask; BusChild *kid; SCLPEventClass *child; @@ -77,9 +77,9 @@ static unsigned int get_host_send_mask(SCLPEventFacility *ef) return mask; } -static unsigned int get_host_receive_mask(SCLPEventFacility *ef) +static sccb_mask_t get_host_receive_mask(SCLPEventFacility *ef) { - unsigned int mask; + sccb_mask_t mask; BusChild *kid; SCLPEventClass *child; @@ -189,7 +189,7 @@ out: } static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, - unsigned int mask) + sccb_mask_t mask) { uint16_t rc; int slen; @@ -242,8 +242,8 @@ static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len, static void read_event_data(SCLPEventFacility *ef, SCCB *sccb) { - unsigned int sclp_active_selection_mask; - unsigned int sclp_cp_receive_mask; + sccb_mask_t sclp_active_selection_mask; + sccb_mask_t sclp_cp_receive_mask; ReadEventData *red = (ReadEventData *) sccb; @@ -285,7 +285,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb) { WriteEventMask *we_mask = (WriteEventMask *) sccb; uint16_t mask_length = be16_to_cpu(we_mask->mask_length); - uint32_t tmp_mask; + sccb_mask_t tmp_mask; if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) || ((mask_length != 4) && !ef->allow_all_mask_sizes)) { diff --git a/hw/s390x/sclpcpu.c b/hw/s390x/sclpcpu.c index 3ee890b..50c021b 100644 --- a/hw/s390x/sclpcpu.c +++ b/hw/s390x/sclpcpu.c @@ -37,12 +37,12 @@ void raise_irq_cpu_hotplug(void) sclp_service_interrupt(0); } -static unsigned int send_mask(void) +static sccb_mask_t send_mask(void) { return SCLP_EVENT_MASK_CONFIG_MGT_DATA; } -static unsigned int receive_mask(void) +static sccb_mask_t receive_mask(void) { return 0; } diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 0241643..1c8f5c9 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -28,12 +28,12 @@ static bool can_handle_event(uint8_t type) return type == SCLP_EVENT_SIGNAL_QUIESCE; } -static unsigned int send_mask(void) +static sccb_mask_t send_mask(void) { return SCLP_EVENT_MASK_SIGNAL_QUIESCE; } -static unsigned int receive_mask(void) +static sccb_mask_t receive_mask(void) { return 0; } diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 5119b9b..0e2b761 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -28,12 +28,14 @@ #define SCLP_EVENT_SIGNAL_QUIESCE 0x1d /* SCLP event masks */ -#define SCLP_EVENT_MASK_SIGNAL_QUIESCE 0x00000008 -#define SCLP_EVENT_MASK_MSG_ASCII 0x00000040 -#define SCLP_EVENT_MASK_CONFIG_MGT_DATA 0x10000000 -#define SCLP_EVENT_MASK_OP_CMD 0x80000000 -#define SCLP_EVENT_MASK_MSG 0x40000000 -#define SCLP_EVENT_MASK_PMSGCMD 0x00800000 +#define SCLP_EVMASK(T) (1ULL << (sizeof(sccb_mask_t) * 8 - (T))) + +#define SCLP_EVENT_MASK_OP_CMD SCLP_EVMASK(SCLP_EVENT_OPRTNS_COMMAND) +#define SCLP_EVENT_MASK_MSG SCLP_EVMASK(SCLP_EVENT_MESSAGE) +#define SCLP_EVENT_MASK_CONFIG_MGT_DATA SCLP_EVMASK(SCLP_EVENT_CONFIG_MGT_DATA) +#define SCLP_EVENT_MASK_PMSGCMD SCLP_EVMASK(SCLP_EVENT_PMSGCMD) +#define SCLP_EVENT_MASK_MSG_ASCII SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA) +#define SCLP_EVENT_MASK_SIGNAL_QUIESCE SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE) #define SCLP_UNCONDITIONAL_READ 0x00 #define SCLP_SELECTIVE_READ 0x01 @@ -71,6 +73,8 @@ typedef struct WriteEventMask { #define WEM_RECEIVE_MASK(wem, mask_len) ((wem)->masks + 2 * (mask_len)) #define WEM_SEND_MASK(wem, mask_len) ((wem)->masks + 3 * (mask_len)) +typedef uint32_t sccb_mask_t; + typedef struct EventBufferHeader { uint16_t length; uint8_t type; @@ -160,7 +164,7 @@ typedef struct WriteEventData { typedef struct ReadEventData { SCCBHeader h; union { - uint32_t mask; + sccb_mask_t mask; EventBufferHeader ebh; }; } QEMU_PACKED ReadEventData; @@ -177,10 +181,10 @@ typedef struct SCLPEventClass { int (*exit)(SCLPEvent *event); /* get SCLP's send mask */ - unsigned int (*get_send_mask)(void); + sccb_mask_t (*get_send_mask)(void); /* get SCLP's receive mask */ - unsigned int (*get_receive_mask)(void); + sccb_mask_t (*get_receive_mask)(void); int (*read_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, int *slen); From patchwork Fri Feb 23 17:42:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudio Imbrenda X-Patchwork-Id: 877239 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3znzNt0jYsz9sW7 for ; Sat, 24 Feb 2018 04:53:50 +1100 (AEDT) Received: from localhost ([::1]:46417 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHXY-0001Ox-8g for incoming@patchwork.ozlabs.org; Fri, 23 Feb 2018 12:53:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46289) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1epHXC-0001O8-7b for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:53:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1epHX8-0007Sq-99 for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:53:26 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:41472 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1epHX8-0007Rv-3D for qemu-devel@nongnu.org; Fri, 23 Feb 2018 12:53:22 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1NHmhHq015074 for ; Fri, 23 Feb 2018 12:53:21 -0500 Received: from e06smtp10.uk.ibm.com (e06smtp10.uk.ibm.com [195.75.94.106]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gapm4twa6-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 23 Feb 2018 12:53:20 -0500 Received: from localhost by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 23 Feb 2018 17:43:06 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 23 Feb 2018 17:43:02 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1NHh21v25624618; Fri, 23 Feb 2018 17:43:02 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4F76E11C054; Fri, 23 Feb 2018 17:36:02 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1978E11C052; Fri, 23 Feb 2018 17:36:02 +0000 (GMT) Received: from p-imbrenda.boeblingen.de.ibm.com (unknown [9.152.224.168]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Fri, 23 Feb 2018 17:36:02 +0000 (GMT) From: Claudio Imbrenda To: cohuck@redhat.com Date: Fri, 23 Feb 2018 18:42:58 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> References: <1519407778-23095-1-git-send-email-imbrenda@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18022317-0040-0000-0000-000004160D3F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022317-0041-0000-0000-0000261927E2 Message-Id: <1519407778-23095-4-git-send-email-imbrenda@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-23_06:, , 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-1802230219 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v4 3/3] s390x/sclp: extend SCLP event masks to 64 bits X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: borntraeger@de.ibm.com, qemu-s390x@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Extend the SCLP event masks to 64 bits. Notice that using any of the new bits results in a state that cannot be migrated to an older version. Signed-off-by: Claudio Imbrenda --- hw/s390x/event-facility.c | 56 ++++++++++++++++++++++++++++++--------- include/hw/s390x/event-facility.h | 2 +- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index e04ed9f..c3e39ee 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -30,7 +30,7 @@ struct SCLPEventFacility { SysBusDevice parent_obj; SCLPEventsBus sbus; /* guest's receive mask */ - sccb_mask_t receive_mask; + uint32_t receive_mask_pieces[2]; /* * when false, we keep the same broken, backwards compatible behaviour as * before, allowing only masks of size exactly 4; when true, we implement @@ -42,6 +42,18 @@ struct SCLPEventFacility { uint16_t mask_length; }; +static inline sccb_mask_t make_receive_mask(SCLPEventFacility *ef) +{ + return ((sccb_mask_t)ef->receive_mask_pieces[0]) << 32 | + ef->receive_mask_pieces[1]; +} + +static inline void store_receive_mask(SCLPEventFacility *ef, sccb_mask_t val) +{ + ef->receive_mask_pieces[1] = val; + ef->receive_mask_pieces[0] = val >> 32; +} + /* return true if any child has event pending set */ static bool event_pending(SCLPEventFacility *ef) { @@ -54,7 +66,7 @@ static bool event_pending(SCLPEventFacility *ef) event = DO_UPCAST(SCLPEvent, qdev, qdev); event_class = SCLP_EVENT_GET_CLASS(event); if (event->event_pending && - event_class->get_send_mask() & ef->receive_mask) { + event_class->get_send_mask() & make_receive_mask(ef)) { return true; } } @@ -252,7 +264,7 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb) goto out; } - sclp_cp_receive_mask = ef->receive_mask; + sclp_cp_receive_mask = make_receive_mask(ef); /* get active selection mask */ switch (sccb->h.function_code) { @@ -262,7 +274,7 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb) case SCLP_SELECTIVE_READ: copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask, sizeof(sclp_active_selection_mask), ef->mask_length); - sclp_active_selection_mask = be32_to_cpu(sclp_active_selection_mask); + sclp_active_selection_mask = be64_to_cpu(sclp_active_selection_mask); if (!sclp_cp_receive_mask || (sclp_active_selection_mask & ~sclp_cp_receive_mask)) { sccb->h.response_code = @@ -294,21 +306,22 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb) } /* - * Note: We currently only support masks up to 4 byte length; - * the remainder is filled up with zeroes. Linux uses - * a 4 byte mask length. + * Note: We currently only support masks up to 8 byte length; + * the remainder is filled up with zeroes. Older Linux + * kernels use a 4 byte mask length, newer ones can use both + * 8 or 4 depending on what is available on the host. */ /* keep track of the guest's capability masks */ copy_mask((uint8_t *)&tmp_mask, WEM_CP_RECEIVE_MASK(we_mask, mask_length), sizeof(tmp_mask), mask_length); - ef->receive_mask = be32_to_cpu(tmp_mask); + store_receive_mask(ef, be64_to_cpu(tmp_mask)); /* return the SCLP's capability masks to the guest */ - tmp_mask = cpu_to_be32(get_host_receive_mask(ef)); + tmp_mask = cpu_to_be64(get_host_receive_mask(ef)); copy_mask(WEM_RECEIVE_MASK(we_mask, mask_length), (uint8_t *)&tmp_mask, mask_length, sizeof(tmp_mask)); - tmp_mask = cpu_to_be32(get_host_send_mask(ef)); + tmp_mask = cpu_to_be64(get_host_send_mask(ef)); copy_mask(WEM_SEND_MASK(we_mask, mask_length), (uint8_t *)&tmp_mask, mask_length, sizeof(tmp_mask)); @@ -369,6 +382,13 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } +static bool vmstate_event_facility_mask64_needed(void *opaque) +{ + SCLPEventFacility *ef = opaque; + + return ef->receive_mask_pieces[1] != 0; +} + static bool vmstate_event_facility_mask_length_needed(void *opaque) { SCLPEventFacility *ef = opaque; @@ -376,6 +396,17 @@ static bool vmstate_event_facility_mask_length_needed(void *opaque) return ef->allow_all_mask_sizes; } +static const VMStateDescription vmstate_event_facility_mask64 = { + .name = "vmstate-event-facility/mask64", + .version_id = 0, + .minimum_version_id = 0, + .needed = vmstate_event_facility_mask64_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32(receive_mask_pieces[1], SCLPEventFacility), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_event_facility_mask_length = { .name = "vmstate-event-facility/mask_length", .version_id = 0, @@ -392,10 +423,11 @@ static const VMStateDescription vmstate_event_facility = { .version_id = 0, .minimum_version_id = 0, .fields = (VMStateField[]) { - VMSTATE_UINT32(receive_mask, SCLPEventFacility), + VMSTATE_UINT32(receive_mask_pieces[0], SCLPEventFacility), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription * []) { + &vmstate_event_facility_mask64, &vmstate_event_facility_mask_length, NULL } @@ -447,7 +479,7 @@ static void reset_event_facility(DeviceState *dev) { SCLPEventFacility *sdev = EVENT_FACILITY(dev); - sdev->receive_mask = 0; + store_receive_mask(sdev, 0); } static void init_event_facility_class(ObjectClass *klass, void *data) diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 0e2b761..06ba4ea 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -73,7 +73,7 @@ typedef struct WriteEventMask { #define WEM_RECEIVE_MASK(wem, mask_len) ((wem)->masks + 2 * (mask_len)) #define WEM_SEND_MASK(wem, mask_len) ((wem)->masks + 3 * (mask_len)) -typedef uint32_t sccb_mask_t; +typedef uint64_t sccb_mask_t; typedef struct EventBufferHeader { uint16_t length;