From patchwork Fri Jul 13 10:52:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Borntraeger X-Patchwork-Id: 170850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E70092C034B for ; Fri, 13 Jul 2012 20:53:26 +1000 (EST) Received: from localhost ([::1]:35565 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SpdUy-0001NW-6e for incoming@patchwork.ozlabs.org; Fri, 13 Jul 2012 06:53:24 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SpdUJ-0008QR-RP for qemu-devel@nongnu.org; Fri, 13 Jul 2012 06:52:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SpdUD-0007th-VY for qemu-devel@nongnu.org; Fri, 13 Jul 2012 06:52:43 -0400 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:49340) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SpdUD-0007tY-JT for qemu-devel@nongnu.org; Fri, 13 Jul 2012 06:52:37 -0400 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 13 Jul 2012 11:52:36 +0100 Received: from d06nrmr1806.portsmouth.uk.ibm.com (9.149.39.193) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 13 Jul 2012 11:52:13 +0100 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6DAqCKr2785368 for ; Fri, 13 Jul 2012 11:52:12 +0100 Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6DAqAJv030059 for ; Fri, 13 Jul 2012 04:52:11 -0600 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6DAq6Wq029840; Fri, 13 Jul 2012 04:52:07 -0600 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 25651) id 97E88122443D; Fri, 13 Jul 2012 12:52:06 +0200 (CEST) From: Christian Borntraeger To: Alexander Graf Date: Fri, 13 Jul 2012 12:52:02 +0200 Message-Id: <1342176724-43776-5-git-send-email-borntraeger@de.ibm.com> X-Mailer: git-send-email 1.7.10.5 In-Reply-To: <1342176724-43776-1-git-send-email-borntraeger@de.ibm.com> References: <1342176724-43776-1-git-send-email-borntraeger@de.ibm.com> x-cbid: 12071310-8372-0000-0000-0000032CA4E2 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.108 Cc: Cornelia Huck , Christian Borntraeger , Jens Freimann , Heinz Graalfs , qemu-devel Subject: [Qemu-devel] [PATCH 4/6] s390: sclp signal quiesce support 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: Heinz Graalfs This implements the sclp signal quiesce event via the SCLP Event Facility. This allows to gracefully shutdown a guest by using system_powerdown. It creates a service interrupt that will trigger a Read Event Data command from the guest. This code will then add an event that is interpreted by linux guests as ctrl-alt-del. Signed-off-by: Heinz Graalfs Signed-off-by: Christian Borntraeger --- hw/s390-event-facility.c | 6 +++ hw/s390-sclpquiesce.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ hw/s390x/Makefile.objs | 2 +- 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 hw/s390-sclpquiesce.c diff --git a/hw/s390-event-facility.c b/hw/s390-event-facility.c index 42ac102..e3c9c56 100644 --- a/hw/s390-event-facility.c +++ b/hw/s390-event-facility.c @@ -335,6 +335,7 @@ static int command_handler(SCCB *sccb, uint64_t code) static int init_event_facility(S390SCLPDevice *sdev) { SCLPEventFacility *event_facility; + DeviceState *quiesce; event_facility = g_malloc0(sizeof(SCLPEventFacility)); sdev->instance = event_facility; @@ -348,6 +349,11 @@ static int init_event_facility(S390SCLPDevice *sdev) event_facility->sbus.event_facility = event_facility; event_facility->qdev = (DeviceState *) sdev; + quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce"); + if (!quiesce) { + return -1; + } + qdev_init_nofail(quiesce); return 0; } diff --git a/hw/s390-sclpquiesce.c b/hw/s390-sclpquiesce.c new file mode 100644 index 0000000..405664a --- /dev/null +++ b/hw/s390-sclpquiesce.c @@ -0,0 +1,113 @@ +/* + * SCLP event type + * Signal Quiesce - trigger system powerdown request + * + * Copyright IBM, Corp. 2007, 2012 + * + * Authors: + * Heinz Graalfs + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#include "qdev.h" +#include "sysemu.h" + +#include "s390-sclp.h" +#include "s390-event-facility.h" + +typedef struct SignalQuiesce { + EventBufferHeader ebh; + uint16_t timeout; + uint8_t unit; +} __attribute__((packed)) SignalQuiesce; + +static int event_type(void) +{ + return SCLP_EVENT_SIGNAL_QUIESCE; +} + +static unsigned int send_mask(void) +{ + return SCLP_EVENT_MASK_SIGNAL_QUIESCE; +} + +static unsigned int receive_mask(void) +{ + return 0; +} + +static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, + int *slen) +{ + SignalQuiesce *sq = (SignalQuiesce *) evt_buf_hdr; + + if (*slen < sizeof(SignalQuiesce)) { + return 0; + } + + if (!event->event_pending) { + return 0; + } + event->event_pending = false; + + sq->ebh.length = cpu_to_be16(sizeof(SignalQuiesce)); + sq->ebh.type = SCLP_EVENT_SIGNAL_QUIESCE; + sq->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED; + /* + * system_powerdown does not have a timeout. Fortunately the + * timeout value is currently ignored by Linux, anyway + */ + sq->timeout = cpu_to_be16(0); + sq->unit = cpu_to_be16(0); + *slen -= sizeof(SignalQuiesce); + + return 1; +} + +static void trigger_signal_quiesce(void *opaque, int n, int level) +{ + SCLPEvent *event = opaque; + + event->event_pending = true; + /* trigger SCLP read operation */ + sclp_service_interrupt(0); +} + +static int quiesce_init(SCLPEvent *event) +{ + event->event_type = SCLP_EVENT_SIGNAL_QUIESCE; + qemu_system_powerdown = *qemu_allocate_irqs(trigger_signal_quiesce, + event, 1); + qemu_mutex_init(&event->lock); + + return 0; +} + +static void quiesce_class_init(ObjectClass *klass, void *data) +{ + SCLPEventClass *k = SCLP_EVENT_CLASS(klass); + + k->init = quiesce_init; + + k->get_send_mask = send_mask; + k->get_receive_mask = receive_mask; + k->event_type = event_type; + k->read_event_data = read_event_data; + k->write_event_data = NULL; +} + +static TypeInfo sclp_quiesce_info = { + .name = "sclpquiesce", + .parent = TYPE_SCLP_EVENT, + .instance_size = sizeof(SCLPEvent), + .class_init = quiesce_class_init, + .class_size = sizeof(SCLPEventClass), +}; + +static void register_types(void) +{ + type_register_static(&sclp_quiesce_info); +} +type_init(register_types) diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index 5ebde3b..a3ab189 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -1,4 +1,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o -obj-y += s390-sclp.o s390-event-facility.o +obj-y += s390-sclp.o s390-event-facility.o s390-sclpquiesce.o obj-y := $(addprefix ../,$(obj-y))