From patchwork Thu Feb 4 15:55:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 77070 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o14FuK38027344 for ; Thu, 4 Feb 2010 15:56:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933215Ab0BDP4E (ORCPT ); Thu, 4 Feb 2010 10:56:04 -0500 Received: from cantor.suse.de ([195.135.220.2]:49941 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933134Ab0BDPz3 (ORCPT ); Thu, 4 Feb 2010 10:55:29 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id B2F1C947B6; Thu, 4 Feb 2010 16:55:26 +0100 (CET) From: Alexander Graf To: kvm-ppc@vger.kernel.org Cc: kvm@vger.kernel.org Subject: [PATCH 02/18] KVM: PPC: Enable MMIO to do 64 bits, fprs and qprs Date: Thu, 4 Feb 2010 16:55:09 +0100 Message-Id: <1265298925-31954-3-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1265298925-31954-1-git-send-email-agraf@suse.de> References: <1265298925-31954-1-git-send-email-agraf@suse.de> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 04 Feb 2010 15:56:22 +0000 (UTC) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 81f3b0b..548376c 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -77,4 +77,11 @@ struct kvm_debug_exit_arch { struct kvm_guest_debug_arch { }; +#define REG_MASK 0x001f +#define REG_EXT_MASK 0xffe0 +#define REG_GPR 0x0000 +#define REG_FPR 0x0020 +#define REG_QPR 0x0040 +#define REG_FQPR 0x0060 + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index e264282..c011170 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -49,7 +49,7 @@ extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int rt, unsigned int bytes, int is_bigendian); extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, - u32 val, unsigned int bytes, int is_bigendian); + u64 val, unsigned int bytes, int is_bigendian); extern int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 51aedd7..98d5e6d 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -277,7 +277,7 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) { - ulong gpr; + u64 gpr; if (run->mmio.len > sizeof(gpr)) { printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); @@ -286,6 +286,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, if (vcpu->arch.mmio_is_bigendian) { switch (run->mmio.len) { + case 8: gpr = *(u64 *)run->mmio.data; break; case 4: gpr = *(u32 *)run->mmio.data; break; case 2: gpr = *(u16 *)run->mmio.data; break; case 1: gpr = *(u8 *)run->mmio.data; break; @@ -300,6 +301,24 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, } kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); + + switch (vcpu->arch.io_gpr & REG_EXT_MASK) { + case REG_GPR: + kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); + break; + case REG_FPR: + vcpu->arch.fpr[vcpu->arch.io_gpr & REG_MASK] = gpr; + break; + case REG_QPR: + vcpu->arch.qpr[vcpu->arch.io_gpr & REG_MASK] = gpr; + break; + case REG_FQPR: + vcpu->arch.fpr[vcpu->arch.io_gpr & REG_MASK] = gpr; + vcpu->arch.qpr[vcpu->arch.io_gpr & REG_MASK] = gpr; + break; + default: + BUG(); + } } int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, @@ -323,7 +342,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, } int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, - u32 val, unsigned int bytes, int is_bigendian) + u64 val, unsigned int bytes, int is_bigendian) { void *data = run->mmio.data; @@ -341,6 +360,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, /* Store the value at the lowest bytes in 'data'. */ if (is_bigendian) { switch (bytes) { + case 8: *(u64 *)data = val; break; case 4: *(u32 *)data = val; break; case 2: *(u16 *)data = val; break; case 1: *(u8 *)data = val; break;