diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 6ff5337..b23a709 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -620,7 +620,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
  */
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-	int ret;
+	int guest_ret, ret;
 	sigset_t sigsaved;

 	/* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */
@@ -640,9 +640,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu,
struct kvm_run *run)
 	if (vcpu->sigset_active)
 		sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);

-	ret = 1;
 	run->exit_reason = KVM_EXIT_UNKNOWN;
-	while (ret > 0) {
+	for (;;) {
 		/*
 		 * Check conditions before entering the guest
 		 */
@@ -650,18 +649,44 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu
*vcpu, struct kvm_run *run)

 		update_vttbr(vcpu->kvm);

+		/*
+		 * There is a dependency between setting IN_GUEST_MODE and
+		 * sending requests.  We need to ensure:
+		 *   1. Setting IN_GUEST_MODE before checking vcpu->requests.
+		 *   2. We need to check vcpu_request after disabling IRQs
+		 *      (see comment about signal_pending below).
+		 */
+		vcpu->mode = IN_GUEST_MODE;
+
 		local_irq_disable();

 		/*
-		 * Re-check atomic conditions
+		 * We need to be careful to check these variables after
+		 * disabling interrupts.  For example with signals:
+		 *   1. If the signal comes before the signal_pending check,
+		 *      we will return to user space and everything's good.
+		 *   2. If the signal comes after the signal_pending check,
+		 *      we rely on an IPI to exit the guest and continue the
+		 *      while loop, which checks for pending signals again.
 		 */
 		if (signal_pending(current)) {
 			ret = -EINTR;
 			run->exit_reason = KVM_EXIT_INTR;
+			local_irq_enable();
+			vcpu->mode = OUTSIDE_GUEST_MODE;
+			break;
 		}

-		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
+		if (vcpu->requests) {
+			ret = -ENOSYS; /* requests not supported */
 			local_irq_enable();
+			vcpu->mode = OUTSIDE_GUEST_MODE;
+			break;
+		}
+
+		if (need_new_vmid_gen(vcpu->kvm)) {
+			local_irq_enable();
+			vcpu->mode = OUTSIDE_GUEST_MODE;
 			continue;
 		}

@@ -670,17 +695,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu
*vcpu, struct kvm_run *run)
 		 */
 		trace_kvm_entry(*vcpu_pc(vcpu));
 		kvm_guest_enter();
-		vcpu->mode = IN_GUEST_MODE;

 		smp_mb(); /* set mode before reading vcpu->arch.pause */
 		if (unlikely(vcpu->arch.pause)) {
 			/* This means ignore, try again. */
-			ret = ARM_EXCEPTION_IRQ;
+			guest_ret = ARM_EXCEPTION_IRQ;
 		} else {
-			ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
+			guest_ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
 		}

-		vcpu->mode = OUTSIDE_GUEST_MODE;
 		vcpu->arch.last_pcpu = smp_processor_id();
 		kvm_guest_exit();
 		trace_kvm_exit(*vcpu_pc(vcpu));
@@ -695,12 +718,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu
*vcpu, struct kvm_run *run)
 		 * mode this time.
 		 */
 		local_irq_enable();
+		vcpu->mode = OUTSIDE_GUEST_MODE;

 		/*
 		 * Back from guest
 		 *************************************************************/

-		ret = handle_exit(vcpu, run, ret);
+		ret = handle_exit(vcpu, run, guest_ret);
+		if (ret <= 0)
+			break;
 	}

 	if (vcpu->sigset_active)

commit fc9a9c5e9dd4eba4acd6bea5c8c083a9a854d662
Author: Christoffer Dall <c.dall@virtualopensystems.com>
Date:   Tue Jan 15 20:42:15 2013 -0500

    KVM: ARM: Remove unused memslot parameter

diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h
index 31ab9f5..571ccf0 100644
--- a/arch/arm/include/asm/kvm_mmio.h
+++ b/arch/arm/include/asm/kvm_mmio.h
@@ -46,6 +46,6 @@ static inline void kvm_prepare_mmio(struct kvm_run *run,

 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
-		 phys_addr_t fault_ipa, struct kvm_memory_slot *memslot);
+		 phys_addr_t fault_ipa);

 #endif	/* __ARM_KVM_MMIO_H__ */
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index d6a4ca0..f655088 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -117,7 +117,7 @@ static int decode_hsr(struct kvm_vcpu *vcpu,
phys_addr_t fault_ipa,
 }

 int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
-		 phys_addr_t fault_ipa, struct kvm_memory_slot *memslot)
+		 phys_addr_t fault_ipa)
 {
 	struct kvm_exit_mmio mmio;
 	unsigned long rt;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 2a83ac9..c806080 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -588,7 +588,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
struct kvm_run *run)
 	unsigned long hsr_ec;
 	unsigned long fault_status;
 	phys_addr_t fault_ipa;
-	struct kvm_memory_slot *memslot = NULL;
+	struct kvm_memory_slot *memslot;
 	bool is_iabt;
 	gfn_t gfn;
 	int ret;
@@ -624,7 +624,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
struct kvm_run *run)

 		/* Adjust page offset */
 		fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK;
-		return io_mem_abort(vcpu, run, fault_ipa, memslot);
+		return io_mem_abort(vcpu, run, fault_ipa);
 	}

 	memslot = gfn_to_memslot(vcpu->kvm, gfn);

commit 70667a06e445e240fb5e6352ccdc4bc8a290866e
Author: Christoffer Dall <c.dall@virtualopensystems.com>
Date:   Tue Jan 15 20:51:42 2013 -0500

    KVM: ARM: Grab kvm->srcu lock when handling page faults

    The memslots data structure is protected with an SRCU lock, so we should
    grab the read side lock before traversing this data structure.

    Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index c806080..0b7eabf 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -591,7 +591,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
struct kvm_run *run)
 	struct kvm_memory_slot *memslot;
 	bool is_iabt;
 	gfn_t gfn;
-	int ret;
+	int ret, idx;

 	hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
