Re: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays

From: David Woodhouse

Date: Sat Feb 28 2026 - 03:55:44 EST


On Fri, 2026-02-27 at 16:43 -0800, Kees Cook wrote:
>
>
> On February 27, 2026 12:29:11 AM PST, David Woodhouse <dwmw2@xxxxxxxxxxxxx> wrote:
> > On Thu, 2026-02-26 at 11:02 -0800, Kees Cook wrote:
> > >
> > > > 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.
> > >
> > > Right, my only worry is if C++ would want those header structs too. In
> > > that case, you'd probably want to use a macro to include them (since not
> > > all compilers are supporting transparent struct members yet):
> > >
> > > #define __kvm_msrs_hdr \
> > > __u32 nmsrs; /* number of msrs in entries */ \
> > > __u32 pad
> > >
> > > struct kvm_msrs_hdr {
> > > __kvm_msrs_hdr;
> > > };
> > >
> > > struct kvm_msrs {
> > > __kvm_msrs_hdr;
> > > __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
> > > };
> >
> > Hm, does the struct_group() not also depend on the compiler supporting
> > anonymous struct members? Is there a distinction I'm missing?
>
> Sorry, I should have been mor clear: the _tag_ that struct_group
> creates isn't supported for all C++ compilers (so is commented out
> for C++) so if a C++ project wanted to use the struct by its tag
> ("struct kvm_msrs_hdr"), you'd need the construct I wrote above.
>

Understood, yes. I was actually getting confused about why we'd use
that #define __kvm_msrs_hdr, and why we wouldn't do it like this:

struct kvm_msr_hdr {
__u32 nmsrs;
__u32 pad;
}

struct kvm_msrs {
struct kvm_msr_hdr /* anonymous */;
__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
};

(In fact, that doesn't even work with GCC). Nevertheless, my question
at the time was intended as: if we can't do it like *that*, then surely
the struct_group() construct will fail on those compilers too?

But that was a brain fart because what struct_group() does is actually
more like:

struct kvm_msrs {
union {
struct { __u32 nmsrs; __u32 pad; };
struct /* foo in C */ { __u32 nmsrs; __u32 pad; } foo;
};

__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
};

And that *does* work.

But yeah, I think C++ should be fine without the new header structs.
What I posted at least allows it to *build* with actual instantiations
of these structures with real payload again.

Attachment: smime.p7s
Description: S/MIME cryptographic signature