Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull virtio fixes from Michael Tsirkin:
 "Just a bunch of fixes, mostly trivial ones in tools/virtio"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  vhost/vsock: improve RCU read sections around vhost_vsock_get()
  tools/virtio: add device, device_driver stubs
  tools/virtio: fix up oot build
  virtio_features: make it self-contained
  tools/virtio: switch to kernel's virtio_config.h
  tools/virtio: stub might_sleep and synchronize_rcu
  tools/virtio: add struct cpumask to cpumask.h
  tools/virtio: pass KCFLAGS to module build
  tools/virtio: add ucopysize.h stub
  tools/virtio: add dev_WARN_ONCE and is_vmalloc_addr stubs
  tools/virtio: stub DMA mapping functions
  tools/virtio: add struct module forward declaration
  tools/virtio: use kernel's virtio.h
  virtio: make it self-contained
  tools/virtio: fix up compiler.h stub
This commit is contained in:
Linus Torvalds
2025-12-26 11:11:30 -08:00
14 changed files with 93 additions and 180 deletions

View File

@@ -66,14 +66,15 @@ static u32 vhost_transport_get_local_cid(void)
return VHOST_VSOCK_DEFAULT_HOST_CID; return VHOST_VSOCK_DEFAULT_HOST_CID;
} }
/* Callers that dereference the return value must hold vhost_vsock_mutex or the /* Callers must be in an RCU read section or hold the vhost_vsock_mutex.
* RCU read lock. * The return value can only be dereferenced while within the section.
*/ */
static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) static struct vhost_vsock *vhost_vsock_get(u32 guest_cid)
{ {
struct vhost_vsock *vsock; struct vhost_vsock *vsock;
hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid) { hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid,
lockdep_is_held(&vhost_vsock_mutex)) {
u32 other_cid = vsock->guest_cid; u32 other_cid = vsock->guest_cid;
/* Skip instances that have no CID yet */ /* Skip instances that have no CID yet */
@@ -709,9 +710,15 @@ static void vhost_vsock_reset_orphans(struct sock *sk)
* executing. * executing.
*/ */
rcu_read_lock();
/* If the peer is still valid, no need to reset connection */ /* If the peer is still valid, no need to reset connection */
if (vhost_vsock_get(vsk->remote_addr.svm_cid)) if (vhost_vsock_get(vsk->remote_addr.svm_cid)) {
rcu_read_unlock();
return; return;
}
rcu_read_unlock();
/* If the close timeout is pending, let it expire. This avoids races /* If the close timeout is pending, let it expire. This avoids races
* with the timeout callback. * with the timeout callback.

View File

@@ -13,6 +13,8 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/virtio_features.h> #include <linux/virtio_features.h>
struct module;
/** /**
* struct virtqueue - a queue to register buffers for sending or receiving. * struct virtqueue - a queue to register buffers for sending or receiving.
* @list: the chain of virtqueues for this device * @list: the chain of virtqueues for this device

View File

@@ -3,6 +3,8 @@
#define _LINUX_VIRTIO_FEATURES_H #define _LINUX_VIRTIO_FEATURES_H
#include <linux/bits.h> #include <linux/bits.h>
#include <linux/bug.h>
#include <linux/string.h>
#define VIRTIO_FEATURES_U64S 2 #define VIRTIO_FEATURES_U64S 2
#define VIRTIO_FEATURES_BITS (VIRTIO_FEATURES_U64S * 64) #define VIRTIO_FEATURES_BITS (VIRTIO_FEATURES_U64S * 64)

View File

@@ -20,8 +20,9 @@ CFLAGS += -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../
CFLAGS += -pthread CFLAGS += -pthread
LDFLAGS += -pthread LDFLAGS += -pthread
vpath %.c ../../drivers/virtio ../../drivers/vhost vpath %.c ../../drivers/virtio ../../drivers/vhost
BUILD=KCFLAGS="-I "`pwd`/../../drivers/vhost ${MAKE} -C `pwd`/../.. V=${V}
mod: mod:
${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V} ${BUILD} M=`pwd`/vhost_test
#oot: build vhost as an out of tree module for a distro kernel #oot: build vhost as an out of tree module for a distro kernel
#no effort is taken to make it actually build or work, but tends to mostly work #no effort is taken to make it actually build or work, but tends to mostly work
@@ -37,8 +38,9 @@ OOT_CONFIGS=\
CONFIG_VHOST_NET=n \ CONFIG_VHOST_NET=n \
CONFIG_VHOST_SCSI=n \ CONFIG_VHOST_SCSI=n \
CONFIG_VHOST_VSOCK=n \ CONFIG_VHOST_VSOCK=n \
CONFIG_VHOST_RING=n CONFIG_VHOST_RING=n \
OOT_BUILD=KCFLAGS="-I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V} CONFIG_VHOST_VDPA=n
OOT_BUILD=KCFLAGS="-include "`pwd`"/oot-stubs.h -I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V}
oot-build: oot-build:
echo "UNSUPPORTED! Don't use the resulting modules in production!" echo "UNSUPPORTED! Don't use the resulting modules in production!"
${OOT_BUILD} M=`pwd`/vhost_test ${OOT_BUILD} M=`pwd`/vhost_test

View File

@@ -2,7 +2,11 @@
#ifndef LINUX_COMPILER_H #ifndef LINUX_COMPILER_H
#define LINUX_COMPILER_H #define LINUX_COMPILER_H
/* Avoid redefinition warnings */
#undef __user
#include "../../../include/linux/compiler_types.h" #include "../../../include/linux/compiler_types.h"
#undef __user
#define __user
#define WRITE_ONCE(var, val) \ #define WRITE_ONCE(var, val) \
(*((volatile typeof(val) *)(&(var))) = (val)) (*((volatile typeof(val) *)(&(var))) = (val))
@@ -35,4 +39,6 @@
__v; \ __v; \
}) })
#define __must_check
#endif #endif

