u8 source;                      /* GICv2 SGIs only */
        u8 priority;
        enum vgic_irq_config config;    /* Level or edge */
+
+       void *owner;                    /* Opaque pointer to reserve an interrupt
+                                          for in-kernel devices. */
 };
 
 struct vgic_register_region;
  */
 int kvm_vgic_setup_default_irq_routing(struct kvm *kvm);
 
+int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner);
+
 #endif /* __KVM_ARM_VGIC_H */
 
        return 0;
 }
 
+/**
+ * kvm_vgic_set_owner - Set the owner of an interrupt for a VM
+ *
+ * @vcpu:   Pointer to the VCPU (used for PPIs)
+ * @intid:  The virtual INTID identifying the interrupt (PPI or SPI)
+ * @owner:  Opaque pointer to the owner
+ *
+ * Returns 0 if intid is not already used by another in-kernel device and the
+ * owner is set, otherwise returns an error code.
+ */
+int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner)
+{
+       struct vgic_irq *irq;
+       int ret = 0;
+
+       if (!vgic_initialized(vcpu->kvm))
+               return -EAGAIN;
+
+       /* SGIs and LPIs cannot be wired up to any device */
+       if (!irq_is_ppi(intid) && !vgic_valid_spi(vcpu->kvm, intid))
+               return -EINVAL;
+
+       irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
+       spin_lock(&irq->irq_lock);
+       if (irq->owner && irq->owner != owner)
+               ret = -EEXIST;
+       else
+               irq->owner = owner;
+       spin_unlock(&irq->irq_lock);
+
+       return ret;
+}
+
 /**
  * vgic_prune_ap_list - Remove non-relevant interrupts from the list
  *