}
 }
 
-/**
- * kvmppc_handle_exit
- *
- * Return value is in the form (errcode<<2 | RESUME_FLAG_HOST | RESUME_FLAG_NV)
- */
-int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
-                       unsigned int exit_nr)
+static void kvmppc_fill_pt_regs(struct pt_regs *regs)
 {
-       int r = RESUME_HOST;
+       ulong r1, ip, msr, lr;
+
+       asm("mr %0, 1" : "=r"(r1));
+       asm("mflr %0" : "=r"(lr));
+       asm("mfmsr %0" : "=r"(msr));
+       asm("bl 1f; 1: mflr %0" : "=r"(ip));
+
+       memset(regs, 0, sizeof(*regs));
+       regs->gpr[1] = r1;
+       regs->nip = ip;
+       regs->msr = msr;
+       regs->link = lr;
+}
 
-       /* update before a new last_exit_type is rewritten */
-       kvmppc_update_timing_stats(vcpu);
+static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
+                                    unsigned int exit_nr)
+{
+       struct pt_regs regs;
 
        switch (exit_nr) {
        case BOOKE_INTERRUPT_EXTERNAL:
-               do_IRQ(current->thread.regs);
+               kvmppc_fill_pt_regs(®s);
+               do_IRQ(®s);
                break;
-
        case BOOKE_INTERRUPT_DECREMENTER:
-               timer_interrupt(current->thread.regs);
+               kvmppc_fill_pt_regs(®s);
+               timer_interrupt(®s);
                break;
-
 #if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_BOOK3E_64)
        case BOOKE_INTERRUPT_DOORBELL:
-               doorbell_exception(current->thread.regs);
+               kvmppc_fill_pt_regs(®s);
+               doorbell_exception(®s);
                break;
 #endif
        case BOOKE_INTERRUPT_MACHINE_CHECK:
                /* FIXME */
                break;
        }
+}
+
+/**
+ * kvmppc_handle_exit
+ *
+ * Return value is in the form (errcode<<2 | RESUME_FLAG_HOST | RESUME_FLAG_NV)
+ */
+int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                       unsigned int exit_nr)
+{
+       int r = RESUME_HOST;
+
+       /* update before a new last_exit_type is rewritten */
+       kvmppc_update_timing_stats(vcpu);
+
+       /* restart interrupts if they were meant for the host */
+       kvmppc_restart_interrupt(vcpu, exit_nr);
 
        local_irq_enable();