lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 8 Feb 2022 15:25:20 +0000 From: Cristian Marussi <cristian.marussi@....com> To: linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org, virtualization@...ts.linux-foundation.org Cc: sudeep.holla@....com, mst@...hat.com, vincent.guittot@...aro.org, souvik.chakravarty@....com, peter.hilber@...nsynergy.com, igor.skalkin@...nsynergy.com, cristian.marussi@....com Subject: [PATCH 4/4] tools/virtio: Add virtqueue_use_wrap_counter support Added simplified missing headers for VRING_POLL_* macros and a definition of virtqueue_use_wrap_counter API. Add --wrap-counters option to virtio_test to be able to test the new virtqueue_use_wrap_counter API. Signed-off-by: Cristian Marussi <cristian.marussi@....com> --- tools/virtio/linux/bitfield.h | 88 +++++++++++++++++++++++++++++++++++ tools/virtio/linux/bits.h | 36 ++++++++++++++ tools/virtio/linux/virtio.h | 33 +++++++++++++ tools/virtio/virtio_test.c | 35 ++++++++++++-- 4 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 tools/virtio/linux/bitfield.h create mode 100644 tools/virtio/linux/bits.h diff --git a/tools/virtio/linux/bitfield.h b/tools/virtio/linux/bitfield.h new file mode 100644 index 000000000000..43421844eecc --- /dev/null +++ b/tools/virtio/linux/bitfield.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _LINUX_BITFIELD_H +#define _LINUX_BITFIELD_H + +#include <asm/byteorder.h> + +/* + * Bitfield access macros + * + * FIELD_{GET,PREP} macros take as first parameter shifted mask + * from which they extract the base mask and shift amount. + * Mask must be a compilation time constant. + * + * Example: + * + * #define REG_FIELD_A GENMASK(6, 0) + * #define REG_FIELD_B BIT(7) + * #define REG_FIELD_C GENMASK(15, 8) + * #define REG_FIELD_D GENMASK(31, 16) + * + * Get: + * a = FIELD_GET(REG_FIELD_A, reg); + * b = FIELD_GET(REG_FIELD_B, reg); + * + * Set: + * reg = FIELD_PREP(REG_FIELD_A, 1) | + * FIELD_PREP(REG_FIELD_B, 0) | + * FIELD_PREP(REG_FIELD_C, c) | + * FIELD_PREP(REG_FIELD_D, 0x40); + * + * Modify: + * reg &= ~REG_FIELD_C; + * reg |= FIELD_PREP(REG_FIELD_C, c); + */ + +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +/** + * FIELD_MAX() - produce the maximum value representable by a field + * @_mask: shifted mask defining the field's length and position + * + * FIELD_MAX() returns the maximum value that can be held in the field + * specified by @_mask. + */ +#define FIELD_MAX(_mask) \ + ({ \ + (typeof(_mask))((_mask) >> __bf_shf(_mask)); \ + }) + +/** + * FIELD_FIT() - check if value fits in the field + * @_mask: shifted mask defining the field's length and position + * @_val: value to test against the field + * + * Return: true if @_val can fit inside @_mask, false if @_val is too big. + */ +#define FIELD_FIT(_mask, _val) \ + ({ \ + !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ + }) + +/** + * FIELD_PREP() - prepare a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + */ +#define FIELD_PREP(_mask, _val) \ + ({ \ + ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ + }) + +/** + * FIELD_GET() - extract a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_reg: value of entire bitfield + * + * FIELD_GET() extracts the field specified by @_mask from the + * bitfield passed in as @_reg by masking and shifting it down. + */ +#define FIELD_GET(_mask, _reg) \ + ({ \ + (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ + }) + +#endif diff --git a/tools/virtio/linux/bits.h b/tools/virtio/linux/bits.h new file mode 100644 index 000000000000..16f8fe32b0b3 --- /dev/null +++ b/tools/virtio/linux/bits.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_BITS_H +#define __LINUX_BITS_H + +#include <linux/const.h> +#include <vdso/bits.h> +#include <asm/bitsperlong.h> + +#define BIT_ULL(nr) (ULL(1) << (nr)) +#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) +#define BITS_PER_BYTE 8 + +/* + * Create a contiguous bitmask starting at bit position @l and ending at + * position @h. For example + * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. + */ + +#define GENMASK_INPUT_CHECK(h, l) 0 + +#define __GENMASK(h, l) \ + (((~UL(0)) - (UL(1) << (l)) + 1) & \ + (~UL(0) >> (BITS_PER_LONG - 1 - (h)))) +#define GENMASK(h, l) \ + (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l)) + +#define __GENMASK_ULL(h, l) \ + (((~ULL(0)) - (ULL(1) << (l)) + 1) & \ + (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))) +#define GENMASK_ULL(h, l) \ + (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l)) + +#endif /* __LINUX_BITS_H */ diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index 9021187a66d9..0556e093f223 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -5,6 +5,8 @@ #include <linux/kernel.h> #include <linux/spinlock.h> +#define VIRTIO_CONFIG_S_DRIVER 2 + typedef struct pm_message { int event; } pm_message_t; @@ -48,9 +50,12 @@ struct device { struct device_driver *driver; }; +struct virtio_config_ops; + struct virtio_device { struct device dev; u64 features; + const struct virtio_config_ops *config; struct list_head vqs; spinlock_t vqs_list_lock; }; @@ -65,6 +70,32 @@ struct virtqueue { void *priv; }; +struct virtio_config_ops { + void (*enable_cbs)(struct virtio_device *vdev); + void (*get)(struct virtio_device *vdev, unsigned int offset, + void *buf, unsigned int len); + void (*set)(struct virtio_device *vdev, unsigned int offset, + const void *buf, unsigned int len); + u32 (*generation)(struct virtio_device *vdev); + u8 (*get_status)(struct virtio_device *vdev); + void (*set_status)(struct virtio_device *vdev, u8 status); + void (*reset)(struct virtio_device *vdev); + int (*find_vqs)(struct virtio_device *vdev, unsigned int nvqs, + struct virtqueue *vqs[], void *callbacks[], + const char * const names[], const bool *ctx, + void *desc); + void (*del_vqs)(struct virtio_device *vdev); + u64 (*get_features)(struct virtio_device *vdev); + int (*finalize_features)(struct virtio_device *vdev); + const char *(*bus_name)(struct virtio_device *vdev); + int (*set_vq_affinity)(struct virtqueue *vq, + const void *cpu_mask); + const void *(*get_vq_affinity)(struct virtio_device *vdev, + int index); + bool (*get_shm_region)(struct virtio_device *vdev, + void *region, u8 id); +}; + struct virtio_driver { struct device_driver driver; const struct virtio_device_id *id_table; @@ -111,6 +142,8 @@ void virtqueue_disable_cb(struct virtqueue *vq); bool virtqueue_enable_cb(struct virtqueue *vq); bool virtqueue_enable_cb_delayed(struct virtqueue *vq); +int virtqueue_use_wrap_counter(struct virtqueue *vq); + void *virtqueue_detach_unused_buf(struct virtqueue *vq); struct virtqueue *vring_new_virtqueue(unsigned int index, unsigned int num, diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index d9cb3d22d52f..deccd44e4739 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -21,6 +21,8 @@ #define RANDOM_BATCH -1 +static u8 virtio_test_device_status; + /* Unused */ void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; @@ -109,7 +111,7 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) info->vq->priv = info; } -static void vq_info_add(struct vdev_info *dev, int num) +static void vq_info_add(struct vdev_info *dev, int num, bool use_wrap_counters) { struct vq_info *info = &dev->vqs[dev->nvqs]; int r; @@ -119,12 +121,25 @@ static void vq_info_add(struct vdev_info *dev, int num) r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); assert(r >= 0); vq_reset(info, num, &dev->vdev); + if (use_wrap_counters) { + r = virtqueue_use_wrap_counter(info->vq); + assert(r == 0); + } vhost_vq_setup(dev, info); dev->fds[info->idx].fd = info->call; dev->fds[info->idx].events = POLLIN; dev->nvqs++; } +static u8 virtio_test_get_status(struct virtio_device *vdev) +{ + return virtio_test_device_status; +} + +struct virtio_config_ops virtio_config_ops = { + .get_status = virtio_test_get_status, +}; + static void vdev_info_init(struct vdev_info* dev, unsigned long long features) { int r; @@ -132,6 +147,8 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) dev->vdriver.suppress_used_validation = false; dev->vdev.dev.driver = &dev->vdriver.driver; dev->vdev.features = features; + virtio_test_device_status = VIRTIO_CONFIG_S_DRIVER; + dev->vdev.config = &virtio_config_ops; INIT_LIST_HEAD(&dev->vdev.vqs); spin_lock_init(&dev->vdev.vqs_list_lock); dev->buf_size = 1024; @@ -316,6 +333,14 @@ const struct option longopts[] = { .name = "no-delayed-interrupt", .val = 'd', }, + { + .name = "wrap-counters", + .val = 'W', + }, + { + .name = "no-wrap-counters", + .val = 'w', + }, { .name = "batch", .val = 'b', @@ -337,6 +362,7 @@ static void help(void) " [--no-event-idx]" " [--no-virtio-1]" " [--delayed-interrupt]" + " [--wrap-counters]" " [--batch=random/N]" " [--reset=N]" "\n"); @@ -349,7 +375,7 @@ int main(int argc, char **argv) (1ULL << VIRTIO_RING_F_EVENT_IDX) | (1ULL << VIRTIO_F_VERSION_1); long batch = 1, reset = 0; int o; - bool delayed = false; + bool delayed = false, use_wrap_counters = false; for (;;) { o = getopt_long(argc, argv, optstring, longopts, NULL); @@ -374,6 +400,9 @@ int main(int argc, char **argv) case 'D': delayed = true; break; + case 'W': + use_wrap_counters = true; + break; case 'b': if (0 == strcmp(optarg, "random")) { batch = RANDOM_BATCH; @@ -400,7 +429,7 @@ int main(int argc, char **argv) done: vdev_info_init(&dev, features); - vq_info_add(&dev, 256); + vq_info_add(&dev, 256, use_wrap_counters); run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); return 0; } -- 2.17.1
Powered by blists - more mailing lists