Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio/vhost fixes from Michael Tsirkin: "Bugfixes and documentation fixes. Igor's patch that allows users to tweak memory table size is borderline, but it does fix known crashes, so I merged it" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: vhost: add max_mem_regions module parameter vhost: extend memory regions allocation to vmalloc 9p/trans_virtio: reset virtio device on remove virtio/s390: rename drivers/s390/kvm -> drivers/s390/virtio MAINTAINERS: separate section for s390 virtio drivers virtio: define virtio_pci_cfg_cap in header. virtio: Fix typecast of pointer in vring_init() virtio scsi: fix unused variable warning vhost: use binary search instead of linear in find_region() virtio_net: document VIRTIO_NET_CTRL_GUEST_OFFLOADS
This commit is contained in:
10
MAINTAINERS
10
MAINTAINERS
@@ -5899,7 +5899,6 @@ S: Supported
|
|||||||
F: Documentation/s390/kvm.txt
|
F: Documentation/s390/kvm.txt
|
||||||
F: arch/s390/include/asm/kvm*
|
F: arch/s390/include/asm/kvm*
|
||||||
F: arch/s390/kvm/
|
F: arch/s390/kvm/
|
||||||
F: drivers/s390/kvm/
|
|
||||||
|
|
||||||
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
|
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
|
||||||
M: Christoffer Dall <christoffer.dall@linaro.org>
|
M: Christoffer Dall <christoffer.dall@linaro.org>
|
||||||
@@ -10896,6 +10895,15 @@ F: drivers/block/virtio_blk.c
|
|||||||
F: include/linux/virtio_*.h
|
F: include/linux/virtio_*.h
|
||||||
F: include/uapi/linux/virtio_*.h
|
F: include/uapi/linux/virtio_*.h
|
||||||
|
|
||||||
|
VIRTIO DRIVERS FOR S390
|
||||||
|
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||||
|
M: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||||
|
L: linux-s390@vger.kernel.org
|
||||||
|
L: virtualization@lists.linux-foundation.org
|
||||||
|
L: kvm@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
F: drivers/s390/virtio/
|
||||||
|
|
||||||
VIRTIO GPU DRIVER
|
VIRTIO GPU DRIVER
|
||||||
M: David Airlie <airlied@linux.ie>
|
M: David Airlie <airlied@linux.ie>
|
||||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
# Makefile for the S/390 specific device drivers
|
# Makefile for the S/390 specific device drivers
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
|
obj-y += cio/ block/ char/ crypto/ net/ scsi/ virtio/
|
||||||
|
|
||||||
drivers-y += drivers/s390/built-in.o
|
drivers-y += drivers/s390/built-in.o
|
||||||
|
|
||||||
|
@@ -949,7 +949,7 @@ static int virtscsi_probe(struct virtio_device *vdev)
|
|||||||
{
|
{
|
||||||
struct Scsi_Host *shost;
|
struct Scsi_Host *shost;
|
||||||
struct virtio_scsi *vscsi;
|
struct virtio_scsi *vscsi;
|
||||||
int err, host_prot;
|
int err;
|
||||||
u32 sg_elems, num_targets;
|
u32 sg_elems, num_targets;
|
||||||
u32 cmd_per_lun;
|
u32 cmd_per_lun;
|
||||||
u32 num_queues;
|
u32 num_queues;
|
||||||
@@ -1009,6 +1009,8 @@ static int virtscsi_probe(struct virtio_device *vdev)
|
|||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||||
if (virtio_has_feature(vdev, VIRTIO_SCSI_F_T10_PI)) {
|
if (virtio_has_feature(vdev, VIRTIO_SCSI_F_T10_PI)) {
|
||||||
|
int host_prot;
|
||||||
|
|
||||||
host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION |
|
host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION |
|
||||||
SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION |
|
SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION |
|
||||||
SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION;
|
SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION;
|
||||||
|
@@ -22,14 +22,20 @@
|
|||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/cgroup.h>
|
#include <linux/cgroup.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/sort.h>
|
||||||
|
|
||||||
#include "vhost.h"
|
#include "vhost.h"
|
||||||
|
|
||||||
|
static ushort max_mem_regions = 64;
|
||||||
|
module_param(max_mem_regions, ushort, 0444);
|
||||||
|
MODULE_PARM_DESC(max_mem_regions,
|
||||||
|
"Maximum number of memory regions in memory map. (default: 64)");
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VHOST_MEMORY_MAX_NREGIONS = 64,
|
|
||||||
VHOST_MEMORY_F_LOG = 0x1,
|
VHOST_MEMORY_F_LOG = 0x1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -543,7 +549,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev, bool locked)
|
|||||||
fput(dev->log_file);
|
fput(dev->log_file);
|
||||||
dev->log_file = NULL;
|
dev->log_file = NULL;
|
||||||
/* No one will access memory at this point */
|
/* No one will access memory at this point */
|
||||||
kfree(dev->memory);
|
kvfree(dev->memory);
|
||||||
dev->memory = NULL;
|
dev->memory = NULL;
|
||||||
WARN_ON(!list_empty(&dev->work_list));
|
WARN_ON(!list_empty(&dev->work_list));
|
||||||
if (dev->worker) {
|
if (dev->worker) {
|
||||||
@@ -663,6 +669,28 @@ int vhost_vq_access_ok(struct vhost_virtqueue *vq)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vhost_vq_access_ok);
|
EXPORT_SYMBOL_GPL(vhost_vq_access_ok);
|
||||||
|
|
||||||
|
static int vhost_memory_reg_sort_cmp(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
const struct vhost_memory_region *r1 = p1, *r2 = p2;
|
||||||
|
if (r1->guest_phys_addr < r2->guest_phys_addr)
|
||||||
|
return 1;
|
||||||
|
if (r1->guest_phys_addr > r2->guest_phys_addr)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *vhost_kvzalloc(unsigned long size)
|
||||||
|
{
|
||||||
|
void *n = kzalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
|
||||||
|
|
||||||
|
if (!n) {
|
||||||
|
n = vzalloc(size);
|
||||||
|
if (!n)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
|
static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
|
||||||
{
|
{
|
||||||
struct vhost_memory mem, *newmem, *oldmem;
|
struct vhost_memory mem, *newmem, *oldmem;
|
||||||
@@ -673,21 +701,23 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (mem.padding)
|
if (mem.padding)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS)
|
if (mem.nregions > max_mem_regions)
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
newmem = kmalloc(size + mem.nregions * sizeof *m->regions, GFP_KERNEL);
|
newmem = vhost_kvzalloc(size + mem.nregions * sizeof(*m->regions));
|
||||||
if (!newmem)
|
if (!newmem)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memcpy(newmem, &mem, size);
|
memcpy(newmem, &mem, size);
|
||||||
if (copy_from_user(newmem->regions, m->regions,
|
if (copy_from_user(newmem->regions, m->regions,
|
||||||
mem.nregions * sizeof *m->regions)) {
|
mem.nregions * sizeof *m->regions)) {
|
||||||
kfree(newmem);
|
kvfree(newmem);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
sort(newmem->regions, newmem->nregions, sizeof(*newmem->regions),
|
||||||
|
vhost_memory_reg_sort_cmp, NULL);
|
||||||
|
|
||||||
if (!memory_access_ok(d, newmem, 0)) {
|
if (!memory_access_ok(d, newmem, 0)) {
|
||||||
kfree(newmem);
|
kvfree(newmem);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
oldmem = d->memory;
|
oldmem = d->memory;
|
||||||
@@ -699,7 +729,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
|
|||||||
d->vqs[i]->memory = newmem;
|
d->vqs[i]->memory = newmem;
|
||||||
mutex_unlock(&d->vqs[i]->mutex);
|
mutex_unlock(&d->vqs[i]->mutex);
|
||||||
}
|
}
|
||||||
kfree(oldmem);
|
kvfree(oldmem);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,17 +1022,22 @@ EXPORT_SYMBOL_GPL(vhost_dev_ioctl);
|
|||||||
static const struct vhost_memory_region *find_region(struct vhost_memory *mem,
|
static const struct vhost_memory_region *find_region(struct vhost_memory *mem,
|
||||||
__u64 addr, __u32 len)
|
__u64 addr, __u32 len)
|
||||||
{
|
{
|
||||||
struct vhost_memory_region *reg;
|
const struct vhost_memory_region *reg;
|
||||||
int i;
|
int start = 0, end = mem->nregions;
|
||||||
|
|
||||||
/* linear search is not brilliant, but we really have on the order of 6
|
while (start < end) {
|
||||||
* regions in practice */
|
int slot = start + (end - start) / 2;
|
||||||
for (i = 0; i < mem->nregions; ++i) {
|
reg = mem->regions + slot;
|
||||||
reg = mem->regions + i;
|
if (addr >= reg->guest_phys_addr)
|
||||||
if (reg->guest_phys_addr <= addr &&
|
end = slot;
|
||||||
reg->guest_phys_addr + reg->memory_size - 1 >= addr)
|
else
|
||||||
return reg;
|
start = slot + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg = mem->regions + start;
|
||||||
|
if (addr >= reg->guest_phys_addr &&
|
||||||
|
reg->guest_phys_addr + reg->memory_size > addr)
|
||||||
|
return reg;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
/* The feature bitmap for virtio net */
|
/* The feature bitmap for virtio net */
|
||||||
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
|
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
|
||||||
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
|
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
|
||||||
|
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
|
||||||
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
|
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
|
||||||
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
|
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
|
||||||
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
|
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
|
||||||
@@ -226,4 +227,19 @@ struct virtio_net_ctrl_mq {
|
|||||||
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
|
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
|
||||||
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
|
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control network offloads
|
||||||
|
*
|
||||||
|
* Reconfigures the network offloads that Guest can handle.
|
||||||
|
*
|
||||||
|
* Available with the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
|
||||||
|
*
|
||||||
|
* Command data format matches the feature bit mask exactly.
|
||||||
|
*
|
||||||
|
* See VIRTIO_NET_F_GUEST_* for the list of offloads
|
||||||
|
* that can be enabled/disabled.
|
||||||
|
*/
|
||||||
|
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
|
||||||
|
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
|
||||||
|
|
||||||
#endif /* _LINUX_VIRTIO_NET_H */
|
#endif /* _LINUX_VIRTIO_NET_H */
|
||||||
|
@@ -157,6 +157,12 @@ struct virtio_pci_common_cfg {
|
|||||||
__le32 queue_used_hi; /* read-write */
|
__le32 queue_used_hi; /* read-write */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Fields in VIRTIO_PCI_CAP_PCI_CFG: */
|
||||||
|
struct virtio_pci_cfg_cap {
|
||||||
|
struct virtio_pci_cap cap;
|
||||||
|
__u8 pci_cfg_data[4]; /* Data for BAR access. */
|
||||||
|
};
|
||||||
|
|
||||||
/* Macro versions of offsets for the Old Timers! */
|
/* Macro versions of offsets for the Old Timers! */
|
||||||
#define VIRTIO_PCI_CAP_VNDR 0
|
#define VIRTIO_PCI_CAP_VNDR 0
|
||||||
#define VIRTIO_PCI_CAP_NEXT 1
|
#define VIRTIO_PCI_CAP_NEXT 1
|
||||||
|
@@ -31,6 +31,9 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Copyright Rusty Russell IBM Corporation 2007. */
|
* Copyright Rusty Russell IBM Corporation 2007. */
|
||||||
|
#ifndef __KERNEL__
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/virtio_types.h>
|
#include <linux/virtio_types.h>
|
||||||
|
|
||||||
@@ -143,7 +146,7 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
|
|||||||
vr->num = num;
|
vr->num = num;
|
||||||
vr->desc = p;
|
vr->desc = p;
|
||||||
vr->avail = p + num*sizeof(struct vring_desc);
|
vr->avail = p + num*sizeof(struct vring_desc);
|
||||||
vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16)
|
vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)
|
||||||
+ align-1) & ~(align - 1));
|
+ align-1) & ~(align - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -704,6 +704,7 @@ static void p9_virtio_remove(struct virtio_device *vdev)
|
|||||||
|
|
||||||
mutex_unlock(&virtio_9p_lock);
|
mutex_unlock(&virtio_9p_lock);
|
||||||
|
|
||||||
|
vdev->config->reset(vdev);
|
||||||
vdev->config->del_vqs(vdev);
|
vdev->config->del_vqs(vdev);
|
||||||
|
|
||||||
sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
|
sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
|
||||||
|
Reference in New Issue
Block a user