lkml.org 
[lkml]   [2020]   [Aug]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v3 03/38] virtio: allow __virtioXX, __leXX in config space
    Currently all config space fields are of the type __uXX.
    This confuses people and some drivers (notably vdpa)
    access them using CPU endian-ness - which only
    works well for legacy or LE platforms.

    Update virtio_cread/virtio_cwrite macros to allow __virtioXX
    and __leXX field types. Follow-up patches will convert
    config space to use these types.

    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Acked-by: Cornelia Huck <cohuck@redhat.com>
    ---
    include/linux/virtio_config.h | 50 +++++++++++++++++++++++++++++++++--
    1 file changed, 48 insertions(+), 2 deletions(-)

    diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
    index 3b4eae5ac5e3..64da491936f7 100644
    --- a/include/linux/virtio_config.h
    +++ b/include/linux/virtio_config.h
    @@ -6,6 +6,7 @@
    #include <linux/bug.h>
    #include <linux/virtio.h>
    #include <linux/virtio_byteorder.h>
    +#include <linux/compiler_types.h>
    #include <uapi/linux/virtio_config.h>

    struct irq_affinity;
    @@ -287,12 +288,57 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
    return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
    }

    +/*
    + * Only the checker differentiates between __virtioXX and __uXX types. But we
    + * try to share as much code as we can with the regular GCC build.
    + */
    +#if !defined(CONFIG_CC_IS_GCC) && !defined(__CHECKER__)
    +
    +/* Not a checker - we can keep things simple */
    +#define __virtio_native_typeof(x) typeof(x)
    +
    +#else
    +
    +/*
    + * We build this out of a couple of helper macros in a vain attempt to
    + * help you keep your lunch down while reading it.
    + */
    +#define __virtio_pick_value(x, type, then, otherwise) \
    + __builtin_choose_expr(__same_type(x, type), then, otherwise)
    +
    +#define __virtio_pick_type(x, type, then, otherwise) \
    + __virtio_pick_value(x, type, (then)0, otherwise)
    +
    +#define __virtio_pick_endian(x, x16, x32, x64, otherwise) \
    + __virtio_pick_type(x, x16, __u16, \
    + __virtio_pick_type(x, x32, __u32, \
    + __virtio_pick_type(x, x64, __u64, \
    + otherwise)))
    +
    +#define __virtio_native_typeof(x) typeof( \
    + __virtio_pick_type(x, __u8, __u8, \
    + __virtio_pick_endian(x, __virtio16, __virtio32, __virtio64, \
    + __virtio_pick_endian(x, __le16, __le32, __le64, \
    + __virtio_pick_endian(x, __u16, __u32, __u64, \
    + /* No other type allowed */ \
    + (void)0)))))
    +
    +#endif
    +
    +#define __virtio_native_type(structname, member) \
    + __virtio_native_typeof(((structname*)0)->member)
    +
    +#define __virtio_typecheck(structname, member, val) \
    + /* Must match the member's type, and be integer */ \
    + typecheck(__virtio_native_type(structname, member), (val))
    +
    +
    /* Config space accessors. */
    #define virtio_cread(vdev, structname, member, ptr) \
    do { \
    might_sleep(); \
    /* Must match the member's type, and be integer */ \
    - if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
    + if (!__virtio_typecheck(structname, member, *(ptr))) \
    (*ptr) = 1; \
    \
    switch (sizeof(*ptr)) { \
    @@ -322,7 +368,7 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
    do { \
    might_sleep(); \
    /* Must match the member's type, and be integer */ \
    - if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
    + if (!__virtio_typecheck(structname, member, *(ptr))) \
    BUG_ON((*ptr) == 1); \
    \
    switch (sizeof(*ptr)) { \
    --
    MST
    \
     
     \ /
      Last update: 2020-08-05 19:14    [W:4.493 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site