From: David Woodhouse Commit 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++. Not just in the sense of 'userspace needs to be updated, but UAPI is supposed to be stable", but broken in the sense that I can't actually see *how* the structures can be used from C++ in the same way that they were usable before. These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's kvm_arch_get_supported_msr_feature(): struct { struct kvm_msrs info; struct kvm_msr_entry entries[1]; } msr_data = {}; While that works in C, it fails in C++ with an error like: flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’ Fix this by using __DECLARE_FLEX_ARRAY() for the VLA, which is a helper provided by that already uses [0] for C++ compilation. Also put the header fields into a struct_group() to provide (in C) a separate struct (e.g 'struct kvm_msrs_hdr') without the trailing VLA. Fixes: 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members") Signed-off-by: David Woodhouse --- arch/x86/include/uapi/asm/kvm.h | 29 ++++++++++++++++++----------- include/uapi/linux/kvm.h | 9 ++++++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 7ceff6583652..8fc0bc2d39a6 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -194,16 +194,19 @@ struct kvm_msr_entry { /* for KVM_GET_MSRS and KVM_SET_MSRS */ struct kvm_msrs { - __u32 nmsrs; /* number of msrs in entries */ - __u32 pad; - - struct kvm_msr_entry entries[]; + __struct_group(kvm_msrs_hdr, hdr, /* no attrs */, + __u32 nmsrs; /* number of msrs in entries */ + __u32 pad; + ); + __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); }; /* for KVM_GET_MSR_INDEX_LIST */ struct kvm_msr_list { - __u32 nmsrs; /* number of msrs in entries */ - __u32 indices[]; + __struct_group(kvm_msr_list_hdr, hdr, /* no attrs */, + __u32 nmsrs; /* number of msrs in entries */ + ); + __DECLARE_FLEX_ARRAY(__u32, indices); }; /* Maximum size of any access bitmap in bytes */ @@ -265,9 +268,11 @@ struct kvm_cpuid_entry2 { /* for KVM_SET_CPUID2 */ struct kvm_cpuid2 { - __u32 nent; - __u32 padding; - struct kvm_cpuid_entry2 entries[]; + __struct_group(kvm_cpuid2_hdr, hdr, /* no attrs */, + __u32 nent; + __u32 padding; + ); + __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry2, entries); }; /* for KVM_GET_PIT and KVM_SET_PIT */ @@ -397,8 +402,10 @@ struct kvm_xsave { * The offsets of the state save areas in struct kvm_xsave follow * the contents of CPUID leaf 0xD on the host. */ - __u32 region[1024]; - __u32 extra[]; + __struct_group(kvm_xsave_hdr, hdr, /* no attrs */, + __u32 region[1024]; + ); + __DECLARE_FLEX_ARRAY(__u32, extra); }; #define KVM_MAX_XCRS 16 diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index dddb781b0507..2849d32ba035 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -1034,9 +1035,11 @@ struct kvm_irq_routing_entry { }; struct kvm_irq_routing { - __u32 nr; - __u32 flags; - struct kvm_irq_routing_entry entries[]; + __struct_group(kvm_irq_routing_hdr, hdr, /* no attrs */, + __u32 nr; + __u32 flags; + ); + __DECLARE_FLEX_ARRAY(struct kvm_irq_routing_entry, entries); }; #define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) -- 2.43.0