static struct virtqueue *vop_find_vq(struct virtio_device *dev,
                                     unsigned index,
                                     void (*callback)(struct virtqueue *vq),
-                                    const char *name)
+                                    const char *name, bool ctx)
 {
        struct _vop_vdev *vdev = to_vopvdev(dev);
        struct vop_device *vpdev = vdev->vpdev;
                                le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN,
                                dev,
                                false,
+                               ctx,
                                (void __force *)va, vop_notify, callback, name);
        if (!vq) {
                err = -ENOMEM;
 static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs,
                        struct virtqueue *vqs[],
                        vq_callback_t *callbacks[],
-                       const char * const names[], struct irq_affinity *desc)
+                       const char * const names[], const bool *ctx,
+                       struct irq_affinity *desc)
 {
        struct _vop_vdev *vdev = to_vopvdev(dev);
        struct vop_device *vpdev = vdev->vpdev;
        for (i = 0; i < nvqs; ++i) {
                dev_dbg(_vop_dev(vdev), "%s: %d: %s\n",
                        __func__, i, names[i]);
-               vqs[i] = vop_find_vq(dev, i, callbacks[i], names[i]);
+               vqs[i] = vop_find_vq(dev, i, callbacks[i], names[i],
+                                    ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        err = PTR_ERR(vqs[i]);
                        goto error;
 
 static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
                                    unsigned int id,
                                    void (*callback)(struct virtqueue *vq),
-                                   const char *name)
+                                   const char *name, bool ctx)
 {
        struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
        struct rproc *rproc = vdev_to_rproc(vdev);
         * Create the new vq, and tell virtio we're not interested in
         * the 'weak' smp barriers, since we're talking with a real device.
         */
-       vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr,
-                                rproc_virtio_notify, callback, name);
+       vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, ctx,
+                                addr, rproc_virtio_notify, callback, name);
        if (!vq) {
                dev_err(dev, "vring_new_virtqueue %s failed\n", name);
                rproc_free_vring(rvring);
                                 struct virtqueue *vqs[],
                                 vq_callback_t *callbacks[],
                                 const char * const names[],
+                                const bool * ctx,
                                 struct irq_affinity *desc)
 {
        int i, ret;
 
        for (i = 0; i < nvqs; ++i) {
-               vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]);
+               vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i],
+                                   ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        ret = PTR_ERR(vqs[i]);
                        goto error;
 
 static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
                                     unsigned index,
                                     void (*callback)(struct virtqueue *vq),
-                                    const char *name)
+                                    const char *name, bool ctx)
 {
        struct kvm_device *kdev = to_kvmdev(vdev);
        struct kvm_vqconfig *config;
                goto out;
 
        vq = vring_new_virtqueue(index, config->num, KVM_S390_VIRTIO_RING_ALIGN,
-                                vdev, true, (void *) config->address,
+                                vdev, true, ctx, (void *) config->address,
                                 kvm_notify, callback, name);
        if (!vq) {
                err = -ENOMEM;
                        struct virtqueue *vqs[],
                        vq_callback_t *callbacks[],
                        const char * const names[],
+                       const bool *ctx,
                        struct irq_affinity *desc)
 {
        struct kvm_device *kdev = to_kvmdev(vdev);
                return -ENOENT;
 
        for (i = 0; i < nvqs; ++i) {
-               vqs[i] = kvm_find_vq(vdev, i, callbacks[i], names[i]);
+               vqs[i] = kvm_find_vq(vdev, i, callbacks[i], names[i],
+                                    ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i]))
                        goto error;
        }
 
 
 static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
                                             int i, vq_callback_t *callback,
-                                            const char *name,
+                                            const char *name, bool ctx,
                                             struct ccw1 *ccw)
 {
        struct virtio_ccw_device *vcdev = to_vc_device(vdev);
        }
 
        vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev,