View File

@@ -4,4 +4,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
struct cpumask {
unsigned long bits[1];
};
#endif /* _LINUX_CPUMASK_H */ #endif /* _LINUX_CPUMASK_H */

View File

@@ -1,2 +1,10 @@
#ifndef LINUX_DEVICE_H #ifndef LINUX_DEVICE_H
struct device {
void *parent;
};
struct device_driver {
const char *name;
};
#endif #endif

View File

@@ -22,6 +22,7 @@ enum dma_data_direction {
#define dma_free_coherent(d, s, p, h) kfree(p) #define dma_free_coherent(d, s, p, h) kfree(p)
#define dma_map_page(d, p, o, s, dir) (page_to_phys(p) + (o)) #define dma_map_page(d, p, o, s, dir) (page_to_phys(p) + (o))
#define dma_map_page_attrs(d, p, o, s, dir, a) (page_to_phys(p) + (o))
#define dma_map_single(d, p, s, dir) (virt_to_phys(p)) #define dma_map_single(d, p, s, dir) (virt_to_phys(p))
#define dma_map_single_attrs(d, p, s, dir, a) (virt_to_phys(p)) #define dma_map_single_attrs(d, p, s, dir, a) (virt_to_phys(p))
@@ -29,6 +30,9 @@ enum dma_data_direction {
#define dma_unmap_single(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0) #define dma_unmap_single(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0)
#define dma_unmap_page(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0) #define dma_unmap_page(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0)
#define dma_unmap_page_attrs(d, a, s, r, t) do { \
(void)(d); (void)(a); (void)(s); (void)(r); (void)(t); \
} while (0)
#define sg_dma_address(sg) (0) #define sg_dma_address(sg) (0)
#define sg_dma_len(sg) (0) #define sg_dma_len(sg) (0)

View File

@@ -14,6 +14,7 @@
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/overflow.h> #include <linux/overflow.h>
#include <linux/limits.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/bug.h> #include <linux/bug.h>
@@ -135,6 +136,21 @@ static inline void *krealloc_array(void *p, size_t new_n, size_t new_size, gfp_t
#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) #define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#define dev_warn_once(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) #define dev_warn_once(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#define dev_WARN_ONCE(dev, condition, format...) \
WARN_ONCE(condition, format)
static inline bool is_vmalloc_addr(const void *x)
{
return false;
}
#define might_sleep() do { } while (0)
static inline void synchronize_rcu(void)
{
assert(0);
}
#define min(x, y) ({ \ #define min(x, y) ({ \
typeof(x) _min1 = (x); \ typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \ typeof(y) _min2 = (y); \

View File

@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <linux/export.h> #include <linux/export.h>
struct module;
#define MODULE_LICENSE(__MODULE_LICENSE_value) \ #define MODULE_LICENSE(__MODULE_LICENSE_value) \
static __attribute__((unused)) const char *__MODULE_LICENSE_name = \ static __attribute__((unused)) const char *__MODULE_LICENSE_name = \
__MODULE_LICENSE_value __MODULE_LICENSE_value

View File

@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_UCOPYSIZE_H__
#define __LINUX_UCOPYSIZE_H__
#include <linux/bug.h>
static inline void check_object_size(const void *ptr, unsigned long n,
bool to_user)
{ }
static inline void copy_overflow(int size, unsigned long count)
{
}
static __always_inline __must_check bool
check_copy_size(const void *addr, size_t bytes, bool is_source)
{
return true;
}
#endif /* __LINUX_UCOPYSIZE_H__ */

View File

@@ -1,72 +1 @@
/* SPDX-License-Identifier: GPL-2.0 */ #include <../../include/linux/virtio.h>
#ifndef LINUX_VIRTIO_H
#define LINUX_VIRTIO_H
#include <linux/scatterlist.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
struct device {
void *parent;
};
struct virtio_device {
struct device dev;
u64 features;
struct list_head vqs;
spinlock_t vqs_list_lock;
const struct virtio_config_ops *config;
};
struct virtqueue {
struct list_head list;
void (*callback)(struct virtqueue *vq);
const char *name;
struct virtio_device *vdev;
unsigned int index;
unsigned int num_free;
unsigned int num_max;
void *priv;
bool reset;
};
/* Interfaces exported by virtio_ring. */
int virtqueue_add_sgs(struct virtqueue *vq,
struct scatterlist *sgs[],
unsigned int out_sgs,
unsigned int in_sgs,
void *data,
gfp_t gfp);
int virtqueue_add_outbuf(struct virtqueue *vq,
struct scatterlist sg[], unsigned int num,
void *data,
gfp_t gfp);
int virtqueue_add_inbuf(struct virtqueue *vq,
struct scatterlist sg[], unsigned int num,
void *data,
gfp_t gfp);
bool virtqueue_kick(struct virtqueue *vq);
void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
void virtqueue_disable_cb(struct virtqueue *vq);
bool virtqueue_enable_cb(struct virtqueue *vq);
bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
void *virtqueue_detach_unused_buf(struct virtqueue *vq);
struct virtqueue *vring_new_virtqueue(unsigned int index,
unsigned int num,
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),
const char *name);
void vring_del_virtqueue(struct virtqueue *vq);
#endif

View File

@@ -1,101 +1 @@
/* SPDX-License-Identifier: GPL-2.0 */ #include "../../include/linux/virtio_config.h"
#ifndef LINUX_VIRTIO_CONFIG_H
#define LINUX_VIRTIO_CONFIG_H
#include <linux/virtio_byteorder.h>
#include <linux/virtio.h>
#include <uapi/linux/virtio_config.h>
struct virtio_config_ops {
int (*disable_vq_and_reset)(struct virtqueue *vq);
int (*enable_vq_after_reset)(struct virtqueue *vq);
};
/*
* __virtio_test_bit - helper to test feature bits. For use by transports.
* Devices should normally use virtio_has_feature,
* which includes more checks.
* @vdev: the device
* @fbit: the feature bit
*/
static inline bool __virtio_test_bit(const struct virtio_device *vdev,
unsigned int fbit)
{
return vdev->features & (1ULL << fbit);
}
/**
* __virtio_set_bit - helper to set feature bits. For use by transports.
* @vdev: the device
* @fbit: the feature bit
*/
static inline void __virtio_set_bit(struct virtio_device *vdev,
unsigned int fbit)
{
vdev->features |= (1ULL << fbit);
}
/**
* __virtio_clear_bit - helper to clear feature bits. For use by transports.
* @vdev: the device
* @fbit: the feature bit
*/
static inline void __virtio_clear_bit(struct virtio_device *vdev,
unsigned int fbit)
{
vdev->features &= ~(1ULL << fbit);
}
#define virtio_has_feature(dev, feature) \
(__virtio_test_bit((dev), feature))
/**
* virtio_has_dma_quirk - determine whether this device has the DMA quirk
* @vdev: the device
*/
static inline bool virtio_has_dma_quirk(const struct virtio_device *vdev)
{
/*
* Note the reverse polarity of the quirk feature (compared to most
* other features), this is for compatibility with legacy systems.
*/
return !virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM);
}
static inline bool virtio_is_little_endian(struct virtio_device *vdev)
{
return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
virtio_legacy_is_little_endian();
}
/* Memory accessors */
static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
{
return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
{
return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
}
static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
{
return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
{
return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
}
static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
{
return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
{
return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
}
#endif

10
tools/virtio/oot-stubs.h Normal file
View File

@@ -0,0 +1,10 @@
#include <linux/bug.h>
#include <linux/string.h>
#include <linux/virtio_features.h>
#ifndef VIRTIO_FEATURES_BITS
#define VIRTIO_FEATURES_BITS 128
#endif
#ifndef VIRTIO_U64
#define VIRTIO_U64(b) ((b) >> 6)
#endif