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

drm/nouveau: Avoid multiple -Wflex-array-member-not-at-end warnings

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
getting ready to enable it, globally.

So, in order to avoid ending up with flexible-array members in the
middle of other structs, we use the `struct_group_tagged()` helper
to separate the flexible arrays from the rest of the members in the
flexible structures. We then use the newly created tagged `struct
nvif_ioctl_v0_hdr` and `struct nvif_ioctl_mthd_v0_hdr` to replace the
type of the objects causing trouble in multiple structures.

We also want to ensure that when new members need to be added to the
flexible structures, they are always included within the newly created
tagged structs. For this, we use `static_assert()`. This ensures that the
memory layout for both the flexible structure and the new tagged struct
is the same after any changes.

So, with these changes, fix the following warnings:
drivers/gpu/drm/nouveau/nvif/object.c:60:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nvif/object.c:233:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nvif/object.c:214:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nvif/object.c:152:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nvif/object.c:138:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nvif/object.c:104:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nouveau_svm.c:83:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/gpu/drm/nouveau/nouveau_svm.c:82:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/Z6xjZhHxRp4Bu_SX@kspp

authored by

Gustavo A. R. Silva and committed by
Danilo Krummrich
77f183d1 cd740b87

+29 -19
+21 -11
drivers/gpu/drm/nouveau/include/nvif/ioctl.h
··· 3 3 #define __NVIF_IOCTL_H__ 4 4 5 5 struct nvif_ioctl_v0 { 6 - __u8 version; 6 + /* New members MUST be added within the struct_group() macro below. */ 7 + struct_group_tagged(nvif_ioctl_v0_hdr, __hdr, 8 + __u8 version; 7 9 #define NVIF_IOCTL_V0_SCLASS 0x01 8 10 #define NVIF_IOCTL_V0_NEW 0x02 9 11 #define NVIF_IOCTL_V0_DEL 0x03 10 12 #define NVIF_IOCTL_V0_MTHD 0x04 11 13 #define NVIF_IOCTL_V0_MAP 0x07 12 14 #define NVIF_IOCTL_V0_UNMAP 0x08 13 - __u8 type; 14 - __u8 pad02[4]; 15 + __u8 type; 16 + __u8 pad02[4]; 15 17 #define NVIF_IOCTL_V0_OWNER_NVIF 0x00 16 18 #define NVIF_IOCTL_V0_OWNER_ANY 0xff 17 - __u8 owner; 19 + __u8 owner; 18 20 #define NVIF_IOCTL_V0_ROUTE_NVIF 0x00 19 21 #define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff 20 - __u8 route; 21 - __u64 token; 22 - __u64 object; 22 + __u8 route; 23 + __u64 token; 24 + __u64 object; 25 + ); 23 26 __u8 data[]; /* ioctl data (below) */ 24 27 }; 28 + static_assert(offsetof(struct nvif_ioctl_v0, data) == sizeof(struct nvif_ioctl_v0_hdr), 29 + "struct member likely outside of struct_group()"); 25 30 26 31 struct nvif_ioctl_sclass_v0 { 27 32 /* nvif_ioctl ... */ ··· 56 51 }; 57 52 58 53 struct nvif_ioctl_mthd_v0 { 59 - /* nvif_ioctl ... */ 60 - __u8 version; 61 - __u8 method; 62 - __u8 pad02[6]; 54 + /* New members MUST be added within the struct_group() macro below. */ 55 + struct_group_tagged(nvif_ioctl_mthd_v0_hdr, __hdr, 56 + /* nvif_ioctl ... */ 57 + __u8 version; 58 + __u8 method; 59 + __u8 pad02[6]; 60 + ); 63 61 __u8 data[]; /* method data (class.h) */ 64 62 }; 63 + static_assert(offsetof(struct nvif_ioctl_mthd_v0, data) == sizeof(struct nvif_ioctl_mthd_v0_hdr), 64 + "struct member likely outside of struct_group()"); 65 65 66 66 struct nvif_ioctl_map_v0 { 67 67 /* nvif_ioctl ... */
+2 -2
drivers/gpu/drm/nouveau/nouveau_svm.c
··· 79 79 #define SVM_ERR(s,f,a...) NV_WARN((s)->drm, "svm: "f"\n", ##a) 80 80 81 81 struct nouveau_pfnmap_args { 82 - struct nvif_ioctl_v0 i; 83 - struct nvif_ioctl_mthd_v0 m; 82 + struct nvif_ioctl_v0_hdr i; 83 + struct nvif_ioctl_mthd_v0_hdr m; 84 84 struct nvif_vmm_pfnmap_v0 p; 85 85 }; 86 86
+6 -6
drivers/gpu/drm/nouveau/nvif/object.c
··· 57 57 nvif_object_sclass_get(struct nvif_object *object, struct nvif_sclass **psclass) 58 58 { 59 59 struct { 60 - struct nvif_ioctl_v0 ioctl; 60 + struct nvif_ioctl_v0_hdr ioctl; 61 61 struct nvif_ioctl_sclass_v0 sclass; 62 62 } *args = NULL; 63 63 int ret, cnt = 0, i; ··· 101 101 nvif_object_mthd(struct nvif_object *object, u32 mthd, void *data, u32 size) 102 102 { 103 103 struct { 104 - struct nvif_ioctl_v0 ioctl; 104 + struct nvif_ioctl_v0_hdr ioctl; 105 105 struct nvif_ioctl_mthd_v0 mthd; 106 106 } *args; 107 107 u32 args_size; ··· 135 135 nvif_object_unmap_handle(struct nvif_object *object) 136 136 { 137 137 struct { 138 - struct nvif_ioctl_v0 ioctl; 138 + struct nvif_ioctl_v0_hdr ioctl; 139 139 struct nvif_ioctl_unmap unmap; 140 140 } args = { 141 141 .ioctl.type = NVIF_IOCTL_V0_UNMAP, ··· 149 149 u64 *handle, u64 *length) 150 150 { 151 151 struct { 152 - struct nvif_ioctl_v0 ioctl; 152 + struct nvif_ioctl_v0_hdr ioctl; 153 153 struct nvif_ioctl_map_v0 map; 154 154 } *args; 155 155 u32 argn = sizeof(*args) + argc; ··· 211 211 nvif_object_dtor(struct nvif_object *object) 212 212 { 213 213 struct { 214 - struct nvif_ioctl_v0 ioctl; 214 + struct nvif_ioctl_v0_hdr ioctl; 215 215 struct nvif_ioctl_del del; 216 216 } args = { 217 217 .ioctl.type = NVIF_IOCTL_V0_DEL, ··· 230 230 s32 oclass, void *data, u32 size, struct nvif_object *object) 231 231 { 232 232 struct { 233 - struct nvif_ioctl_v0 ioctl; 233 + struct nvif_ioctl_v0_hdr ioctl; 234 234 struct nvif_ioctl_new_v0 new; 235 235 } *args; 236 236 int ret = 0;