mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
um: drivers: Add virtio vhost-user driver
This module allows virtio devices to be used over a vhost-user socket. Signed-off-by: Erel Geron <erelx.geron@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
851b6cb17c
commit
5d38f32499
@ -335,3 +335,10 @@ config UML_NET_SLIRP
|
||||
Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
|
||||
|
||||
endmenu
|
||||
|
||||
config VIRTIO_UML
|
||||
tristate "UML driver for virtio devices"
|
||||
select VIRTIO
|
||||
help
|
||||
This driver provides support for virtio based paravirtual device
|
||||
drivers over vhost-user sockets.
|
||||
|
@ -61,6 +61,7 @@ obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
|
||||
obj-$(CONFIG_UML_WATCHDOG) += harddog.o
|
||||
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
|
||||
obj-$(CONFIG_UML_RANDOM) += random.o
|
||||
obj-$(CONFIG_VIRTIO_UML) += virtio_uml.o
|
||||
|
||||
# pcap_user.o must be added explicitly.
|
||||
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o vector_user.o
|
||||
|
102
arch/um/drivers/vhost_user.h
Normal file
102
arch/um/drivers/vhost_user.h
Normal file
@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* Vhost-user protocol */
|
||||
|
||||
#ifndef __VHOST_USER_H__
|
||||
#define __VHOST_USER_H__
|
||||
|
||||
/* Message flags */
|
||||
#define VHOST_USER_FLAG_REPLY BIT(2)
|
||||
/* Feature bits */
|
||||
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||
/* Protocol feature bits */
|
||||
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
||||
/* Vring state index masks */
|
||||
#define VHOST_USER_VRING_INDEX_MASK 0xff
|
||||
#define VHOST_USER_VRING_POLL_MASK BIT(8)
|
||||
|
||||
/* Supported version */
|
||||
#define VHOST_USER_VERSION 1
|
||||
/* Supported transport features */
|
||||
#define VHOST_USER_SUPPORTED_F BIT_ULL(VHOST_USER_F_PROTOCOL_FEATURES)
|
||||
/* Supported protocol features */
|
||||
#define VHOST_USER_SUPPORTED_PROTOCOL_F BIT_ULL(VHOST_USER_PROTOCOL_F_CONFIG)
|
||||
|
||||
enum vhost_user_request {
|
||||
VHOST_USER_GET_FEATURES = 1,
|
||||
VHOST_USER_SET_FEATURES = 2,
|
||||
VHOST_USER_SET_OWNER = 3,
|
||||
VHOST_USER_RESET_OWNER = 4,
|
||||
VHOST_USER_SET_MEM_TABLE = 5,
|
||||
VHOST_USER_SET_LOG_BASE = 6,
|
||||
VHOST_USER_SET_LOG_FD = 7,
|
||||
VHOST_USER_SET_VRING_NUM = 8,
|
||||
VHOST_USER_SET_VRING_ADDR = 9,
|
||||
VHOST_USER_SET_VRING_BASE = 10,
|
||||
VHOST_USER_GET_VRING_BASE = 11,
|
||||
VHOST_USER_SET_VRING_KICK = 12,
|
||||
VHOST_USER_SET_VRING_CALL = 13,
|
||||
VHOST_USER_SET_VRING_ERR = 14,
|
||||
VHOST_USER_GET_PROTOCOL_FEATURES = 15,
|
||||
VHOST_USER_SET_PROTOCOL_FEATURES = 16,
|
||||
VHOST_USER_GET_QUEUE_NUM = 17,
|
||||
VHOST_USER_SET_VRING_ENABLE = 18,
|
||||
VHOST_USER_SEND_RARP = 19,
|
||||
VHOST_USER_NET_SEND_MTU = 20,
|
||||
VHOST_USER_SET_SLAVE_REQ_FD = 21,
|
||||
VHOST_USER_IOTLB_MSG = 22,
|
||||
VHOST_USER_SET_VRING_ENDIAN = 23,
|
||||
VHOST_USER_GET_CONFIG = 24,
|
||||
VHOST_USER_SET_CONFIG = 25,
|
||||
};
|
||||
|
||||
struct vhost_user_header {
|
||||
u32 request; /* Use enum vhost_user_request */
|
||||
u32 flags;
|
||||
u32 size;
|
||||
} __packed;
|
||||
|
||||
struct vhost_user_config {
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 flags;
|
||||
u8 payload[0]; /* Variable length */
|
||||
} __packed;
|
||||
|
||||
struct vhost_user_vring_state {
|
||||
u32 index;
|
||||
u32 num;
|
||||
} __packed;
|
||||
|
||||
struct vhost_user_vring_addr {
|
||||
u32 index;
|
||||
u32 flags;
|
||||
u64 desc, used, avail, log;
|
||||
} __packed;
|
||||
|
||||
struct vhost_user_mem_region {
|
||||
u64 guest_addr;
|
||||
u64 size;
|
||||
u64 user_addr;
|
||||
u64 mmap_offset;
|
||||
} __packed;
|
||||
|
||||
struct vhost_user_mem_regions {
|
||||
u32 num;
|
||||
u32 padding;
|
||||
struct vhost_user_mem_region regions[2]; /* Currently supporting 2 */
|
||||
} __packed;
|
||||
|
||||
union vhost_user_payload {
|
||||
u64 integer;
|
||||
struct vhost_user_config config;
|
||||
struct vhost_user_vring_state vring_state;
|
||||
struct vhost_user_vring_addr vring_addr;
|
||||
struct vhost_user_mem_regions mem_regions;
|
||||
};
|
||||
|
||||
struct vhost_user_msg {
|
||||
struct vhost_user_header header;
|
||||
union vhost_user_payload payload;
|
||||
} __packed;
|
||||
|
||||
#endif
|
1002
arch/um/drivers/virtio_uml.c
Normal file
1002
arch/um/drivers/virtio_uml.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,17 +17,18 @@
|
||||
#define TELNETD_IRQ 12
|
||||
#define XTERM_IRQ 13
|
||||
#define RANDOM_IRQ 14
|
||||
#define VIRTIO_IRQ 15
|
||||
|
||||
#ifdef CONFIG_UML_NET_VECTOR
|
||||
|
||||
#define VECTOR_BASE_IRQ 15
|
||||
#define VECTOR_BASE_IRQ (VIRTIO_IRQ + 1)
|
||||
#define VECTOR_IRQ_SPACE 8
|
||||
|
||||
#define LAST_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ - 1)
|
||||
|
||||
#else
|
||||
|
||||
#define LAST_IRQ RANDOM_IRQ
|
||||
#define LAST_IRQ VIRTIO_IRQ
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
#define OS_LIB_PATH "/usr/lib/"
|
||||
#endif
|
||||
|
||||
#define OS_SENDMSG_MAX_FDS 8
|
||||
|
||||
/*
|
||||
* types taken from stat_file() in hostfs_user.c
|
||||
* (if they are wrong here, they are wrong there...).
|
||||
@ -176,6 +178,9 @@ extern unsigned os_major(unsigned long long dev);
|
||||
extern unsigned os_minor(unsigned long long dev);
|
||||
extern unsigned long long os_makedev(unsigned major, unsigned minor);
|
||||
extern int os_falloc_punch(int fd, unsigned long long offset, int count);
|
||||
extern int os_eventfd(unsigned int initval, int flags);
|
||||
extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len,
|
||||
const int *fds, unsigned int fds_num);
|
||||
|
||||
/* start_up.c */
|
||||
extern void os_early_checks(void);
|
||||
|
@ -38,6 +38,8 @@ EXPORT_SYMBOL(run_helper);
|
||||
EXPORT_SYMBOL(os_major);
|
||||
EXPORT_SYMBOL(os_minor);
|
||||
EXPORT_SYMBOL(os_makedev);
|
||||
EXPORT_SYMBOL(os_eventfd);
|
||||
EXPORT_SYMBOL(os_sendmsg_fds);
|
||||
|
||||
EXPORT_SYMBOL(add_sigio_fd);
|
||||
EXPORT_SYMBOL(ignore_sigio_fd);
|
||||
|
@ -31,6 +31,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
/* Initialized at boot time, and readonly after that */
|
||||
unsigned long long highmem;
|
||||
EXPORT_SYMBOL(highmem);
|
||||
int kmalloc_ok = 0;
|
||||
|
||||
/* Used during early boot */
|
||||
|
@ -143,6 +143,7 @@ int phys_mapping(unsigned long phys, unsigned long long *offset_out)
|
||||
|
||||
return fd;
|
||||
}
|
||||
EXPORT_SYMBOL(phys_mapping);
|
||||
|
||||
static int __init uml_mem_setup(char *line, int *add)
|
||||
{
|
||||
|
@ -113,6 +113,7 @@ static int have_root __initdata = 0;
|
||||
|
||||
/* Set in uml_mem_setup and modified in linux_main */
|
||||
long long physmem_size = 32 * 1024 * 1024;
|
||||
EXPORT_SYMBOL(physmem_size);
|
||||
|
||||
static const char *usage_string =
|
||||
"User Mode Linux v%s\n"
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <os.h>
|
||||
|
||||
static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
|
||||
@ -620,3 +621,46 @@ int os_falloc_punch(int fd, unsigned long long offset, int len)
|
||||
return n;
|
||||
}
|
||||
|
||||
int os_eventfd(unsigned int initval, int flags)
|
||||
{
|
||||
int fd = eventfd(initval, flags);
|
||||
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
return fd;
|
||||
}
|
||||
|
||||
int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds,
|
||||
unsigned int fds_num)
|
||||
{
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *) buf,
|
||||
.iov_len = len,
|
||||
};
|
||||
union {
|
||||
char control[CMSG_SPACE(sizeof(*fds) * OS_SENDMSG_MAX_FDS)];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
unsigned int fds_size = sizeof(*fds) * fds_num;
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = u.control,
|
||||
.msg_controllen = CMSG_SPACE(fds_size),
|
||||
};
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
int err;
|
||||
|
||||
if (fds_num > OS_SENDMSG_MAX_FDS)
|
||||
return -EINVAL;
|
||||
memset(u.control, 0, sizeof(u.control));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(fds_size);
|
||||
memcpy(CMSG_DATA(cmsg), fds, fds_size);
|
||||
err = sendmsg(fd, &msg, 0);
|
||||
|
||||
if (err < 0)
|
||||
return -errno;
|
||||
return err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user