Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+48 -2
+48 -2
include/linux/virtio_config.h
··· 6 6 #include <linux/bug.h> 7 7 #include <linux/virtio.h> 8 8 #include <linux/virtio_byteorder.h> 9 + #include <linux/compiler_types.h> 9 10 #include <uapi/linux/virtio_config.h> 10 11 11 12 struct irq_affinity; ··· 288 287 return __cpu_to_virtio64(virtio_is_little_endian(vdev), val); 289 288 } 290 289 290 + /* 291 + * Only the checker differentiates between __virtioXX and __uXX types. But we 292 + * try to share as much code as we can with the regular GCC build. 293 + */ 294 + #if !defined(CONFIG_CC_IS_GCC) && !defined(__CHECKER__) 295 + 296 + /* Not a checker - we can keep things simple */ 297 + #define __virtio_native_typeof(x) typeof(x) 298 + 299 + #else 300 + 301 + /* 302 + * We build this out of a couple of helper macros in a vain attempt to 303 + * help you keep your lunch down while reading it. 304 + */ 305 + #define __virtio_pick_value(x, type, then, otherwise) \ 306 + __builtin_choose_expr(__same_type(x, type), then, otherwise) 307 + 308 + #define __virtio_pick_type(x, type, then, otherwise) \ 309 + __virtio_pick_value(x, type, (then)0, otherwise) 310 + 311 + #define __virtio_pick_endian(x, x16, x32, x64, otherwise) \ 312 + __virtio_pick_type(x, x16, __u16, \ 313 + __virtio_pick_type(x, x32, __u32, \ 314 + __virtio_pick_type(x, x64, __u64, \ 315 + otherwise))) 316 + 317 + #define __virtio_native_typeof(x) typeof( \ 318 + __virtio_pick_type(x, __u8, __u8, \ 319 + __virtio_pick_endian(x, __virtio16, __virtio32, __virtio64, \ 320 + __virtio_pick_endian(x, __le16, __le32, __le64, \ 321 + __virtio_pick_endian(x, __u16, __u32, __u64, \ 322 + /* No other type allowed */ \ 323 + (void)0))))) 324 + 325 + #endif 326 + 327 + #define __virtio_native_type(structname, member) \ 328 + __virtio_native_typeof(((structname*)0)->member) 329 + 330 + #define __virtio_typecheck(structname, member, val) \ 331 + /* Must match the member's type, and be integer */ \ 332 + typecheck(__virtio_native_type(structname, member), (val)) 333 + 334 + 291 335 /* Config space accessors. */ 292 336 #define virtio_cread(vdev, structname, member, ptr) \ 293 337 do { \ 294 338 might_sleep(); \ 295 339 /* Must match the member's type, and be integer */ \ 296 - if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 340 + if (!__virtio_typecheck(structname, member, *(ptr))) \ 297 341 (*ptr) = 1; \ 298 342 \ 299 343 switch (sizeof(*ptr)) { \ ··· 368 322 do { \ 369 323 might_sleep(); \ 370 324 /* Must match the member's type, and be integer */ \ 371 - if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 325 + if (!__virtio_typecheck(structname, member, *(ptr))) \ 372 326 BUG_ON((*ptr) == 1); \ 373 327 \ 374 328 switch (sizeof(*ptr)) { \