Skip to content

Commit

Permalink
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/mst/vhost

Pull virtio fixes from Michael Tsirkin:
 "Fixes all over the place.

  This includes a couple of tests that I would normally defer, but since
  they have already been helpful in catching some bugs, don't build for
  any users at all, and having them upstream makes life easier for
  everyone, I think it's ok even at this late stage"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  tools/virtio: Use tools/include/list.h instead of stubs
  tools/virtio: Reset index in virtio_test --reset.
  tools/virtio: Extract virtqueue initialization in vq_reset
  tools/virtio: Use __vring_new_virtqueue in virtio_test.c
  tools/virtio: Add --reset
  tools/virtio: Add --batch=random option
  tools/virtio: Add --batch option
  virtio-mem: add memory via add_memory_driver_managed()
  virtio-mem: silence a static checker warning
  vhost_vdpa: Fix potential underflow in vhost_vdpa_mmap()
  vdpa: fix typos in the comments for __vdpa_alloc_device()
  • Loading branch information
Linus Torvalds committed Jun 24, 2020
2 parents fbb5801 + cb91909 commit fc10807
Showing 9 changed files with 207 additions and 35 deletions.
2 changes: 1 addition & 1 deletion drivers/vdpa/vdpa.c
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ static void vdpa_release_dev(struct device *d)
* @config: the bus operations that is supported by this device
* @size: size of the parent structure that contains private data
*
* Drvier should use vdap_alloc_device() wrapper macro instead of
* Driver should use vdpa_alloc_device() wrapper macro instead of
* using this directly.
*
* Returns an error when parent/config/dma_dev is not set or fail to get
57 changes: 57 additions & 0 deletions drivers/vhost/test.c
Original file line number Diff line number Diff line change
@@ -263,9 +263,62 @@ static int vhost_test_set_features(struct vhost_test *n, u64 features)
return 0;
}

static long vhost_test_set_backend(struct vhost_test *n, unsigned index, int fd)
{
static void *backend;

const bool enable = fd != -1;
struct vhost_virtqueue *vq;
int r;

mutex_lock(&n->dev.mutex);
r = vhost_dev_check_owner(&n->dev);
if (r)
goto err;

if (index >= VHOST_TEST_VQ_MAX) {
r = -ENOBUFS;
goto err;
}
vq = &n->vqs[index];
mutex_lock(&vq->mutex);

/* Verify that ring has been setup correctly. */
if (!vhost_vq_access_ok(vq)) {
r = -EFAULT;
goto err_vq;
}
if (!enable) {
vhost_poll_stop(&vq->poll);
backend = vhost_vq_get_backend(vq);
vhost_vq_set_backend(vq, NULL);
} else {
vhost_vq_set_backend(vq, backend);
r = vhost_vq_init_access(vq);
if (r == 0)
r = vhost_poll_start(&vq->poll, vq->kick);
}

mutex_unlock(&vq->mutex);

if (enable) {
vhost_test_flush_vq(n, index);
}

mutex_unlock(&n->dev.mutex);
return 0;

err_vq:
mutex_unlock(&vq->mutex);
err:
mutex_unlock(&n->dev.mutex);
return r;
}