-                                true, info->queue, virtio_ccw_kvm_notify,
+                                true, ctx, info->queue, virtio_ccw_kvm_notify,
                                 callback, name);
        if (!vq) {
                /* For now, we fail if we can't get the requested size. */
                               struct virtqueue *vqs[],
                               vq_callback_t *callbacks[],
                               const char * const names[],
+                              const bool *ctx,
                               struct irq_affinity *desc)
 {
        struct virtio_ccw_device *vcdev = to_vc_device(vdev);
 
        for (i = 0; i < nvqs; ++i) {
                vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i],
-                                            ccw);
+                                            ctx ? ctx[i] : false, ccw);
                if (IS_ERR(vqs[i])) {
                        ret = PTR_ERR(vqs[i]);
                        vqs[i] = NULL;
 
 
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
                                  void (*callback)(struct virtqueue *vq),
-                                 const char *name)
+                                 const char *name, bool ctx)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
        struct virtio_mmio_vq_info *info;
 
        /* Create the vring */
        vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
-                                true, true, vm_notify, callback, name);
+                                true, true, ctx, vm_notify, callback, name);
        if (!vq) {
                err = -ENOMEM;
                goto error_new_virtqueue;
                       struct virtqueue *vqs[],
                       vq_callback_t *callbacks[],
                       const char * const names[],
+                      const bool *ctx,
                       struct irq_affinity *desc)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
                return err;
 
        for (i = 0; i < nvqs; ++i) {
-               vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i]);
+               vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i],
+                                    ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        vm_del_vqs(vdev);
                        return PTR_ERR(vqs[i]);
 
 static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index,
                                     void (*callback)(struct virtqueue *vq),
                                     const char *name,
+                                    bool ctx,
                                     u16 msix_vec)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        if (!info)
                return ERR_PTR(-ENOMEM);
 
-       vq = vp_dev->setup_vq(vp_dev, info, index, callback, name,
+       vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, ctx,
                              msix_vec);
        if (IS_ERR(vq))
                goto out_info;
 static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
                const char * const names[], bool per_vq_vectors,
+               const bool *ctx,
                struct irq_affinity *desc)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
                else
                        msix_vec = VP_MSIX_VQ_VECTOR;
                vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i],
+                                    ctx ? ctx[i] : false,
                                     msix_vec);
                if (IS_ERR(vqs[i])) {
                        err = PTR_ERR(vqs[i]);
 
 static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[])
+               const char * const names[], const bool *ctx)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        int i, err;
                        continue;
                }
                vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i],
+                                    ctx ? ctx[i] : false,
                                     VIRTIO_MSI_NO_VECTOR);
                if (IS_ERR(vqs[i])) {
                        err = PTR_ERR(vqs[i]);
 /* the config->find_vqs() implementation */
 int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], struct irq_affinity *desc)
+               const char * const names[], const bool *ctx,
+               struct irq_affinity *desc)
 {
        int err;
 
        /* Try MSI-X with one vector per queue. */
-       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, desc);
+       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, desc);
        if (!err)
                return 0;
        /* Fallback: MSI-X with one vector for config, one shared for queues. */
-       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, desc);
+       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, desc);
        if (!err)
                return 0;
        /* Finally fall back to regular interrupts. */
-       return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names);
+       return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
 }
 
 const char *vp_bus_name(struct virtio_device *vdev)
 
                                      unsigned idx,
                                      void (*callback)(struct virtqueue *vq),
                                      const char *name,
+                                     bool ctx,
                                      u16 msix_vec);
        void (*del_vq)(struct virtio_pci_vq_info *info);
 
 /* the config->find_vqs() implementation */
 int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], struct irq_affinity *desc);
+               const char * const names[], const bool *ctx,
+               struct irq_affinity *desc);
 const char *vp_bus_name(struct virtio_device *vdev);
 
 /* Setup the affinity for a virtqueue:
 
                                  unsigned index,
                                  void (*callback)(struct virtqueue *vq),
                                  const char *name,
+                                 bool ctx,
                                  u16 msix_vec)
 {
        struct virtqueue *vq;
        /* create the vring */
        vq = vring_create_virtqueue(index, num,
                                    VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev,
-                                   true, false, vp_notify, callback, name);
+                                   true, false, ctx,
+                                   vp_notify, callback, name);
        if (!vq)
                return ERR_PTR(-ENOMEM);
 
 
                                  unsigned index,
                                  void (*callback)(struct virtqueue *vq),
                                  const char *name,
