From patchwork Sat Sep 15 15:36:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 1462251 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 40C7E3FC33 for ; Sat, 15 Sep 2012 15:46:09 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TCuVf-00036S-Sw; Sat, 15 Sep 2012 15:42:20 +0000 Received: from mail-qc0-f177.google.com ([209.85.216.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TCuPe-0007k9-Vz for linux-arm-kernel@lists.infradead.org; Sat, 15 Sep 2012 15:36:08 +0000 Received: by mail-qc0-f177.google.com with SMTP id u28so3767554qcs.36 for ; Sat, 15 Sep 2012 08:36:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=subject:to:from:date:message-id:in-reply-to:references:user-agent :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=JIVOr+0i2C7gW6BOZMDGRXnyFgPN3B0EYD7ZrpV3EKU=; b=Dm0h5R/SgoA6kmUgLuqHQ//TB6VHaX+lAA8ApRlibf555Dn3PSYVROGiObRaAFjO1l KKv4nTzZOO5d5usq5y0o8H9BLdp1vFTVKdUvg4YgZ3AV9rJDz/m2ecvW5e1IqbLPVdB3 L5hU19dHD/4xWKcVKRUKKIqmWPnTMzpRr6eaNiLiurxbJYBl3G8T/cgTun2Y6+FymSuH wmsad9fI5+4UhqEbcGLRmwf66XiEE+CbkWL4Ea6MCV1ZMSBbG/YRPStSDJ+/Y3MnoIlX ybeyt309Pf0w90ooGJUtLV61K65hb2Pm+Ae+tzwVAEoL3eVrgGU0NwsZczkxlfws6M+H +MLQ== Received: by 10.224.213.198 with SMTP id gx6mr15585665qab.9.1347723366773; Sat, 15 Sep 2012 08:36:06 -0700 (PDT) Received: from [127.0.1.1] (pool-72-80-83-148.nycmny.fios.verizon.net. [72.80.83.148]) by mx.google.com with ESMTPS id ca8sm6996736qab.20.2012.09.15.08.36.06 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 15 Sep 2012 08:36:06 -0700 (PDT) Subject: [PATCH 15/15] KVM: ARM: Guest wait-for-interrupts (WFI) support To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu From: Christoffer Dall Date: Sat, 15 Sep 2012 11:36:05 -0400 Message-ID: <20120915153605.21241.75455.stgit@ubuntu> In-Reply-To: <20120915153359.21241.86002.stgit@ubuntu> References: <20120915153359.21241.86002.stgit@ubuntu> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnaDusoi1Pnu5Dj5erWHTwGQMtMUWkGThu5RKQ7cwCvUMnfofUyof/dl30NZdYSKbhNI58X X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.216.177 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Christoffer Dall When the guest executes a WFI instruction the operation is trapped to KVM, which emulates the instruction in software. There is no correlation between a guest executing a WFI instruction and actually putting the hardware into a low-power mode, since a KVM guest is essentially a process and the WFI instruction can be seen as 'sleep' call from this process. Therefore, we block the vcpu when the guest excecutes a wfi instruction and the IRQ or FIQ lines are not raised. When an interrupt comes in through KVM_IRQ_LINE (see previous patch) we signal the VCPU thread and unflag the VCPU to no longer wait for interrupts. Signed-off-by: Christoffer Dall --- arch/arm/kvm/arm.c | 10 ++++++++-- arch/arm/kvm/emulate.c | 13 ++++++++++++- arch/arm/kvm/trace.h | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 06a3368..64fbec7 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -318,9 +318,16 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return -EINVAL; } +/** + * kvm_arch_vcpu_runnable - determine if the vcpu can be scheduled + * @v: The VCPU pointer + * + * If the guest CPU is not waiting for interrupts or an interrupt line is + * asserted, the CPU is by definition runnable. + */ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { - return 0; + return !!v->arch.irq_lines; } int kvm_arch_vcpu_in_guest_mode(struct kvm_vcpu *v) @@ -586,7 +593,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) * Check conditions before entering the guest */ cond_resched(); - update_vttbr(vcpu->kvm); local_irq_disable(); diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index 2670679..fc0fcd3 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -154,9 +154,20 @@ static int kvm_instr_index(u32 instr, u32 table[][2], int table_entries) return INSTR_NONE; } +/** + * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest + * @vcpu: the vcpu pointer + * @run: the kvm_run structure pointer + * + * Simply sets the wait_for_interrupts flag on the vcpu structure, which will + * halt execution of world-switches and schedule other host processes until + * there is an incoming IRQ or FIQ to the VM. + */ int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) { - return 0; + trace_kvm_wfi(vcpu->arch.regs.pc); + kvm_vcpu_block(vcpu); + return 1; } diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index 7199b58..b371138 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h @@ -143,6 +143,22 @@ TRACE_EVENT(kvm_emulate_cp15_imp, __entry->CRm, __entry->Op2) ); +TRACE_EVENT(kvm_wfi, + TP_PROTO(unsigned long vcpu_pc), + TP_ARGS(vcpu_pc), + + TP_STRUCT__entry( + __field( unsigned long, vcpu_pc ) + ), + + TP_fast_assign( + __entry->vcpu_pc = vcpu_pc; + ), + + TP_printk("guest executed wfi at: 0x%08lx", __entry->vcpu_pc) +); + + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH