Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio/vhost cross endian support from Michael Tsirkin: "I have just queued some more bugfix patches today but none fix regressions and none are related to these ones, so it looks like a good time for a merge for -rc1. The motivation for this is support for legacy BE guests on the new LE hosts. There are two redeeming properties that made me merge this: - It's a trivial amount of code: since we wrap host/guest accesses anyway, almost all of it is well hidden from drivers. - Sane platforms would never set flags like VHOST_CROSS_ENDIAN_LEGACY, and when it's clear, there's zero overhead (as some point it was tested by compiling with and without the patches, got the same stripped binary). Maybe we could create a Kconfig symbol to enforce the second point: prevent people from enabling it eg on x86. I will look into this" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio-pci: alloc only resources actually used. macvtap/tun: cross-endian support for little-endian hosts vhost: cross-endian support for legacy devices virtio: add explicit big-endian support to memory accessors vhost: introduce vhost_is_little_endian() helper vringh: introduce vringh_is_little_endian() helper macvtap: introduce macvtap_is_little_endian() helper tun: add tun_is_little_endian() helper virtio: introduce virtio_is_little_endian() helper
This commit is contained in:
@@ -111,6 +111,7 @@ do { \
|
||||
#define TUN_FASYNC IFF_ATTACH_QUEUE
|
||||
/* High bits in flags field are unused. */
|
||||
#define TUN_VNET_LE 0x80000000
|
||||
#define TUN_VNET_BE 0x40000000
|
||||
|
||||
#define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
|
||||
IFF_MULTI_QUEUE)
|
||||
@@ -205,14 +206,68 @@ struct tun_struct {
|
||||
u32 flow_count;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TUN_VNET_CROSS_LE
|
||||
static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
|
||||
{
|
||||
return tun->flags & TUN_VNET_BE ? false :
|
||||
virtio_legacy_is_little_endian();
|
||||
}
|
||||
|
||||
static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
|
||||
{
|
||||
int be = !!(tun->flags & TUN_VNET_BE);
|
||||
|
||||
if (put_user(be, argp))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
|
||||
{
|
||||
int be;
|
||||
|
||||
if (get_user(be, argp))
|
||||
return -EFAULT;
|
||||
|
||||
if (be)
|
||||
tun->flags |= TUN_VNET_BE;
|
||||
else
|
||||
tun->flags &= ~TUN_VNET_BE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
|
||||
{
|
||||
return virtio_legacy_is_little_endian();
|
||||
}
|
||||
|
||||
static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* CONFIG_TUN_VNET_CROSS_LE */
|
||||
|
||||
static inline bool tun_is_little_endian(struct tun_struct *tun)
|
||||
{
|
||||
return tun->flags & TUN_VNET_LE ||
|
||||
tun_legacy_is_little_endian(tun);
|
||||
}
|
||||
|
||||
static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
|
||||
{
|
||||
return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val);
|
||||
return __virtio16_to_cpu(tun_is_little_endian(tun), val);
|
||||
}
|
||||
|
||||
static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val)
|
||||
{
|
||||
return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val);
|
||||
return __cpu_to_virtio16(tun_is_little_endian(tun), val);
|
||||
}
|
||||
|
||||
static inline u32 tun_hashfn(u32 rxhash)
|
||||
@@ -2044,6 +2099,14 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
|
||||
tun->flags &= ~TUN_VNET_LE;
|
||||
break;
|
||||
|
||||
case TUNGETVNETBE:
|
||||
ret = tun_get_vnet_be(tun, argp);
|
||||
break;
|
||||
|
||||
case TUNSETVNETBE:
|
||||
ret = tun_set_vnet_be(tun, argp);
|
||||
break;
|
||||
|
||||
case TUNATTACHFILTER:
|
||||
/* Can be set only for TAPs */
|
||||
ret = -EINVAL;
|
||||
|
Reference in New Issue
Block a user