From patchwork Tue Feb 24 13:15:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 442967 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 B32D6140159 for ; Wed, 25 Feb 2015 00:19:50 +1100 (AEDT) Received: from localhost ([::1]:49279 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQFOu-0000VU-TQ for incoming@patchwork.ozlabs.org; Tue, 24 Feb 2015 08:19:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51810) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQFLC-0001rv-DR for qemu-devel@nongnu.org; Tue, 24 Feb 2015 08:16:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YQFL5-0002QI-8H for qemu-devel@nongnu.org; Tue, 24 Feb 2015 08:15:58 -0500 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:46117) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQFL4-0002LJ-T0 for qemu-devel@nongnu.org; Tue, 24 Feb 2015 08:15:51 -0500 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 24 Feb 2015 13:15:38 -0000 Received: from d06dlp02.portsmouth.uk.ibm.com (9.149.20.14) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 24 Feb 2015 13:15:36 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id CEC292190056 for ; Tue, 24 Feb 2015 13:15:28 +0000 (GMT) Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1ODFZPg7864680 for ; Tue, 24 Feb 2015 13:15:35 GMT Received: from d06av10.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1ODFYT6008855 for ; Tue, 24 Feb 2015 06:15:35 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1ODFYsF008842; Tue, 24 Feb 2015 06:15:34 -0700 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 1122) id 659BA122445B; Tue, 24 Feb 2015 14:15:34 +0100 (CET) From: Jens Freimann To: Christian Borntraeger , Alexander Graf , Cornelia Huck Date: Tue, 24 Feb 2015 14:15:23 +0100 Message-Id: <1424783731-43426-3-git-send-email-jfrei@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1424783731-43426-1-git-send-email-jfrei@linux.vnet.ibm.com> References: <1424783731-43426-1-git-send-email-jfrei@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15022413-0021-0000-0000-000002FFF28E X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.111 Cc: David Hildenbrand , Jens Freimann , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 02/10] s390x/kvm: more details for SIGP handler with one destination vcpu 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: David Hildenbrand Whenever a sigp order is to be executed by a target vcpu, we use run_on_cpu(). As we have only one pointer to pass all data to these sigp handlers, let's introduce the struct sigp_info and use it as a transport container. All orders targeting a single vcpu are now dispatched from a separate handler. The destination vcpu is only valid for these orders and must not be checked for SIGP SET ARCHITECTURE. The sigp_info is filled with life in this new handler and used to pass the information about the sigp order to the existing handlers. The cc is set within these handlers. Rename sigp_cpu_start() and sigp_cpu_restart() on the way to match the SIGP order names (in order to avoid touching affected lines several times). Reviewed-by: Thomas Huth Signed-off-by: Jens Freimann Signed-off-by: David Hildenbrand --- target-s390x/kvm.c | 153 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 91b0257..ec17ac8 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -1098,110 +1098,139 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb) return r; } -static void sigp_cpu_start(void *arg) +typedef struct SigpInfo { + S390CPU *cpu; + int cc; + uint64_t *status_reg; +} SigpInfo; + +static void sigp_start(void *arg) { - CPUState *cs = arg; - S390CPU *cpu = S390_CPU(cs); + SigpInfo *si = arg; - s390_cpu_set_state(CPU_STATE_OPERATING, cpu); - DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env); + s390_cpu_set_state(CPU_STATE_OPERATING, si->cpu); + si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; + DPRINTF("DONE: KVM cpu start: %p\n", &si->cpu->env); } -static void sigp_cpu_restart(void *arg) +static void sigp_restart(void *arg) { - CPUState *cs = arg; - S390CPU *cpu = S390_CPU(cs); + SigpInfo *si = arg; struct kvm_s390_irq irq = { .type = KVM_S390_RESTART, }; - kvm_s390_vcpu_interrupt(cpu, &irq); - s390_cpu_set_state(CPU_STATE_OPERATING, cpu); + kvm_s390_vcpu_interrupt(si->cpu, &irq); + s390_cpu_set_state(CPU_STATE_OPERATING, si->cpu); + si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; } int kvm_s390_cpu_restart(S390CPU *cpu) { - run_on_cpu(CPU(cpu), sigp_cpu_restart, CPU(cpu)); + SigpInfo si = { + .cpu = cpu, + }; + + run_on_cpu(CPU(cpu), sigp_restart, &si); DPRINTF("DONE: KVM cpu restart: %p\n", &cpu->env); return 0; } static void sigp_initial_cpu_reset(void *arg) { - CPUState *cpu = arg; - S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); + SigpInfo *si = arg; + CPUState *cs = CPU(si->cpu); + S390CPUClass *scc = S390_CPU_GET_CLASS(si->cpu); - cpu_synchronize_state(cpu); - scc->initial_cpu_reset(cpu); - cpu_synchronize_post_reset(cpu); + cpu_synchronize_state(cs); + scc->initial_cpu_reset(cs); + cpu_synchronize_post_reset(cs); + si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; } static void sigp_cpu_reset(void *arg) { - CPUState *cpu = arg; - S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); + SigpInfo *si = arg; + CPUState *cs = CPU(si->cpu); + S390CPUClass *scc = S390_CPU_GET_CLASS(si->cpu); - cpu_synchronize_state(cpu); - scc->cpu_reset(cpu); - cpu_synchronize_post_reset(cpu); + cpu_synchronize_state(cs); + scc->cpu_reset(cs); + cpu_synchronize_post_reset(cs); + si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; } -#define SIGP_ORDER_MASK 0x000000ff - -static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) +static int handle_sigp_single_dst(S390CPU *dst_cpu, uint8_t order, + uint64_t *status_reg) { - CPUS390XState *env = &cpu->env; - uint8_t order_code; - uint16_t cpu_addr; - S390CPU *target_cpu; - uint64_t *statusreg = &env->regs[ipa1 >> 4]; - int cc; - - cpu_synchronize_state(CPU(cpu)); - - /* get order code */ - order_code = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK; + SigpInfo si = { + .cpu = dst_cpu, + .status_reg = status_reg, + }; - cpu_addr = env->regs[ipa1 & 0x0f]; - target_cpu = s390_cpu_addr2state(cpu_addr); - if (target_cpu == NULL) { - cc = SIGP_CC_NOT_OPERATIONAL; - goto out; + /* cpu available? */ + if (dst_cpu == NULL) { + return SIGP_CC_NOT_OPERATIONAL; } - switch (order_code) { + switch (order) { case SIGP_START: - run_on_cpu(CPU(target_cpu), sigp_cpu_start, CPU(target_cpu)); - cc = SIGP_CC_ORDER_CODE_ACCEPTED; + run_on_cpu(CPU(dst_cpu), sigp_start, &si); break; case SIGP_RESTART: - run_on_cpu(CPU(target_cpu), sigp_cpu_restart, CPU(target_cpu)); - cc = SIGP_CC_ORDER_CODE_ACCEPTED; - break; - case SIGP_SET_ARCH: - *statusreg &= 0xffffffff00000000UL; - *statusreg |= SIGP_STAT_INVALID_PARAMETER; - cc = SIGP_CC_STATUS_STORED; - break; + run_on_cpu(CPU(dst_cpu), sigp_restart, &si); case SIGP_INITIAL_CPU_RESET: - run_on_cpu(CPU(target_cpu), sigp_initial_cpu_reset, CPU(target_cpu)); - cc = SIGP_CC_ORDER_CODE_ACCEPTED; + run_on_cpu(CPU(dst_cpu), sigp_initial_cpu_reset, &si); break; case SIGP_CPU_RESET: - run_on_cpu(CPU(target_cpu), sigp_cpu_reset, CPU(target_cpu)); - cc = SIGP_CC_ORDER_CODE_ACCEPTED; + run_on_cpu(CPU(dst_cpu), sigp_cpu_reset, &si); break; default: - DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code); - *statusreg &= 0xffffffff00000000UL; - *statusreg |= SIGP_STAT_INVALID_ORDER; - cc = SIGP_CC_STATUS_STORED; + DPRINTF("KVM: unknown SIGP: 0x%x\n", order); + *status_reg &= 0xffffffff00000000ULL; + *status_reg |= SIGP_STAT_INVALID_ORDER; + si.cc = SIGP_CC_STATUS_STORED; + } + + return si.cc; +} + +#define SIGP_ORDER_MASK 0x000000ff + +static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) +{ + CPUS390XState *env = &cpu->env; + const uint8_t r1 = ipa1 >> 4; + const uint8_t r3 = ipa1 & 0x0f; + int ret; + uint8_t order; + uint64_t *status_reg; + S390CPU *dst_cpu = NULL; + + cpu_synchronize_state(CPU(cpu)); + + /* get order code */ + order = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK; + status_reg = &env->regs[r1]; + + switch (order) { + case SIGP_SET_ARCH: + *status_reg &= 0xffffffff00000000ULL; + *status_reg |= SIGP_STAT_INVALID_PARAMETER; + ret = SIGP_CC_STATUS_STORED; break; + default: + /* all other sigp orders target a single vcpu */ + dst_cpu = s390_cpu_addr2state(env->regs[r3]); + ret = handle_sigp_single_dst(dst_cpu, order, status_reg); } -out: - setcc(cpu, cc); - return 0; + if (ret >= 0) { + setcc(cpu, ret); + return 0; + } + + return ret; } static int handle_instruction(S390CPU *cpu, struct kvm_run *run)