+                                 bool ctx,
                                  u16 msix_vec)
 {
        struct virtio_pci_common_cfg __iomem *cfg = vp_dev->common;
        /* create the vring */
        vq = vring_create_virtqueue(index, num,
                                    SMP_CACHE_BYTES, &vp_dev->vdev,
-                                   true, true, vp_notify, callback, name);
+                                   true, true, ctx,
+                                   vp_notify, callback, name);
        if (!vq)
                return ERR_PTR(-ENOMEM);
 
 }
 
 static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs,
-               struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], struct irq_affinity *desc)
+                             struct virtqueue *vqs[],
+                             vq_callback_t *callbacks[],
+                             const char * const names[], const bool *ctx,
+                             struct irq_affinity *desc)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        struct virtqueue *vq;
-       int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names, desc);
+       int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names, ctx, desc);
 
        if (rc)
                return rc;
 
                                        struct vring vring,
                                        struct virtio_device *vdev,
                                        bool weak_barriers,
+                                       bool context,
                                        bool (*notify)(struct virtqueue *),
                                        void (*callback)(struct virtqueue *),
                                        const char *name)
        struct virtio_device *vdev,
        bool weak_barriers,
        bool may_reduce_num,
+       bool context,
        bool (*notify)(struct virtqueue *),
        void (*callback)(struct virtqueue *),
        const char *name)
        queue_size_in_bytes = vring_size(num, vring_align);
        vring_init(&vring, num, queue, vring_align);
 
-       vq = __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+       vq = __vring_new_virtqueue(index, vring, vdev, weak_barriers, context,
                                   notify, callback, name);
        if (!vq) {
                vring_free_queue(vdev, queue_size_in_bytes, queue,
                                      unsigned int vring_align,
                                      struct virtio_device *vdev,
                                      bool weak_barriers,
+                                     bool context,
                                      void *pages,
                                      bool (*notify)(struct virtqueue *vq),
                                      void (*callback)(struct virtqueue *vq),
 {
        struct vring vring;
        vring_init(&vring, num, pages, vring_align);
-       return __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+       return __vring_new_virtqueue(index, vring, vdev, weak_barriers, context,
                                     notify, callback, name);
 }
 EXPORT_SYMBOL_GPL(vring_new_virtqueue);
 
        void (*reset)(struct virtio_device *vdev);
        int (*find_vqs)(struct virtio_device *, unsigned nvqs,
                        struct virtqueue *vqs[], vq_callback_t *callbacks[],
-                       const char * const names[], struct irq_affinity *desc);
+                       const char * const names[], const bool *ctx,
+                       struct irq_affinity *desc);
        void (*del_vqs)(struct virtio_device *);
        u64 (*get_features)(struct virtio_device *vdev);
        int (*finalize_features)(struct virtio_device *vdev);
        vq_callback_t *callbacks[] = { c };
        const char *names[] = { n };
        struct virtqueue *vq;
-       int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL);
+       int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL,
+                                        NULL);
        if (err < 0)
                return ERR_PTR(err);
        return vq;
                        const char * const names[],
                        struct irq_affinity *desc)
 {
-       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, desc);
+       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL, desc);
+}
+
+static inline
+int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs,
+                       struct virtqueue *vqs[], vq_callback_t *callbacks[],
+                       const char * const names[], const bool *ctx,
+                       struct irq_affinity *desc)
+{
+       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, ctx,
+                                     desc);
 }
 
 /**
 
                                         struct virtio_device *vdev,
                                         bool weak_barriers,
                                         bool may_reduce_num,
+                                        bool ctx,
                                         bool (*notify)(struct virtqueue *vq),
                                         void (*callback)(struct virtqueue *vq),
                                         const char *name);
                                        struct vring vring,
                                        struct virtio_device *vdev,
                                        bool weak_barriers,
+                                       bool ctx,
                                        bool (*notify)(struct virtqueue *),
                                        void (*callback)(struct virtqueue *),
                                        const char *name);
                                      unsigned int vring_align,
                                      struct virtio_device *vdev,
                                      bool weak_barriers,
+                                     bool ctx,
                                      void *pages,
                                      bool (*notify)(struct virtqueue *vq),
                                      void (*callback)(struct virtqueue *vq),