static long vhost_test_ioctl(struct file *f, unsigned int ioctl,
unsigned long arg)
{
struct vhost_vring_file backend;
struct vhost_test *n = f->private_data;
void __user *argp = (void __user *)arg;
u64 __user *featurep = argp;
@@ -277,6 +330,10 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl,
if (copy_from_user(&test, argp, sizeof test))
return -EFAULT;
return vhost_test_run(n, test);
case VHOST_TEST_SET_BACKEND:
if (copy_from_user(&backend, argp, sizeof backend))
return -EFAULT;
return vhost_test_set_backend(n, backend.index, backend.fd);
case VHOST_GET_FEATURES:
features = VHOST_FEATURES;
if (copy_to_user(featurep, &features, sizeof features))
1 change: 1 addition & 0 deletions drivers/vhost/test.h
Original file line number Diff line number Diff line change
@@ -4,5 +4,6 @@

/* Start a given test on the virtio null device. 0 stops all tests. */
#define VHOST_TEST_RUN _IOW(VHOST_VIRTIO, 0x31, int)
#define VHOST_TEST_SET_BACKEND _IOW(VHOST_VIRTIO, 0x32, int)

#endif
2 changes: 1 addition & 1 deletion drivers/vhost/vdpa.c
Original file line number Diff line number Diff line change
@@ -818,7 +818,7 @@ static int vhost_vdpa_mmap(struct file *file, struct vm_area_struct *vma)
struct vdpa_device *vdpa = v->vdpa;
const struct vdpa_config_ops *ops = vdpa->config;
struct vdpa_notification_area notify;
int index = vma->vm_pgoff;
unsigned long index = vma->vm_pgoff;

if (vma->vm_end - vma->vm_start != PAGE_SIZE)
return -EINVAL;
27 changes: 23 additions & 4 deletions drivers/virtio/virtio_mem.c
Original file line number Diff line number Diff line change
@@ -101,6 +101,11 @@ struct virtio_mem {

/* The parent resource for all memory added via this device. */
struct resource *parent_resource;
/*
* Copy of "System RAM (virtio_mem)" to be used for
* add_memory_driver_managed().
*/
const char *resource_name;

/* Summary of all memory block states. */
unsigned long nb_mb_state[VIRTIO_MEM_MB_STATE_COUNT];
@@ -414,8 +419,20 @@ static int virtio_mem_mb_add(struct virtio_mem *vm, unsigned long mb_id)
if (nid == NUMA_NO_NODE)
nid = memory_add_physaddr_to_nid(addr);

/*
* When force-unloading the driver and we still have memory added to
* Linux, the resource name has to stay.
*/
if (!vm->resource_name) {
vm->resource_name = kstrdup_const("System RAM (virtio_mem)",
GFP_KERNEL);
if (!vm->resource_name)
return -ENOMEM;
}

dev_dbg(&vm->vdev->dev, "adding memory block: %lu\n", mb_id);
return add_memory(nid, addr, memory_block_size_bytes());
return add_memory_driver_managed(nid, addr, memory_block_size_bytes(),
vm->resource_name);
}

/*
@@ -1192,7 +1209,7 @@ static int virtio_mem_mb_plug_any_sb(struct virtio_mem *vm, unsigned long mb_id,
VIRTIO_MEM_MB_STATE_OFFLINE);
}

return rc;
return 0;
}

/*
@@ -1890,10 +1907,12 @@ static void virtio_mem_remove(struct virtio_device *vdev)
vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL] ||
vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE] ||
vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL] ||
vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE])
vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE]) {
dev_warn(&vdev->dev, "device still has system memory added\n");
else
} else {
virtio_mem_delete_resource(vm);
kfree_const(vm->resource_name);
}

/* remove all tracking data - no locking needed */
vfree(vm->mb_state);
7 changes: 1 addition & 6 deletions tools/virtio/linux/kernel.h
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/printk.h>
#include <linux/bug.h>
#include <errno.h>
@@ -135,10 +136,4 @@ static inline void free_page(unsigned long addr)
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })

/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
#define list_add_tail(a, b) do {} while (0)
#define list_del(a) do {} while (0)
#define list_for_each_entry(a, b, c) while (0)
/* end of stubs */

#endif /* KERNEL_H */
5 changes: 2 additions & 3 deletions tools/virtio/linux/virtio.h
Original file line number Diff line number Diff line change
@@ -11,12 +11,11 @@ struct device {
struct virtio_device {
struct device dev;
u64 features;
struct list_head vqs;
};

struct virtqueue {
/* TODO: commented as list macros are empty stubs for now.
* Broken but enough for virtio_ring.c
* struct list_head list; */
struct list_head list;
void (*callback)(struct virtqueue *vq);
const char *name;
struct virtio_device *vdev;
Loading

0 comments on commit fc10807

Please sign in to comment.