From patchwork Sun Jun 22 21:23:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 4396691 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4A013BEEAA for ; Sun, 22 Jun 2014 21:24:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7442A201DE for ; Sun, 22 Jun 2014 21:24:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7DC202024F for ; Sun, 22 Jun 2014 21:24:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752557AbaFVVYl (ORCPT ); Sun, 22 Jun 2014 17:24:41 -0400 Received: from cantor2.suse.de ([195.135.220.15]:33366 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752267AbaFVVXp (ORCPT ); Sun, 22 Jun 2014 17:23:45 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7397DAD7C; Sun, 22 Jun 2014 21:23:38 +0000 (UTC) From: Alexander Graf To: kvm-ppc@vger.kernel.org Cc: kvm@vger.kernel.org Subject: [PATCH 32/33] KVM: PPC: Handle NV registers in emulated critical sections Date: Sun, 22 Jun 2014 23:23:36 +0200 Message-Id: <1403472217-22263-33-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1403472217-22263-1-git-send-email-agraf@suse.de> References: <1403472217-22263-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-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When we emulate instructions during our critical section emulation we may overwrite non-volatile registers that the looping code would need to load back in. Notify the callers of prepare_to_enter() when we emulated code, so that they can set enable NV restoration on their exit path. Signed-off-by: Alexander Graf --- arch/powerpc/kvm/book3s_pr.c | 16 +++++++++++++--- arch/powerpc/kvm/booke.c | 3 +++ arch/powerpc/kvm/powerpc.c | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 3b82e86..8cce531 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1174,10 +1174,20 @@ program_interrupt: * again due to a host external interrupt. */ s = kvmppc_prepare_to_enter(vcpu); - if (s <= 0) + switch (s) { + case -EINTR: r = s; - else { - /* interrupts now hard-disabled */ + break; + case 0: + /* Exit_reason is set, go to host */ + r = RESUME_HOST; + break; + case 2: + /* Registers modified, reload then enter */ + r = RESUME_GUEST_NV; + /* fall through */ + case 1: + /* Interrupts now hard-disabled, enter guest */ kvmppc_fix_ee_before_entry(); } diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index c0a71ce..66718d4 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1216,6 +1216,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, if (s <= 0) r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); else { + if (s == 2) + r = RESUME_GUEST_NV; + /* interrupts now hard-disabled */ kvmppc_fix_ee_before_entry(); } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0a326e1..6757c47 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -103,12 +103,14 @@ static bool kvmppc_needs_emulation(struct kvm_vcpu *vcpu) * * returns: * + * == 2 if we're ready to go into guest state with NV registers restored * == 1 if we're ready to go into guest state * <= 0 if we need to go back to the host with return value */ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) { int r; + int enter_level = 1; WARN_ON(irqs_disabled()); hard_irq_disable(); @@ -163,13 +165,15 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) r = kvmppc_emulate_any_instruction(vcpu); if (r == EMULATE_DO_MMIO) return 0; + if (r == EMULATE_DONE) + enter_level = 2; hard_irq_disable(); continue; } kvm_guest_enter(); - return 1; + return enter_level; } /* return to host */