]> Gentwo Git Trees - linux/.git/commitdiff
vhost: switch to arrays of feature bits
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 13 Nov 2025 22:42:05 +0000 (17:42 -0500)
committerMichael S. Tsirkin <mst@redhat.com>
Sun, 30 Nov 2025 23:02:43 +0000 (18:02 -0500)
The current interface where caller has to know in which 64 bit chunk
each bit is, is inelegant and fragile.
Let's simply use arrays of bits.
By using unroll macros text size grows only slightly.

Message-ID: <637e182e139980e5930d50b928ba5ac072d628a9.1764225384.git.mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vhost/net.c
drivers/vhost/scsi.c
drivers/vhost/test.c
drivers/vhost/vhost.h
drivers/vhost/vsock.c

index d057ea55f5add4a52be1d4d17dbbde57b11c554c..f8ed39337f5673a6e673f0e188539fc34b8517ed 100644 (file)
@@ -69,15 +69,15 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"
 
 #define VHOST_DMA_IS_DONE(len) ((__force u32)(len) >= (__force u32)VHOST_DMA_DONE_LEN)
 
-static const u64 vhost_net_features[VIRTIO_FEATURES_U64S] = {
-       VHOST_FEATURES |
-       (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
-       (1ULL << VIRTIO_NET_F_MRG_RXBUF) |
-       (1ULL << VIRTIO_F_ACCESS_PLATFORM) |
-       (1ULL << VIRTIO_F_RING_RESET) |
-       (1ULL << VIRTIO_F_IN_ORDER),
-       VIRTIO_BIT(VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO) |
-       VIRTIO_BIT(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO),
+static const int vhost_net_bits[] = {
+       VHOST_FEATURES,
+       VHOST_NET_F_VIRTIO_NET_HDR,
+       VIRTIO_NET_F_MRG_RXBUF,
+       VIRTIO_F_ACCESS_PLATFORM,
+       VIRTIO_F_RING_RESET,
+       VIRTIO_F_IN_ORDER,
+       VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO,
+       VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO
 };
 
 enum {
@@ -1720,6 +1720,7 @@ static long vhost_net_set_owner(struct vhost_net *n)
 static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
                            unsigned long arg)
 {
+       const DEFINE_VHOST_FEATURES_ARRAY(vhost_net_features, vhost_net_bits);
        u64 all_features[VIRTIO_FEATURES_U64S];
        struct vhost_net *n = f->private_data;
        void __user *argp = (void __user *)arg;
index 98e4f68f4e3cb6a6a3a0983e77577b95cb9ca1dc..f43c1fe9fad9ae3acb72261aa6f0023a5b105b51 100644 (file)
@@ -197,11 +197,14 @@ enum {
 };
 
 /* Note: can't set VIRTIO_F_VERSION_1 yet, since that implies ANY_LAYOUT. */
-enum {
-       VHOST_SCSI_FEATURES = VHOST_FEATURES | (1ULL << VIRTIO_SCSI_F_HOTPLUG) |
-                                              (1ULL << VIRTIO_SCSI_F_T10_PI)
+static const int vhost_scsi_bits[] = {
+       VHOST_FEATURES,
+       VIRTIO_SCSI_F_HOTPLUG,
+       VIRTIO_SCSI_F_T10_PI
 };
 
+#define VHOST_SCSI_FEATURES VHOST_FEATURES_U64(vhost_scsi_bits, 0)
+
 #define VHOST_SCSI_MAX_TARGET  256
 #define VHOST_SCSI_MAX_IO_VQ   1024
 #define VHOST_SCSI_MAX_EVENT   128
index 94cd09f36f59c323401a8c0cf6876ac643836f3b..1e4e36edbcd262882fe5cccbdc6e1e5132debc08 100644 (file)
  */
 #define VHOST_TEST_PKT_WEIGHT 256
 
-#define VHOST_TEST_FEATURES VHOST_FEATURES
+static const int vhost_test_bits[] = {
+       VHOST_FEATURES
+};
+
+#define VHOST_TEST_FEATURES VHOST_FEATURES_U64(vhost_test_bits, 0)
 
 enum {
        VHOST_TEST_VQ = 0,
index 621a6d9a8791f3d7af23bf93acc392a3c4f27483..c7b92730668e0f38467af186042a0f2dbb9f3e11 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/atomic.h>
 #include <linux/vhost_iotlb.h>
 #include <linux/irqbypass.h>
+#include <linux/unroll.h>
 
 struct vhost_work;
 struct vhost_task;
@@ -279,14 +280,39 @@ void vhost_iotlb_map_free(struct vhost_iotlb *iotlb,
                                eventfd_signal((vq)->error_ctx);\
        } while (0)
 
-enum {
-       VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) |
-                        (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
-                        (1ULL << VIRTIO_RING_F_EVENT_IDX) |
-                        (1ULL << VHOST_F_LOG_ALL) |
-                        (1ULL << VIRTIO_F_ANY_LAYOUT) |
-                        (1ULL << VIRTIO_F_VERSION_1)
-};
+#define VHOST_FEATURES \
+       VIRTIO_F_NOTIFY_ON_EMPTY, \
+       VIRTIO_RING_F_INDIRECT_DESC, \
+       VIRTIO_RING_F_EVENT_IDX, \
+       VHOST_F_LOG_ALL, \
+       VIRTIO_F_ANY_LAYOUT, \
+       VIRTIO_F_VERSION_1
+
+static inline u64 vhost_features_u64(const int *features, int size, int idx)
+{
+       u64 res = 0;
+
+       unrolled_count(VIRTIO_FEATURES_BITS)
+       for (int i = 0; i < size; ++i) {
+               int bit = features[i];
+
+               if (virtio_features_chk_bit(bit) && VIRTIO_U64(bit) == idx)
+                       res |= VIRTIO_BIT(bit);
+       }
+       return res;
+}
+
+#define VHOST_FEATURES_U64(features, idx) \
+       vhost_features_u64(features, ARRAY_SIZE(features), idx)
+
+#define DEFINE_VHOST_FEATURES_ARRAY_ENTRY(idx, features) \
+       [idx] = VHOST_FEATURES_U64(features, idx),
+
+#define DEFINE_VHOST_FEATURES_ARRAY(array, features) \
+       u64 array[VIRTIO_FEATURES_U64S] = { \
+               UNROLL(VIRTIO_FEATURES_U64S, \
+                      DEFINE_VHOST_FEATURES_ARRAY_ENTRY, features) \
+       }
 
 /**
  * vhost_vq_set_backend - Set backend.
index ae01457ea2cdbb2a3813c6cbf72b8ad9a405343e..0298ddc3482420fe8aad751c2e2919361d366669 100644 (file)
  */
 #define VHOST_VSOCK_PKT_WEIGHT 256
 
-enum {
-       VHOST_VSOCK_FEATURES = VHOST_FEATURES |
-                              (1ULL << VIRTIO_F_ACCESS_PLATFORM) |
-                              (1ULL << VIRTIO_VSOCK_F_SEQPACKET)
+static const int vhost_vsock_bits[] = {
+       VHOST_FEATURES,
+       VIRTIO_F_ACCESS_PLATFORM,
+       VIRTIO_VSOCK_F_SEQPACKET
 };
 
+#define VHOST_VSOCK_FEATURES VHOST_FEATURES_U64(vhost_vsock_bits, 0)
+
 enum {
        VHOST_VSOCK_BACKEND_FEATURES = (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)
 };