All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <c.dall@virtualopensystems.com>
To: android-virt@lists.cs.columbia.edu, kvm@vger.kernel.org
Cc: tech@virtualopensystems.com
Subject: [PATCH v7 12/12] ARM: KVM: Guest wait-for-interrupts (WFI) support
Date: Mon, 12 Mar 2012 02:53:07 -0400	[thread overview]
Message-ID: <20120312065307.8074.97910.stgit@ubuntu> (raw)
In-Reply-To: <20120312065134.8074.36949.stgit@ubuntu>

From: Christoffer Dall <cdall@cs.columbia.edu>

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 flag the VCPU to be in wait_for_interrupts mode
and call the main KVM function kvm_vcpu_block() function. This function
will put the thread on a wait-queue and call schedule.

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. All calls to kvm_arch_vcpu_ioctl_run() result in a call to
kvm_vcpu_block() as long as the VCPU is in wfi-mode.

Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
---
 arch/arm/kvm/arm.c     |   15 ++++++++++++++-
 arch/arm/kvm/emulate.c |   12 ++++++++++++
 arch/arm/kvm/trace.h   |   16 ++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index ae4210b..1cce7af 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -291,9 +291,17 @@ 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 waiting and
+ * an interrupt is pending) then it is by definition runnable.
+ */
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
-	return 0;
+	return !!v->arch.irq_lines ||
+		!v->arch.wait_for_interrupts;
 }
 
 int kvm_arch_vcpu_in_guest_mode(struct kvm_vcpu *v)
@@ -479,6 +487,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			break;
 		}
 
+		if (vcpu->arch.wait_for_interrupts)
+			kvm_vcpu_block(vcpu);
+
 		/*
 		 * Enter the guest
 		 */
@@ -551,6 +562,8 @@ static int kvm_arch_vm_ioctl_irq_line(struct kvm *kvm,
 	 * trigger a world-switch round on the running physical CPU to set the
 	 * virtual IRQ/FIQ fields in the HCR appropriately.
 	 */
+	if (irq_level->level)
+		vcpu->arch.wait_for_interrupts = 0;
 	kvm_vcpu_kick(vcpu);
 
 	return 0;
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index 4ab9bbd..e356d1c 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -407,8 +407,20 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	return emulate_cp15(vcpu, &params);
 }
 
+/**
+ * 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)
 {
+	trace_kvm_wfi(vcpu->arch.regs.pc);
+	if (!vcpu->arch.irq_lines)
+		vcpu->arch.wait_for_interrupts = 1;
 	return 0;
 }
 
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index bd3a6cc..fc68394 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -90,6 +90,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


  parent reply	other threads:[~2012-03-12  6:53 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-12  6:51 [PATCH v7 00/12] KVM/ARM Implementation Christoffer Dall
2012-03-12  6:51 ` [PATCH v7 01/12] KVM: Introduce __KVM_HAVE_IRQ_LINE Christoffer Dall
2012-03-23  0:41   ` [PATCH] ARM: KVM: Check the cpuid we're being asked to emulate Rusty Russell
2012-05-14 22:57     ` Christoffer Dall
2012-05-16 23:58       ` Rusty Russell
2012-05-20 18:34         ` Christoffer Dall
2012-05-21  1:13           ` Rusty Russell
2012-03-12  6:52 ` [PATCH v7 02/12] KVM: Guard mmu_notifier specific code with CONFIG_MMU_NOTIFIER Christoffer Dall
2012-03-12 15:50   ` Avi Kivity
2012-03-12  6:52 ` [PATCH v7 03/12] ARM: KVM: Initial skeleton to compile KVM support Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 04/12] ARM: KVM: Hypervisor identity mapping Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 05/12] ARM: KVM: Hypervisor inititalization Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 06/12] ARM: KVM: Memory virtualization setup Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 07/12] ARM: KVM: Inject IRQs and FIQs from userspace Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 08/12] ARM: KVM: World-switch implementation Christoffer Dall
2012-03-23  0:23   ` Rusty Russell
2012-03-28 13:05     ` Avi Kivity
2012-03-28 21:57       ` Rusty Russell
2012-03-29 10:49         ` Avi Kivity
2012-05-14 18:08           ` Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 09/12] ARM: KVM: Emulation framework and CP15 emulation Christoffer Dall
2012-03-12  6:52 ` [PATCH v7 10/12] ARM: KVM: Handle guest faults in KVM Christoffer Dall
2012-03-12 15:31   ` [Android-virt] " Marc Zyngier
2012-03-12 16:23     ` Christoffer Dall
2012-03-12 16:28       ` Marc Zyngier
2012-03-12  6:53 ` [PATCH v7 11/12] ARM: KVM: Handle I/O aborts Christoffer Dall
2012-03-12  6:53 ` Christoffer Dall [this message]
2012-03-12 17:36 ` [PATCH v7 00/12] KVM/ARM Implementation Avi Kivity
2012-03-23  0:40 ` [PATCH] ARM: KVM: Remove l2ctlr write Rusty Russell
2012-05-14 22:59   ` Christoffer Dall
2012-03-29  5:11 ` [PATCH 0/3] Emulation cleanups Rusty, Russell <rusty.russell
2012-03-29  5:15   ` [PATCH 1/3] ARM: KVM: Remove l2ctlr write Rusty Russell
2012-03-29  5:17   ` [PATCH 2/3] ARM: KVM: Fake up performance counters a little more precisely Rusty Russell
2012-05-14 22:49     ` Christoffer Dall
2012-05-17  0:12       ` Rusty Russell
2012-03-29  5:17   ` [PATCH 3/3] ARM: KVM: Check the cpuid we're being asked to emulate Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120312065307.8074.97910.stgit@ubuntu \
    --to=c.dall@virtualopensystems.com \
    --cc=android-virt@lists.cs.columbia.edu \
    --cc=kvm@vger.kernel.org \
    --cc=tech@virtualopensystems.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.