#define BOOK3S_INTERRUPT_FAC_UNAVAIL   0xf60
 #define BOOK3S_INTERRUPT_H_FAC_UNAVAIL 0xf80
 
+/* book3s_hv */
+
+/*
+ * Special trap used to indicate to host that this is a
+ * passthrough interrupt that could not be handled
+ * completely in the guest.
+ */
+#define BOOK3S_INTERRUPT_HV_RM_HARD    0x5555
+
 #define BOOK3S_IRQPRIO_SYSTEM_RESET            0
 #define BOOK3S_IRQPRIO_DATA_SEGMENT            1
 #define BOOK3S_IRQPRIO_INST_SEGMENT            2
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
 #define RESUME_FLAG_ARCH1      (1<<2)
+#define RESUME_FLAG_ARCH2      (1<<3)
 
 #define RESUME_GUEST            0
 #define RESUME_GUEST_NV         RESUME_FLAG_NV
 
 extern void kvmppc_alloc_host_rm_ops(void);
 extern void kvmppc_free_host_rm_ops(void);
 extern void kvmppc_free_pimap(struct kvm *kvm);
+extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall);
 extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
 extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server);
 extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args);
 static inline void kvmppc_alloc_host_rm_ops(void) {};
 static inline void kvmppc_free_host_rm_ops(void) {};
 static inline void kvmppc_free_pimap(struct kvm *kvm) {};
+static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
+       { return 0; }
 static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
        { return 0; }
 static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
 
 
 /* Used to indicate that a guest page fault needs to be handled */
 #define RESUME_PAGE_FAULT      (RESUME_GUEST | RESUME_FLAG_ARCH1)
+/* Used to indicate that a guest passthrough interrupt needs to be handled */
+#define RESUME_PASSTHROUGH     (RESUME_GUEST | RESUME_FLAG_ARCH2)
 
 /* Used as a "null" value for timebase values */
 #define TB_NIL (~(u64)0)
                kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
                r = RESUME_GUEST;
                break;
+       case BOOK3S_INTERRUPT_HV_RM_HARD:
+               r = RESUME_PASSTHROUGH;
+               break;
        default:
                kvmppc_dump_regs(vcpu);
                printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
                        r = kvmppc_book3s_hv_page_fault(run, vcpu,
                                vcpu->arch.fault_dar, vcpu->arch.fault_dsisr);
                        srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx);
-               }
+               } else if (r == RESUME_PASSTHROUGH)
+                       r = kvmppc_xics_rm_complete(vcpu, 0);
        } while (is_kvmppc_resume_guest(r));
 
  out:
 
  * Returns:
  *     0 if no interrupt is pending
  *     1 if an interrupt is pending that needs to be handled by the host
+ *     2 Passthrough that needs completion in the host
  *     -1 if there was a guest wakeup IPI (which has now been cleared)
  *     -2 if there is PCI passthrough external interrupt that was handled
  */
 
        icp_eoi(irq_desc_get_chip(irq_map->desc), irq_map->r_hwirq, xirr);
 
        if (check_too_hard(xics, icp) == H_TOO_HARD)
-               return 1;
+               return 2;
        else
                return -2;
 }
 
         *   1 An interrupt is pending that needs to be handled by the host
         *     Exit guest and return to host by branching to guest_exit_cont
         *
+        *   2 Passthrough that needs completion in the host
+        *     Exit guest and return to host by branching to guest_exit_cont
+        *     However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD
+        *     to indicate to the host to complete handling the interrupt
+        *
         * Before returning to guest, we check if any CPU is heading out
         * to the host and if so, we head out also. If no CPUs are heading
         * check return values <= 0.
         *    Return to guest to deliver any pending guest interrupts.
         */
 
+       cmpdi   r3, 1
+       ble     1f
+
+       /* Return code = 2 */
+       li      r12, BOOK3S_INTERRUPT_HV_RM_HARD
+       stw     r12, VCPU_TRAP(r9)
+       b       guest_exit_cont
+
+1:     /* Return code <= 1 */
        cmpdi   r3, 0
        bgt     guest_exit_cont
 
        bl      kvmppc_read_intr
        nop
        li      r12, BOOK3S_INTERRUPT_EXTERNAL
+       cmpdi   r3, 1
+       ble     1f
+
+       /*
+        * Return code of 2 means PCI passthrough interrupt, but
+        * we need to return back to host to complete handling the
+        * interrupt. Trap reason is expected in r12 by guest
+        * exit code.
+        */
+       li      r12, BOOK3S_INTERRUPT_HV_RM_HARD
+1:
        ld      r0, PPC_MIN_STKFRM+PPC_LR_STKOFF(r1)
        addi    r1, r1, PPC_MIN_STKFRM
        mtlr    r0
 
        return H_SUCCESS;
 }
 
-static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
+int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
 {
        struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
        struct kvmppc_icp *icp = vcpu->arch.icp;
 
        return H_SUCCESS;
 }
+EXPORT_SYMBOL_GPL(kvmppc_xics_rm_complete);
 
 int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
 {