From patchwork Tue Jul 25 09:40:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 9861585 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3AED6601A1 for ; Tue, 25 Jul 2017 09:49:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 218CB26B41 for ; Tue, 25 Jul 2017 09:49:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 15CAE28609; Tue, 25 Jul 2017 09:49:09 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 159C026B41 for ; Tue, 25 Jul 2017 09:49:07 +0000 (UTC) Received: from localhost ([::1]:59516 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZwSh-00084u-3V for patchwork-qemu-devel@patchwork.kernel.org; Tue, 25 Jul 2017 05:49:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44289) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZwL0-00029j-Rr for qemu-devel@nongnu.org; Tue, 25 Jul 2017 05:41:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZwKz-0003od-4E for qemu-devel@nongnu.org; Tue, 25 Jul 2017 05:41:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55246) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dZwKy-0003nx-R5 for qemu-devel@nongnu.org; Tue, 25 Jul 2017 05:41:09 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C9E7AC0587E8; Tue, 25 Jul 2017 09:41:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C9E7AC0587E8 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=cohuck@redhat.com Received: from localhost (ovpn-116-214.ams2.redhat.com [10.36.116.214]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E7579189FE; Tue, 25 Jul 2017 09:41:06 +0000 (UTC) From: Cornelia Huck To: peter.maydell@linaro.org Date: Tue, 25 Jul 2017 11:40:22 +0200 Message-Id: <20170725094026.5376-11-cohuck@redhat.com> In-Reply-To: <20170725094026.5376-1-cohuck@redhat.com> References: <20170725094026.5376-1-cohuck@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 25 Jul 2017 09:41:07 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.10 10/14] target/s390x: Move diag helpers to a separate file 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: thuth@redhat.com, david@redhat.com, Cornelia Huck , qemu-devel@nongnu.org, agraf@suse.de, borntraeger@de.ibm.com, rth@twiddle.net Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Thomas Huth misc_helper.c won't be compiled with --disable-tcg anymore, but we still need the diag helpers in KVM builds, too, so move the helper functions to a separate file. Reviewed-by: Richard Henderson Signed-off-by: Thomas Huth Message-Id: <1500886370-14572-3-git-send-email-thuth@redhat.com> Signed-off-by: Cornelia Huck --- target/s390x/Makefile.objs | 2 +- target/s390x/diag.c | 179 +++++++++++++++++++++++++++++++++++++++++++++ target/s390x/misc_helper.c | 167 ------------------------------------------ 3 files changed, 180 insertions(+), 168 deletions(-) create mode 100644 target/s390x/diag.c diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs index 46f6a8c6b6..80028521ef 100644 --- a/target/s390x/Makefile.objs +++ b/target/s390x/Makefile.objs @@ -1,7 +1,7 @@ obj-y += translate.o helper.o cpu.o interrupt.o obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o obj-y += gdbstub.o cpu_models.o cpu_features.o -obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o +obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o obj-$(CONFIG_KVM) += kvm.o # build and run feature list generator diff --git a/target/s390x/diag.c b/target/s390x/diag.c new file mode 100644 index 0000000000..10ac845bcd --- /dev/null +++ b/target/s390x/diag.c @@ -0,0 +1,179 @@ +/* + * S390x DIAG instruction helper functions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/address-spaces.h" +#include "exec/exec-all.h" +#include "hw/watchdog/wdt_diag288.h" +#include "sysemu/cpus.h" +#include "hw/s390x/ipl.h" + +static int modified_clear_reset(S390CPU *cpu) +{ + S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); + CPUState *t; + + pause_all_vcpus(); + cpu_synchronize_all_states(); + CPU_FOREACH(t) { + run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); + } + s390_cmma_reset(); + subsystem_reset(); + s390_crypto_reset(); + scc->load_normal(CPU(cpu)); + cpu_synchronize_all_post_reset(); + resume_all_vcpus(); + return 0; +} + +static int load_normal_reset(S390CPU *cpu) +{ + S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); + CPUState *t; + + pause_all_vcpus(); + cpu_synchronize_all_states(); + CPU_FOREACH(t) { + run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL); + } + s390_cmma_reset(); + subsystem_reset(); + scc->initial_cpu_reset(CPU(cpu)); + scc->load_normal(CPU(cpu)); + cpu_synchronize_all_post_reset(); + resume_all_vcpus(); + return 0; +} + +int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3) +{ + uint64_t func = env->regs[r1]; + uint64_t timeout = env->regs[r1 + 1]; + uint64_t action = env->regs[r3]; + Object *obj; + DIAG288State *diag288; + DIAG288Class *diag288_class; + + if (r1 % 2 || action != 0) { + return -1; + } + + /* Timeout must be more than 15 seconds except for timer deletion */ + if (func != WDT_DIAG288_CANCEL && timeout < 15) { + return -1; + } + + obj = object_resolve_path_type("", TYPE_WDT_DIAG288, NULL); + if (!obj) { + return -1; + } + + diag288 = DIAG288(obj); + diag288_class = DIAG288_GET_CLASS(diag288); + return diag288_class->handle_timer(diag288, func, timeout); +} + +#define DIAG_308_RC_OK 0x0001 +#define DIAG_308_RC_NO_CONF 0x0102 +#define DIAG_308_RC_INVALID 0x0402 + +void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) +{ + uint64_t addr = env->regs[r1]; + uint64_t subcode = env->regs[r3]; + IplParameterBlock *iplb; + + if (env->psw.mask & PSW_MASK_PSTATE) { + program_interrupt(env, PGM_PRIVILEGED, ILEN_AUTO); + return; + } + + if ((subcode & ~0x0ffffULL) || (subcode > 6)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); + return; + } + + switch (subcode) { + case 0: + modified_clear_reset(s390_env_get_cpu(env)); + if (tcg_enabled()) { + cpu_loop_exit(CPU(s390_env_get_cpu(env))); + } + break; + case 1: + load_normal_reset(s390_env_get_cpu(env)); + if (tcg_enabled()) { + cpu_loop_exit(CPU(s390_env_get_cpu(env))); + } + break; + case 3: + s390_reipl_request(); + if (tcg_enabled()) { + cpu_loop_exit(CPU(s390_env_get_cpu(env))); + } + break; + case 5: + if ((r1 & 1) || (addr & 0x0fffULL)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); + return; + } + if (!address_space_access_valid(&address_space_memory, addr, + sizeof(IplParameterBlock), false)) { + program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO); + return; + } + iplb = g_malloc0(sizeof(IplParameterBlock)); + cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); + if (!iplb_valid_len(iplb)) { + env->regs[r1 + 1] = DIAG_308_RC_INVALID; + goto out; + } + + cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); + + if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { + env->regs[r1 + 1] = DIAG_308_RC_INVALID; + goto out; + } + + s390_ipl_update_diag308(iplb); + env->regs[r1 + 1] = DIAG_308_RC_OK; +out: + g_free(iplb); + return; + case 6: + if ((r1 & 1) || (addr & 0x0fffULL)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); + return; + } + if (!address_space_access_valid(&address_space_memory, addr, + sizeof(IplParameterBlock), true)) { + program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO); + return; + } + iplb = s390_ipl_get_iplb(); + if (iplb) { + cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); + env->regs[r1 + 1] = DIAG_308_RC_OK; + } else { + env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; + } + return; + default: + hw_error("Unhandled diag308 subcode %" PRIx64, subcode); + break; + } +} diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index b5081019c5..6a90ad55cc 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -24,22 +24,15 @@ #include "exec/memory.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" -#include "sysemu/kvm.h" #include "qemu/timer.h" -#include "qemu/main-loop.h" #include "exec/address-spaces.h" -#ifdef CONFIG_KVM -#include -#endif #include "exec/exec-all.h" #include "exec/cpu_ldst.h" #if !defined(CONFIG_USER_ONLY) -#include "hw/watchdog/wdt_diag288.h" #include "sysemu/cpus.h" #include "sysemu/sysemu.h" #include "hw/s390x/ebcdic.h" -#include "hw/s390x/ipl.h" #endif /* #define DEBUG_HELPER */ @@ -116,166 +109,6 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2) return r; } -#ifndef CONFIG_USER_ONLY -static int modified_clear_reset(S390CPU *cpu) -{ - S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); - CPUState *t; - - pause_all_vcpus(); - cpu_synchronize_all_states(); - CPU_FOREACH(t) { - run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); - } - s390_cmma_reset(); - subsystem_reset(); - s390_crypto_reset(); - scc->load_normal(CPU(cpu)); - cpu_synchronize_all_post_reset(); - resume_all_vcpus(); - return 0; -} - -static int load_normal_reset(S390CPU *cpu) -{ - S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); - CPUState *t; - - pause_all_vcpus(); - cpu_synchronize_all_states(); - CPU_FOREACH(t) { - run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL); - } - s390_cmma_reset(); - subsystem_reset(); - scc->initial_cpu_reset(CPU(cpu)); - scc->load_normal(CPU(cpu)); - cpu_synchronize_all_post_reset(); - resume_all_vcpus(); - return 0; -} - -int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3) -{ - uint64_t func = env->regs[r1]; - uint64_t timeout = env->regs[r1 + 1]; - uint64_t action = env->regs[r3]; - Object *obj; - DIAG288State *diag288; - DIAG288Class *diag288_class; - - if (r1 % 2 || action != 0) { - return -1; - } - - /* Timeout must be more than 15 seconds except for timer deletion */ - if (func != WDT_DIAG288_CANCEL && timeout < 15) { - return -1; - } - - obj = object_resolve_path_type("", TYPE_WDT_DIAG288, NULL); - if (!obj) { - return -1; - } - - diag288 = DIAG288(obj); - diag288_class = DIAG288_GET_CLASS(diag288); - return diag288_class->handle_timer(diag288, func, timeout); -} - -#define DIAG_308_RC_OK 0x0001 -#define DIAG_308_RC_NO_CONF 0x0102 -#define DIAG_308_RC_INVALID 0x0402 - -void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) -{ - uint64_t addr = env->regs[r1]; - uint64_t subcode = env->regs[r3]; - IplParameterBlock *iplb; - - if (env->psw.mask & PSW_MASK_PSTATE) { - program_interrupt(env, PGM_PRIVILEGED, ILEN_AUTO); - return; - } - - if ((subcode & ~0x0ffffULL) || (subcode > 6)) { - program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); - return; - } - - switch (subcode) { - case 0: - modified_clear_reset(s390_env_get_cpu(env)); - if (tcg_enabled()) { - cpu_loop_exit(CPU(s390_env_get_cpu(env))); - } - break; - case 1: - load_normal_reset(s390_env_get_cpu(env)); - if (tcg_enabled()) { - cpu_loop_exit(CPU(s390_env_get_cpu(env))); - } - break; - case 3: - s390_reipl_request(); - if (tcg_enabled()) { - cpu_loop_exit(CPU(s390_env_get_cpu(env))); - } - break; - case 5: - if ((r1 & 1) || (addr & 0x0fffULL)) { - program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); - return; - } - if (!address_space_access_valid(&address_space_memory, addr, - sizeof(IplParameterBlock), false)) { - program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO); - return; - } - iplb = g_malloc0(sizeof(IplParameterBlock)); - cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); - if (!iplb_valid_len(iplb)) { - env->regs[r1 + 1] = DIAG_308_RC_INVALID; - goto out; - } - - cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); - - if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { - env->regs[r1 + 1] = DIAG_308_RC_INVALID; - goto out; - } - - s390_ipl_update_diag308(iplb); - env->regs[r1 + 1] = DIAG_308_RC_OK; -out: - g_free(iplb); - return; - case 6: - if ((r1 & 1) || (addr & 0x0fffULL)) { - program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO); - return; - } - if (!address_space_access_valid(&address_space_memory, addr, - sizeof(IplParameterBlock), true)) { - program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO); - return; - } - iplb = s390_ipl_get_iplb(); - if (iplb) { - cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); - env->regs[r1 + 1] = DIAG_308_RC_OK; - } else { - env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; - } - return; - default: - hw_error("Unhandled diag308 subcode %" PRIx64, subcode); - break; - } -} -#endif - void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num) { uint64_t r;