[RFC PATCH v2 3/4] liveupdate: Replace compatibility string with a 2-bit pair feature header
Pasha Tatashin
pasha.tatashin at soleen.com
Tue Oct 27 09:21:11 PDT 2026
On 10-26 20:49, David Matlack wrote:
> I still think it's not advisable to define name##_wrap since anyone
> could accidentally start using it on the incoming path and we wouldn't
> notice at first (especially since same kernel Live Update tests would
> keep working totally fine). I also don't think asserting the combined
> size buys us anything. The header size is just a function of the
> number of features, and what we are trying to protect against is
> structs embedded in the payload changing size.
Fair point.
>
> So I would just do:
>
> /* Marks struct name as a KHO serialized payload with a kho_ser_hdr. */
> #define DECLARE_KHO_SER(name, payload_size) \
> static_assert(sizeof(struct name) == (payload_size))
>
> DECLARE_KHO_SER(luo_memfd_ser, 16);
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), \
}
> 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.
More information about the kexec
mailing list