mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
virtio/vhost: fixes for 4.2
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. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVpBzpAAoJECgfDbjSjVRpQXEIAMEqetqPuRduynjIw2HNktle fe/UUhvipwTsAM4R2pmcEl5tW04A/M54RkXN4iVy0rPshAfG3Fh4XTjLmzSGU0fI KD6qX8/Zc/+DUWnfe3aUC6jOOrjb7c4xRKOlQ9X8lZgi2M6AzrPeoZHFTtbX34CU 2kcnv5Sb1SaI/t2SaCc2CaKilQalEOcd59gGjje2QXjidZnIVHwONrOyjBiINUy6 GzfTgvAje8ZiG6951W3HDwwSfcqXezin27LJqnZgaLCwTCKt2gdQ2MAKjrfP2aVF +gX2B4XxcFLutMVx/obsjvA1ceipubyUauRLB3mnO3P5VOj1qbofa2lj4pzQ80k= =EKPr -----END PGP SIGNATURE----- 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:
commit
d1a343a023
10
MAINTAINERS
10
MAINTAINERS
@ -5899,7 +5899,6 @@ S: Supported
|
||||
F: Documentation/s390/kvm.txt
|
||||
F: arch/s390/include/asm/kvm*
|
||||
F: arch/s390/kvm/
|
||||
F: drivers/s390/kvm/
|
||||
|
||||
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
|
||||
M: Christoffer Dall <christoffer.dall@linaro.org>
|
||||
@ -10896,6 +10895,15 @@ F: drivers/block/virtio_blk.c
|
||||
F: include/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
|
||||
M: David Airlie <airlied@linux.ie>
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
|
@ -2,7 +2,7 @@
|
||||
# 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
|
||||
|
||||
|
@ -949,7 +949,7 @@ static int virtscsi_probe(struct virtio_device *vdev)
|
||||
{
|
||||
struct Scsi_Host *shost;
|
||||
struct virtio_scsi *vscsi;
|
||||
int err, host_prot;
|
||||
int err;
|
||||
u32 sg_elems, num_targets;
|
||||
u32 cmd_per_lun;
|
||||
u32 num_queues;
|
||||
@ -1009,6 +1009,8 @@ static int virtscsi_probe(struct virtio_device *vdev)
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||
if (virtio_has_feature(vdev, VIRTIO_SCSI_F_T10_PI)) {
|
||||
int host_prot;
|
||||
|
||||
host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION |
|
||||
SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION |
|
||||
SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION;
|
||||
|
@ -22,14 +22,20 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sort.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 {
|
||||
VHOST_MEMORY_MAX_NREGIONS = 64,
|
||||
VHOST_MEMORY_F_LOG = 0x1,
|
||||
};
|
||||
|
||||
@ -543,7 +549,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev, bool locked)
|
||||
fput(dev->log_file);
|
||||
dev->log_file = NULL;
|
||||
/* No one will access memory at this point */
|
||||
kfree(dev->memory);
|
||||
kvfree(dev->memory);
|
||||
dev->memory = NULL;
|
||||
WARN_ON(!list_empty(&dev->work_list));
|
||||
if (dev->worker) {
|
||||
@ -663,6 +669,28 @@ int vhost_vq_access_ok(struct vhost_virtqueue *vq)
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (mem.padding)
|
||||
return -EOPNOTSUPP;
|
||||
if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS)
|
||||
if (mem.nregions > max_mem_regions)
|
||||
return -E2BIG;
|
||||
newmem = kmalloc(size + mem.nregions * sizeof *m->regions, GFP_KERNEL);
|
||||
newmem = vhost_kvzalloc(size + mem.nregions * sizeof(*m->regions));
|
||||
if (!newmem)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(newmem, &mem, size);
|
||||
if (copy_from_user(newmem->regions, m->regions,
|
||||
mem.nregions * sizeof *m->regions)) {
|
||||
kfree(newmem);
|
||||
kvfree(newmem);
|
||||
return -EFAULT;
|
||||
}
|
||||
sort(newmem->regions, newmem->nregions, sizeof(*newmem->regions),
|
||||
vhost_memory_reg_sort_cmp, NULL);
|
||||
|
||||
if (!memory_access_ok(d, newmem, 0)) {
|
||||
kfree(newmem);
|
||||
kvfree(newmem);
|
||||
return -EFAULT;
|
||||
}
|
||||
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;
|
||||
mutex_unlock(&d->vqs[i]->mutex);
|
||||
}
|
||||
kfree(oldmem);
|
||||
kvfree(oldmem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -992,17 +1022,22 @@ EXPORT_SYMBOL_GPL(vhost_dev_ioctl);
|
||||
static const struct vhost_memory_region *find_region(struct vhost_memory *mem,
|
||||
__u64 addr, __u32 len)
|
||||
{
|
||||
struct vhost_memory_region *reg;
|
||||
int i;
|
||||
const struct vhost_memory_region *reg;
|
||||
int start = 0, end = mem->nregions;
|
||||
|
||||
/* linear search is not brilliant, but we really have on the order of 6
|
||||
* regions in practice */
|
||||
for (i = 0; i < mem->nregions; ++i) {
|
||||
reg = mem->regions + i;
|
||||
if (reg->guest_phys_addr <= addr &&
|
||||
reg->guest_phys_addr + reg->memory_size - 1 >= addr)
|
||||
return reg;
|
||||
while (start < end) {
|
||||
int slot = start + (end - start) / 2;
|
||||
reg = mem->regions + slot;
|
||||
if (addr >= reg->guest_phys_addr)
|
||||
end = slot;
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
/* The feature bitmap for virtio net */
|
||||
#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_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
|
||||
#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_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_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 */
|
||||
|
@ -157,6 +157,12 @@ struct virtio_pci_common_cfg {
|
||||
__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! */
|
||||
#define VIRTIO_PCI_CAP_VNDR 0
|
||||
#define VIRTIO_PCI_CAP_NEXT 1
|
||||
|
@ -31,6 +31,9 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Copyright Rusty Russell IBM Corporation 2007. */
|
||||
#ifndef __KERNEL__
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <linux/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->desc = p;
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -704,6 +704,7 @@ static void p9_virtio_remove(struct virtio_device *vdev)
|
||||
|
||||
mutex_unlock(&virtio_9p_lock);
|
||||
|
||||
vdev->config->reset(vdev);
|
||||
vdev->config->del_vqs(vdev);
|
||||
|
||||
sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
|
||||
|
Loading…
Reference in New Issue
Block a user