From patchwork Fri Jul 27 06:18:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 173561 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 62F4B2C0093 for ; Fri, 27 Jul 2012 16:18:28 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751709Ab2G0GS1 (ORCPT ); Fri, 27 Jul 2012 02:18:27 -0400 Received: from ozlabs.org ([203.10.76.45]:45141 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751208Ab2G0GS0 (ORCPT ); Fri, 27 Jul 2012 02:18:26 -0400 Received: from [10.61.2.137] (ibmaus65.lnk.telstra.net [165.228.126.9]) (using SSLv3 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPSA id D9D792C0092; Fri, 27 Jul 2012 16:18:25 +1000 (EST) Message-ID: <1343369904.2118.20.camel@pasglop> Subject: [PATCH] powerpc/kvm: Allow qemu hypercalls to set all regs From: Benjamin Herrenschmidt To: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org Cc: Alexander Graf Date: Fri, 27 Jul 2012 16:18:24 +1000 X-Mailer: Evolution 3.2.3-0ubuntu6 Mime-Version: 1.0 Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Right now, whenever we exit for an hcall, upon return, we fetch some register values from the structure that carries the hcall results and update the vcpu accordingly. However, if the hypercall chooses instead to update the registers itself by calling set_regs, then we end up clobbering those values. This is for example the case of the rtas calls used to reboot the machine where a new CPU state is established and must not be clobbered. The simple fix is to always clear the hcall_needed flag when a set-regs happen. This fixes reboot problems. Signed-off-by: Benjamin Herrenschmidt --- Note: There are similar issues if the reboot is triggered by an MMIO emulation, or an OSI call, Alex, you might want to handle those cases as well. In any cases, I'd like this to still go into 3.6 but I can send it myself to Linus if you want. -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 3f2a836..9ab13d6 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -463,6 +463,14 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) kvmppc_set_gpr(vcpu, i, regs->gpr[i]); + /* + * If the hypercall decides to change register values + * explicitly, we must ensure that we do not override + * them upon return from that hypercall. Among others + * this happens on system reset + */ + vcpu->arch.hcall_needed = 0; + return 0; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 87f4dc8..75e196d 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -592,6 +592,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) } else if (vcpu->arch.hcall_needed) { int i; + /* + * Note: This might not be called if the hypervisor + * call has done a set_regs(). In this case hcall_needed + * is cleared. This is necessary for reset to work properly + */ kvmppc_set_gpr(vcpu, 3, run->papr_hcall.ret); for (i = 0; i < 9; ++i) kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]);