From patchwork Mon Aug 20 14:28:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 178852 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 0C1A12C007E for ; Tue, 21 Aug 2012 00:46:52 +1000 (EST) Received: from localhost ([::1]:41650 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T3Szy-0002ho-NS for incoming@patchwork.ozlabs.org; Mon, 20 Aug 2012 10:30:34 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47011) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T3Syv-0008Sd-Df for qemu-devel@nongnu.org; Mon, 20 Aug 2012 10:29:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T3Syu-00045L-3g for qemu-devel@nongnu.org; Mon, 20 Aug 2012 10:29:29 -0400 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:55975) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T3Syt-00044Z-Ng for qemu-devel@nongnu.org; Mon, 20 Aug 2012 10:29:28 -0400 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 20 Aug 2012 15:29:26 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 20 Aug 2012 15:29:08 +0100 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by b06cxnps4075.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q7KET27U19660822 for ; Mon, 20 Aug 2012 14:29:02 GMT 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 q7KET6ER029142 for ; Mon, 20 Aug 2012 08:29:08 -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 q7KET52V029087; Mon, 20 Aug 2012 08:29:05 -0600 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 1122) id 9DC77122443A; Mon, 20 Aug 2012 16:29:05 +0200 (CEST) From: Jens Freimann To: Alexander Graf Date: Mon, 20 Aug 2012 16:28:45 +0200 Message-Id: <1345472926-21528-4-git-send-email-jfrei@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.11.5 In-Reply-To: <1345472926-21528-1-git-send-email-jfrei@linux.vnet.ibm.com> References: <1345472926-21528-1-git-send-email-jfrei@linux.vnet.ibm.com> x-cbid: 12082014-8372-0000-0000-000003828728 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.108 Cc: Heinz Graalfs , qemu-devel , Einar Lueck , Christian Borntraeger , Jens Freimann , Cornelia Huck , Andreas Faerber Subject: [Qemu-devel] [PATCH 3/4] 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 Signed-off-by: Jens Freimann --- hw/s390x/Makefile.objs | 1 + hw/s390x/event-facility.c | 7 +++ hw/s390x/sclpquiesce.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 hw/s390x/sclpquiesce.c diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index b32fc52..ed4e61a 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -3,3 +3,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o obj-y := $(addprefix ../,$(obj-y)) obj-y += sclp.o obj-y += event-facility.o +obj-y += sclpquiesce.o diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 1108e2d..9367660 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -315,6 +315,7 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) static int init_event_facility(S390SCLPDevice *sdev) { SCLPEventFacility *event_facility; + DeviceState *quiesce; event_facility = g_malloc0(sizeof(SCLPEventFacility)); sdev->ef = event_facility; @@ -327,6 +328,12 @@ static int init_event_facility(S390SCLPDevice *sdev) event_facility->sbus.qbus.allow_hotplug = 0; 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/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c new file mode 100644 index 0000000..69d6737 --- /dev/null +++ b/hw/s390x/sclpquiesce.c @@ -0,0 +1,112 @@ +/* + * SCLP event type + * Signal Quiesce - trigger system powerdown request + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Heinz Graalfs + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at your + * option) any later version. See the COPYING file in the top-level directory. + * + */ +#include +#include "sysemu.h" +#include "sclp.h" +#include "event-facility.h" + +typedef struct SignalQuiesce { + EventBufferHeader ebh; + uint16_t timeout; + uint8_t unit; +} QEMU_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); + + 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)