From patchwork Wed Jun 6 12:05:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 163380 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 97C2CB6FA3 for ; Wed, 6 Jun 2012 23:36:06 +1000 (EST) Received: from localhost ([::1]:58347 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ScF14-0001N0-EZ for incoming@patchwork.ozlabs.org; Wed, 06 Jun 2012 08:07:10 -0400 Received: from eggs.gnu.org ([208.118.235.92]:55689) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ScEzt-0006pw-NC for qemu-devel@nongnu.org; Wed, 06 Jun 2012 08:06:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ScEzk-0001LY-9K for qemu-devel@nongnu.org; Wed, 06 Jun 2012 08:05:57 -0400 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:40347) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ScEzj-0001Ke-U9 for qemu-devel@nongnu.org; Wed, 06 Jun 2012 08:05:48 -0400 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 6 Jun 2012 13:05:43 +0100 Received: from d06nrmr1806.portsmouth.uk.ibm.com (9.149.39.193) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 6 Jun 2012 13:05:40 +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 q56C5eZu2486370 for ; Wed, 6 Jun 2012 13:05:40 +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 q56C5ctX001934 for ; Wed, 6 Jun 2012 06:05:39 -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 q56C5bdg001896; Wed, 6 Jun 2012 06:05:38 -0600 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 1122) id 7411C122443B; Wed, 6 Jun 2012 14:05:37 +0200 (CEST) From: Jens Freimann To: Alexander Graf Date: Wed, 6 Jun 2012 14:05:20 +0200 Message-Id: <1338984323-21914-6-git-send-email-jfrei@de.ibm.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1338984323-21914-1-git-send-email-jfrei@de.ibm.com> References: <1338984323-21914-1-git-send-email-jfrei@de.ibm.com> x-cbid: 12060612-0342-0000-0000-000001E98843 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.111 Cc: Jens Freimann , Heinz Graalfs , qemu-devel , Christian Borntraeger , Jens Freimann , Cornelia Huck Subject: [Qemu-devel] [PATCH 5/8] s390: Cleanup sclp functions 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: Christian Borntraeger The sclp facility on s390 is a hardware that is external to the cpu. Lets cleanup the definitions and move the functionality into a separate file under hw/. Signed-off-by: Christian Borntraeger Signed-off-by: Jens Freimann --- Makefile.target | 2 +- hw/s390-sclp.c | 42 ++++++++++++++++++++++++++++++++++++++++++ hw/s390-sclp.h | 34 ++++++++++++++++++++++++++++++++++ target-s390x/cpu.h | 11 ----------- target-s390x/kvm.c | 5 ++--- target-s390x/op_helper.c | 39 +++++++++++++++++---------------------- 6 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 hw/s390-sclp.c create mode 100644 hw/s390-sclp.h diff --git a/Makefile.target b/Makefile.target index 1582904..fed2d72 100644 --- a/Makefile.target +++ b/Makefile.target @@ -374,7 +374,7 @@ obj-sh4-y += ide/mmio.o obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o obj-m68k-y += m68k-semi.o dummy_m68k.o -obj-s390x-y = s390-virtio-bus.o s390-virtio.o +obj-s390x-y = s390-virtio-bus.o s390-virtio.o s390-sclp.o obj-alpha-y = mc146818rtc.o obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o diff --git a/hw/s390-sclp.c b/hw/s390-sclp.c new file mode 100644 index 0000000..c046441 --- /dev/null +++ b/hw/s390-sclp.c @@ -0,0 +1,42 @@ +/* + * sclp facility + * Copyright IBM Corp. 2012 + * Author: Christian Borntraeger + * + */ + +#include "cpu.h" +#include "kvm.h" +#include "hw/s390-sclp.h" + +int sclp_read_info(CPUS390XState *env, struct sccb *sccb) +{ + int shift = 0; + + while ((ram_size >> (20 + shift)) > 65535) { + shift++; + } + sccb->c.read_info.rnmax = cpu_to_be16(ram_size >> (20 + shift)); + sccb->c.read_info.rnsize = 1 << shift; + sccb->h.response_code = cpu_to_be16(0x10); + + return 0; +} + +void sclp_service_interrupt(CPUS390XState *env, uint32_t sccb) +{ + if (!sccb) { + return; + } + + if (kvm_enabled()) { +#ifdef CONFIG_KVM + kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE, + (sccb & ~3), 0, 1); +#endif + } else { + env->psw.addr += 4; + cpu_inject_ext(env, EXT_SERVICE, (sccb & ~3), 0); + } +} + diff --git a/hw/s390-sclp.h b/hw/s390-sclp.h new file mode 100644 index 0000000..e335b21 --- /dev/null +++ b/hw/s390-sclp.h @@ -0,0 +1,34 @@ +#include +#include + + +/* SCLP command codes */ +#define SCLP_CMDW_READ_SCP_INFO 0x00020001 +#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 + +/* SCLP response codes */ +#define SCLP_RC_SCCB_RESOURCE_INSUFFICENT 0x07f0 + +struct sccb_header { + uint16_t length; +#define SCLP_FC_NORMAL_WRITE 0 + uint8_t function_code; + uint8_t control_mask[3]; + uint16_t response_code; +} __attribute__((packed)); + +struct read_info_sccb { + uint16_t rnmax; + uint8_t rnsize; +} __attribute__((packed)); + +struct sccb { + struct sccb_header h; + union { + struct read_info_sccb read_info; + char data[4088]; + } c; + } __attribute__((packed)); + +int sclp_read_info(CPUS390XState *env, struct sccb *sccb); +void sclp_service_interrupt(CPUS390XState *env, uint32_t sccb); diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 2f3f394..d0199d7 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -591,17 +591,6 @@ static inline const char *cc_name(int cc_op) return cc_names[cc_op]; } -/* SCLP PV interface defines */ -#define SCLP_CMDW_READ_SCP_INFO 0x00020001 -#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 - -#define SCP_LENGTH 0x00 -#define SCP_FUNCTION_CODE 0x02 -#define SCP_CONTROL_MASK 0x03 -#define SCP_RESPONSE_CODE 0x06 -#define SCP_MEM_CODE 0x08 -#define SCP_INCREMENT 0x0a - typedef struct LowCore { /* prefix area: defined by architecture */ diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 73cfd1f..7a7604b 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -60,9 +60,6 @@ #define SIGP_STORE_STATUS_ADDR 0x0e #define SIGP_SET_ARCH 0x12 -#define SCLP_CMDW_READ_SCP_INFO 0x00020001 -#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 - const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -246,6 +243,8 @@ static int kvm_sclp_service_call(CPUS390XState *env, struct kvm_run *run, r = sclp_service_call(env, sccb, code); if (r) { setcc(env, 3); + } else { + setcc(env, 0); } return 0; diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c index 7b72473..74bd9ad 100644 --- a/target-s390x/op_helper.c +++ b/target-s390x/op_helper.c @@ -31,6 +31,7 @@ #if !defined (CONFIG_USER_ONLY) #include "sysemu.h" +#include "hw/s390-sclp.h" #endif /*****************************************************************************/ @@ -2360,16 +2361,13 @@ static void program_interrupt(CPUS390XState *env, uint32_t code, int ilc) } } -static void ext_interrupt(CPUS390XState *env, int type, uint32_t param, - uint64_t param64) -{ - cpu_inject_ext(env, type, param, param64); -} int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code) { int r = 0; - int shift = 0; + struct sccb work_sccb; + struct sccb *guest_sccb; + target_phys_addr_t sccb_len = sizeof(*guest_sccb); #ifdef DEBUG_HELPER printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code); @@ -2380,26 +2378,18 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code) r = -1; goto out; } + /* + * we want to work on a private copy of the sccb, to prevent guests + * from playing dirty tricks by modifying the memory content after + * the host has checked the values + */ + guest_sccb = cpu_physical_memory_map(sccb, &sccb_len, true); + memcpy(&work_sccb, guest_sccb, sizeof(*guest_sccb)); switch(code) { case SCLP_CMDW_READ_SCP_INFO: case SCLP_CMDW_READ_SCP_INFO_FORCED: - while ((ram_size >> (20 + shift)) > 65535) { - shift++; - } - stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift)); - stb_phys(sccb + SCP_INCREMENT, 1 << shift); - stw_phys(sccb + SCP_RESPONSE_CODE, 0x10); - - if (kvm_enabled()) { -#ifdef CONFIG_KVM - kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE, - sccb & ~3, 0, 1); -#endif - } else { - env->psw.addr += 4; - ext_interrupt(env, EXT_SERVICE, sccb & ~3, 0); - } + r = sclp_read_info(env, &work_sccb); break; default: #ifdef DEBUG_HELPER @@ -2408,6 +2398,11 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code) r = -1; break; } + memcpy(guest_sccb, &work_sccb, work_sccb.h.length); + cpu_physical_memory_unmap(guest_sccb, 4096, true, 4096); + if (!r) { + sclp_service_interrupt(env, sccb); + } out: return r;