[RFC PATCH v2 3/4] liveupdate: Replace compatibility string with a 2-bit pair feature header
David Matlack
dmatlack at google.com
Tue Oct 27 10:33:41 PDT 2026
On 2026-10-27 12:21 PM, Pasha Tatashin wrote:
> My main requirement is that DECLARE_KHO_SER() in include/linux/kho/abi/
> must be enforced by the compiler rather than being just a bare
> static_assert() that someone could forget to add. Since kho/abi/ headers
> contain both versioned structs and unversioned sub-structs, it must be
> mandatory to declare versioned structs in kho/abi/ with their
> static_assert size check before the kho_ser_*() helpers can be used on
> them.
>
> So, how about adding enum names like this, that are going to be required
> in accessor functions later:
>
> #define DECLARE_KHO_SER(name, payload_size, nr_feats) \
> static_assert(sizeof(struct name) == (payload_size), \
> "struct " #name " size mismatch"); \
> enum { \
> __KHO_SER_SIZE_##name = (payload_size), \
> __KHO_SER_NR_FEATS_##name = (nr_feats), \
> }
Sounds good. Since you're also on board with splitting required
and optional features [1], this would take both counts:
#define DECLARE_KHO_SER(name, payload_size, nr_required, nr_optional) \
static_assert(sizeof(struct name) == (payload_size), \
"struct " #name " size mismatch"); \
enum { \
__KHO_SER_SIZE_##name = (payload_size), \
__KHO_SER_NR_REQUIRED_##name = (nr_required), \
__KHO_SER_NR_OPTIONAL_##name = (nr_optional), \
}
DECLARE_KHO_SER(memfd_luo_ser, 16, MEMFD_LUO_NR_REQUIRED, MEMFD_LUO_NR_OPTIONAL);
The incoming path can also use __KHO_SER_NR_OPTIONAL_##name to validate
the incoming header only contains required features that it knows how to
handle:
#define kho_ser_validate(hdr, name) \
__kho_ser_validate(hdr, __KHO_SER_NR_REQUIRED_##name)
> > Plus helpers that allocate and initialize the header and return the
> > payload as a typed pointer. Both the outgoing and incoming paths find
> > the payload the same way, by computing its offset from the header,
> > rather than through a struct with a fixed payload offset:
> >
> > /* outgoing */
> > hdr = kho_ser_alloc(luo_memfd_ser, LUO_MEMFD_NR_FEATS);
> > ser = kho_ser_payload(hdr, luo_memfd_ser);
> >
> > /* incoming */
> > hdr = phys_to_virt(args->serialized_data);
> > ser = kho_ser_payload(hdr, luo_memfd_ser);
>
> These would become, where without enum, the init would fail:
>
> #define kho_ser_init(buf, name) \
> __kho_ser_init(buf, __KHO_SER_SIZE_##name, \
> __KHO_SER_NR_FEATS_##name)
>
> And payload can also check the existance of DECLARE_KHO_SER, using
> (expr1, expr2):
>
> #define kho_ser_payload(hdr, name) \
> ((void)__KHO_SER_SIZE_##name, \
> (struct name *)__kho_ser_payload(hdr))
>
> We can also add an optional kho_ser_alloc(name) to allocate, init, and
> preserve.
+1
More information about the kexec
mailing list