Commit f94682dd authored by Michael S. Tsirkin's avatar Michael S. Tsirkin

virtio: add context flag to find vqs

Allows maintaining extra context per vq.  For ease of use, passing in
NULL is legal and disables the feature for all vqs.

Includes fixes by Christian for s390, acked by Cornelia.
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Acked-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 9b2bbdb2
...@@ -278,7 +278,7 @@ static void vop_del_vqs(struct virtio_device *dev) ...@@ -278,7 +278,7 @@ static void vop_del_vqs(struct virtio_device *dev)
static struct virtqueue *vop_find_vq(struct virtio_device *dev, static struct virtqueue *vop_find_vq(struct virtio_device *dev,
unsigned index, unsigned index,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name) const char *name, bool ctx)
{ {
struct _vop_vdev *vdev = to_vopvdev(dev); struct _vop_vdev *vdev = to_vopvdev(dev);
struct vop_device *vpdev = vdev->vpdev; struct vop_device *vpdev = vdev->vpdev;
...@@ -314,6 +314,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev, ...@@ -314,6 +314,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN, le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN,
dev, dev,
false, false,
ctx,
(void __force *)va, vop_notify, callback, name); (void __force *)va, vop_notify, callback, name);
if (!vq) { if (!vq) {
err = -ENOMEM; err = -ENOMEM;
...@@ -374,7 +375,8 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev, ...@@ -374,7 +375,8 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs, static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs,
struct virtqueue *vqs[], struct virtqueue *vqs[],
vq_callback_t *callbacks[], 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_vdev *vdev = to_vopvdev(dev);
struct vop_device *vpdev = vdev->vpdev; struct vop_device *vpdev = vdev->vpdev;
...@@ -388,7 +390,8 @@ static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs, ...@@ -388,7 +390,8 @@ static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs,
for (i = 0; i < nvqs; ++i) { for (i = 0; i < nvqs; ++i) {
dev_dbg(_vop_dev(vdev), "%s: %d: %s\n", dev_dbg(_vop_dev(vdev), "%s: %d: %s\n",
__func__, i, names[i]); __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])) { if (IS_ERR(vqs[i])) {
err = PTR_ERR(vqs[i]); err = PTR_ERR(vqs[i]);
goto error; goto error;
......
...@@ -71,7 +71,7 @@ EXPORT_SYMBOL(rproc_vq_interrupt); ...@@ -71,7 +71,7 @@ EXPORT_SYMBOL(rproc_vq_interrupt);
static struct virtqueue *rp_find_vq(struct virtio_device *vdev, static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
unsigned int id, unsigned int id,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name) const char *name, bool ctx)
{ {
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct rproc *rproc = vdev_to_rproc(vdev); struct rproc *rproc = vdev_to_rproc(vdev);
...@@ -103,8 +103,8 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, ...@@ -103,8 +103,8 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
* Create the new vq, and tell virtio we're not interested in * Create the new vq, and tell virtio we're not interested in
* the 'weak' smp barriers, since we're talking with a real device. * the 'weak' smp barriers, since we're talking with a real device.
*/ */
vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr, vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, ctx,
rproc_virtio_notify, callback, name); addr, rproc_virtio_notify, callback, name);
if (!vq) { if (!vq) {
dev_err(dev, "vring_new_virtqueue %s failed\n", name); dev_err(dev, "vring_new_virtqueue %s failed\n", name);
rproc_free_vring(rvring); rproc_free_vring(rvring);
...@@ -138,12 +138,14 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, ...@@ -138,12 +138,14 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
struct virtqueue *vqs[], struct virtqueue *vqs[],
vq_callback_t *callbacks[], vq_callback_t *callbacks[],
const char * const names[], const char * const names[],
const bool * ctx,
struct irq_affinity *desc) struct irq_affinity *desc)
{ {
int i, ret; int i, ret;
for (i = 0; i < nvqs; ++i) { 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])) { if (IS_ERR(vqs[i])) {
ret = PTR_ERR(vqs[i]); ret = PTR_ERR(vqs[i]);
goto error; goto error;
......
...@@ -189,7 +189,7 @@ static bool kvm_notify(struct virtqueue *vq) ...@@ -189,7 +189,7 @@ static bool kvm_notify(struct virtqueue *vq)
static struct virtqueue *kvm_find_vq(struct virtio_device *vdev, static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
unsigned index, unsigned index,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name) const char *name, bool ctx)
{ {
struct kvm_device *kdev = to_kvmdev(vdev); struct kvm_device *kdev = to_kvmdev(vdev);
struct kvm_vqconfig *config; struct kvm_vqconfig *config;
...@@ -211,7 +211,7 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev, ...@@ -211,7 +211,7 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
goto out; goto out;
vq = vring_new_virtqueue(index, config->num, KVM_S390_VIRTIO_RING_ALIGN, 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); kvm_notify, callback, name);
if (!vq) { if (!vq) {
err = -ENOMEM; err = -ENOMEM;
...@@ -256,6 +256,7 @@ static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -256,6 +256,7 @@ static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], struct virtqueue *vqs[],
vq_callback_t *callbacks[], vq_callback_t *callbacks[],
const char * const names[], const char * const names[],
const bool *ctx,
struct irq_affinity *desc) struct irq_affinity *desc)
{ {
struct kvm_device *kdev = to_kvmdev(vdev); struct kvm_device *kdev = to_kvmdev(vdev);
...@@ -266,7 +267,8 @@ static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -266,7 +267,8 @@ static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
return -ENOENT; return -ENOENT;
for (i = 0; i < nvqs; ++i) { 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])) if (IS_ERR(vqs[i]))
goto error; goto error;
} }
......
...@@ -484,7 +484,7 @@ static void virtio_ccw_del_vqs(struct virtio_device *vdev) ...@@ -484,7 +484,7 @@ static void virtio_ccw_del_vqs(struct virtio_device *vdev)
static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
int i, vq_callback_t *callback, int i, vq_callback_t *callback,
const char *name, const char *name, bool ctx,
struct ccw1 *ccw) struct ccw1 *ccw)
{ {
struct virtio_ccw_device *vcdev = to_vc_device(vdev); struct virtio_ccw_device *vcdev = to_vc_device(vdev);
...@@ -522,7 +522,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, ...@@ -522,7 +522,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
} }
vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, 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); callback, name);
if (!vq) { if (!vq) {
/* For now, we fail if we can't get the requested size. */ /* For now, we fail if we can't get the requested size. */
...@@ -629,6 +629,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -629,6 +629,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], struct virtqueue *vqs[],
vq_callback_t *callbacks[], vq_callback_t *callbacks[],
const char * const names[], const char * const names[],
const bool *ctx,
struct irq_affinity *desc) struct irq_affinity *desc)
{ {
struct virtio_ccw_device *vcdev = to_vc_device(vdev); struct virtio_ccw_device *vcdev = to_vc_device(vdev);
...@@ -642,7 +643,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -642,7 +643,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
for (i = 0; i < nvqs; ++i) { for (i = 0; i < nvqs; ++i) {
vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i], vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i],
ccw); ctx ? ctx[i] : false, ccw);
if (IS_ERR(vqs[i])) { if (IS_ERR(vqs[i])) {
ret = PTR_ERR(vqs[i]); ret = PTR_ERR(vqs[i]);
vqs[i] = NULL; vqs[i] = NULL;
......
...@@ -351,7 +351,7 @@ static void vm_del_vqs(struct virtio_device *vdev) ...@@ -351,7 +351,7 @@ static void vm_del_vqs(struct virtio_device *vdev)
static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index, static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
void (*callback)(struct virtqueue *vq), 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_device *vm_dev = to_virtio_mmio_device(vdev);
struct virtio_mmio_vq_info *info; struct virtio_mmio_vq_info *info;
...@@ -388,7 +388,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index, ...@@ -388,7 +388,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
/* Create the vring */ /* Create the vring */
vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev, 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) { if (!vq) {
err = -ENOMEM; err = -ENOMEM;
goto error_new_virtqueue; goto error_new_virtqueue;
...@@ -447,6 +447,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -447,6 +447,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], struct virtqueue *vqs[],
vq_callback_t *callbacks[], vq_callback_t *callbacks[],
const char * const names[], const char * const names[],
const bool *ctx,
struct irq_affinity *desc) struct irq_affinity *desc)
{ {
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
...@@ -459,7 +460,8 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -459,7 +460,8 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
return err; return err;
for (i = 0; i < nvqs; ++i) { 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])) { if (IS_ERR(vqs[i])) {
vm_del_vqs(vdev); vm_del_vqs(vdev);
return PTR_ERR(vqs[i]); return PTR_ERR(vqs[i]);
......
...@@ -172,6 +172,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, ...@@ -172,6 +172,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index, static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name, const char *name,
bool ctx,
u16 msix_vec) u16 msix_vec)
{ {
struct virtio_pci_device *vp_dev = to_vp_device(vdev); struct virtio_pci_device *vp_dev = to_vp_device(vdev);
...@@ -183,7 +184,7 @@ static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index, ...@@ -183,7 +184,7 @@ static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index,
if (!info) if (!info)
return ERR_PTR(-ENOMEM); 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); msix_vec);
if (IS_ERR(vq)) if (IS_ERR(vq))
goto out_info; goto out_info;
...@@ -274,6 +275,7 @@ void vp_del_vqs(struct virtio_device *vdev) ...@@ -274,6 +275,7 @@ void vp_del_vqs(struct virtio_device *vdev)
static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], struct virtqueue *vqs[], vq_callback_t *callbacks[],
const char * const names[], bool per_vq_vectors, const char * const names[], bool per_vq_vectors,
const bool *ctx,
struct irq_affinity *desc) struct irq_affinity *desc)
{ {
struct virtio_pci_device *vp_dev = to_vp_device(vdev); struct virtio_pci_device *vp_dev = to_vp_device(vdev);
...@@ -315,6 +317,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, ...@@ -315,6 +317,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
else else
msix_vec = VP_MSIX_VQ_VECTOR; msix_vec = VP_MSIX_VQ_VECTOR;
vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i], vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i],
ctx ? ctx[i] : false,
msix_vec); msix_vec);
if (IS_ERR(vqs[i])) { if (IS_ERR(vqs[i])) {
err = PTR_ERR(vqs[i]); err = PTR_ERR(vqs[i]);
...@@ -345,7 +348,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, ...@@ -345,7 +348,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], 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); struct virtio_pci_device *vp_dev = to_vp_device(vdev);
int i, err; int i, err;
...@@ -367,6 +370,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, ...@@ -367,6 +370,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
continue; continue;
} }
vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i], vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i],
ctx ? ctx[i] : false,
VIRTIO_MSI_NO_VECTOR); VIRTIO_MSI_NO_VECTOR);
if (IS_ERR(vqs[i])) { if (IS_ERR(vqs[i])) {
err = PTR_ERR(vqs[i]); err = PTR_ERR(vqs[i]);
...@@ -383,20 +387,21 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, ...@@ -383,20 +387,21 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
/* the config->find_vqs() implementation */ /* the config->find_vqs() implementation */
int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs, int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], 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; int err;
/* Try MSI-X with one vector per queue. */ /* 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) if (!err)
return 0; return 0;
/* Fallback: MSI-X with one vector for config, one shared for queues. */ /* 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) if (!err)
return 0; return 0;
/* Finally fall back to regular interrupts. */ /* 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) const char *vp_bus_name(struct virtio_device *vdev)
......
...@@ -102,6 +102,7 @@ struct virtio_pci_device { ...@@ -102,6 +102,7 @@ struct virtio_pci_device {
unsigned idx, unsigned idx,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name, const char *name,
bool ctx,
u16 msix_vec); u16 msix_vec);
void (*del_vq)(struct virtio_pci_vq_info *info); void (*del_vq)(struct virtio_pci_vq_info *info);
...@@ -131,7 +132,8 @@ void vp_del_vqs(struct virtio_device *vdev); ...@@ -131,7 +132,8 @@ void vp_del_vqs(struct virtio_device *vdev);
/* the config->find_vqs() implementation */ /* the config->find_vqs() implementation */
int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs, int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], 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); const char *vp_bus_name(struct virtio_device *vdev);
/* Setup the affinity for a virtqueue: /* Setup the affinity for a virtqueue:
......
...@@ -116,6 +116,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, ...@@ -116,6 +116,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
unsigned index, unsigned index,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name, const char *name,
bool ctx,
u16 msix_vec) u16 msix_vec)
{ {
struct virtqueue *vq; struct virtqueue *vq;
...@@ -135,7 +136,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, ...@@ -135,7 +136,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
/* create the vring */ /* create the vring */
vq = vring_create_virtqueue(index, num, vq = vring_create_virtqueue(index, num,
VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev, VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev,
true, false, vp_notify, callback, name); true, false, ctx,
vp_notify, callback, name);
if (!vq) if (!vq)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
......
...@@ -297,6 +297,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, ...@@ -297,6 +297,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
unsigned index, unsigned index,
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name, const char *name,
bool ctx,
u16 msix_vec) u16 msix_vec)
{ {
struct virtio_pci_common_cfg __iomem *cfg = vp_dev->common; struct virtio_pci_common_cfg __iomem *cfg = vp_dev->common;
...@@ -328,7 +329,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, ...@@ -328,7 +329,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
/* create the vring */ /* create the vring */
vq = vring_create_virtqueue(index, num, vq = vring_create_virtqueue(index, num,
SMP_CACHE_BYTES, &vp_dev->vdev, SMP_CACHE_BYTES, &vp_dev->vdev,
true, true, vp_notify, callback, name); true, true, ctx,
vp_notify, callback, name);
if (!vq) if (!vq)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -387,12 +389,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, ...@@ -387,12 +389,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
} }
static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs, static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], struct virtqueue *vqs[],
const char * const names[], struct irq_affinity *desc) 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 virtio_pci_device *vp_dev = to_vp_device(vdev);
struct virtqueue *vq; 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) if (rc)
return rc; return rc;
......
...@@ -916,6 +916,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, ...@@ -916,6 +916,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
struct vring vring, struct vring vring,
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool context,
bool (*notify)(struct virtqueue *), bool (*notify)(struct virtqueue *),
void (*callback)(struct virtqueue *), void (*callback)(struct virtqueue *),
const char *name) const char *name)
...@@ -1019,6 +1020,7 @@ struct virtqueue *vring_create_virtqueue( ...@@ -1019,6 +1020,7 @@ struct virtqueue *vring_create_virtqueue(
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool may_reduce_num, bool may_reduce_num,
bool context,
bool (*notify)(struct virtqueue *), bool (*notify)(struct virtqueue *),
void (*callback)(struct virtqueue *), void (*callback)(struct virtqueue *),
const char *name) const char *name)
...@@ -1058,7 +1060,7 @@ struct virtqueue *vring_create_virtqueue( ...@@ -1058,7 +1060,7 @@ struct virtqueue *vring_create_virtqueue(
queue_size_in_bytes = vring_size(num, vring_align); queue_size_in_bytes = vring_size(num, vring_align);
vring_init(&vring, num, queue, 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); notify, callback, name);
if (!vq) { if (!vq) {
vring_free_queue(vdev, queue_size_in_bytes, queue, vring_free_queue(vdev, queue_size_in_bytes, queue,
...@@ -1079,6 +1081,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, ...@@ -1079,6 +1081,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
unsigned int vring_align, unsigned int vring_align,
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool context,
void *pages, void *pages,
bool (*notify)(struct virtqueue *vq), bool (*notify)(struct virtqueue *vq),
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
...@@ -1086,7 +1089,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, ...@@ -1086,7 +1089,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
{ {
struct vring vring; struct vring vring;
vring_init(&vring, num, pages, vring_align); 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); notify, callback, name);
} }
EXPORT_SYMBOL_GPL(vring_new_virtqueue); EXPORT_SYMBOL_GPL(vring_new_virtqueue);
......
...@@ -72,7 +72,8 @@ struct virtio_config_ops { ...@@ -72,7 +72,8 @@ struct virtio_config_ops {
void (*reset)(struct virtio_device *vdev); void (*reset)(struct virtio_device *vdev);
int (*find_vqs)(struct virtio_device *, unsigned nvqs, int (*find_vqs)(struct virtio_device *, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[], 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 *); void (*del_vqs)(struct virtio_device *);
u64 (*get_features)(struct virtio_device *vdev); u64 (*get_features)(struct virtio_device *vdev);
int (*finalize_features)(struct virtio_device *vdev); int (*finalize_features)(struct virtio_device *vdev);
...@@ -173,7 +174,8 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, ...@@ -173,7 +174,8 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
vq_callback_t *callbacks[] = { c }; vq_callback_t *callbacks[] = { c };
const char *names[] = { n }; const char *names[] = { n };
struct virtqueue *vq; 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) if (err < 0)
return ERR_PTR(err); return ERR_PTR(err);
return vq; return vq;
...@@ -185,7 +187,17 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, ...@@ -185,7 +187,17 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
const char * const names[], const char * const names[],
struct irq_affinity *desc) 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);
} }
/** /**
......
...@@ -71,6 +71,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int index, ...@@ -71,6 +71,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int index,
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool may_reduce_num, bool may_reduce_num,
bool ctx,
bool (*notify)(struct virtqueue *vq), bool (*notify)(struct virtqueue *vq),
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
const char *name); const char *name);
...@@ -80,6 +81,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, ...@@ -80,6 +81,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
struct vring vring, struct vring vring,
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool ctx,
bool (*notify)(struct virtqueue *), bool (*notify)(struct virtqueue *),
void (*callback)(struct virtqueue *), void (*callback)(struct virtqueue *),
const char *name); const char *name);
...@@ -93,6 +95,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, ...@@ -93,6 +95,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
unsigned int vring_align, unsigned int vring_align,
struct virtio_device *vdev, struct virtio_device *vdev,
bool weak_barriers, bool weak_barriers,
bool ctx,
void *pages, void *pages,
bool (*notify)(struct virtqueue *vq), bool (*notify)(struct virtqueue *vq),
void (*callback)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment