From patchwork Tue Mar 29 13:29:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 88774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 320D0B6F07 for ; Wed, 30 Mar 2011 00:36:30 +1100 (EST) Received: from localhost ([127.0.0.1]:43133 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q4Z5v-000484-NQ for incoming@patchwork.ozlabs.org; Tue, 29 Mar 2011 09:36:27 -0400 Received: from [140.186.70.92] (port=58586 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q4YzZ-00013P-Dw for qemu-devel@nongnu.org; Tue, 29 Mar 2011 09:29:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q4YzX-0006Wb-OJ for qemu-devel@nongnu.org; Tue, 29 Mar 2011 09:29:53 -0400 Received: from cantor2.suse.de ([195.135.220.15]:40429 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q4YzX-0006Va-Db for qemu-devel@nongnu.org; Tue, 29 Mar 2011 09:29:51 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 443678891E; Tue, 29 Mar 2011 15:29:50 +0200 (CEST) From: Alexander Graf To: qemu-devel@nongnu.org Date: Tue, 29 Mar 2011 15:29:44 +0200 Message-Id: <1301405386-25738-18-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1301405386-25738-1-git-send-email-agraf@suse.de> References: <1301405386-25738-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: peter.maydell@linaro.org, aurelien@aurel32.net, rth@twiddle.net Subject: [Qemu-devel] [PATCH 17/19] s390x: Adjust internal kvm code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We're now finally emulating an s390x CPU, so we can move quite some logic from the kvm code out into generic CPU code. This patch does this and adjusts the interfaces according to what the code around now expects to be able to call. Signed-off-by: Alexander Graf --- target-s390x/kvm.c | 60 ++++++++++++--------------------------------------- 1 files changed, 14 insertions(+), 46 deletions(-) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index ae7dc56..f464367 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -49,13 +49,6 @@ #define DIAG_KVM_HYPERCALL 0x500 #define DIAG_KVM_BREAKPOINT 0x501 -#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 - #define ICPT_INSTRUCTION 0x04 #define ICPT_WAITPSW 0x1c #define ICPT_SOFT_INTERCEPT 0x24 @@ -182,8 +175,8 @@ int kvm_arch_process_async_events(CPUState *env) return 0; } -static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, - uint64_t parm64, int vm) +void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, + uint64_t parm64, int vm) { struct kvm_s390_interrupt kvmint; int r; @@ -218,7 +211,7 @@ void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token) token, 1); } -static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code) +void kvm_s390_interrupt(CPUState *env, int type, uint32_t code) { kvm_s390_interrupt_internal(env, type, code, 0, 0); } @@ -228,16 +221,16 @@ static void enter_pgmcheck(CPUState *env, uint16_t code) kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code); } -static void setcc(CPUState *env, uint64_t cc) +static inline void setcc(CPUState *env, uint64_t cc) { - env->kvm_run->psw_mask &= ~(3ul << 44); + env->kvm_run->psw_mask &= ~(3ull << 44); env->kvm_run->psw_mask |= (cc & 3) << 44; env->psw.mask &= ~(3ul << 44); env->psw.mask |= (cc & 3) << 44; } -static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0) +static int kvm_sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0) { uint32_t sccb; uint64_t code; @@ -247,35 +240,11 @@ static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0) sccb = env->regs[ipbh0 & 0xf]; code = env->regs[(ipbh0 & 0xf0) >> 4]; - dprintf("sclp(0x%x, 0x%lx)\n", sccb, code); - - if (sccb & ~0x7ffffff8ul) { - fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb); - r = -1; - goto out; - } - - switch(code) { - case SCLP_CMDW_READ_SCP_INFO: - case SCLP_CMDW_READ_SCP_INFO_FORCED: - stw_phys(sccb + SCP_MEM_CODE, ram_size >> 20); - stb_phys(sccb + SCP_INCREMENT, 1); - stw_phys(sccb + SCP_RESPONSE_CODE, 0x10); - setcc(env, 0); - - kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE, - sccb & ~3, 0, 1); - break; - default: - dprintf("KVM: invalid sclp call 0x%x / 0x%lx\n", sccb, code); - r = -1; - break; - } - -out: - if (r < 0) { + r = sclp_service_call(env, sccb, code); + if (r) { setcc(env, 3); } + return 0; } @@ -287,7 +256,7 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1) dprintf("KVM: PRIV: %d\n", ipa1); switch (ipa1) { case PRIV_SCLP_CALL: - r = sclp_service_call(env, run, ipbh0); + r = kvm_sclp_service_call(env, run, ipbh0); break; default: dprintf("KVM: unknown PRIV: 0x%x\n", ipa1); @@ -300,12 +269,10 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1) static int handle_hypercall(CPUState *env, struct kvm_run *run) { - int r; - cpu_synchronize_state(env); - r = s390_virtio_hypercall(env); + env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]); - return r; + return 0; } static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code) @@ -450,7 +417,8 @@ static int handle_intercept(CPUState *env) int icpt_code = run->s390_sieic.icptcode; int r = 0; - dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, env->kvm_run->psw_addr); + dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, + (long)env->kvm_run->psw_addr); switch (icpt_code) { case ICPT_INSTRUCTION: r = handle_instruction(env, run);