> From 4dcc25d0d7d1a055f19cb561883b8e6efc55c9b8 Mon Sep 17 00:00:00 2001 > From: Jiri Pirko > Date: Thu, 15 Oct 2026 16:50:47 +0200 > Subject: [PATCH 14/20] attestation: Add the base family specification and > generated files > > Define the base attestation family. Reserve its family ID and add the ABI > snapshot, registry entry and generated kernel and UAPI files. > > The ABI is intentionally specification-first. The generated descriptor is Commit message: 'specification-first' hides that this patch adds 1200 lines of generated code (`drivers/attestation/generated/*.c`, *.h) that nothing compiles: there is no `drivers/attestation/Makefile/Kconfig` hook here, and the .c references `ctlv_attestation_op_pre`/post, `ctlv_attestation_priv_size`, init, `mr_get_action`, ... that are not defined until later patches. Not building it is what keeps the series bisectable, but then the generated kernel header/source cannot have been compile-tested at this point. Please state this explicitly. I regenerated the tree at this commit (`tools/ctlv/ctlv-regen.sh` -c, validate, abi-check): all pass, so the generated files do match the spec. > linked after the provider, journal and operation handlers arrive. > > Assisted-by: Cursor: GPT-5.6 Sol > Assisted-by: Cursor: Claude Opus 5.5 > Signed-off-by: Jiri Pirko > --- > Documentation/ctlv/abi/ctlv-attestation.yaml | 184 ++++++++++ > Documentation/ctlv/abi/families.registry.yaml | 1 + > Documentation/ctlv/families.yaml | 1 + > Documentation/ctlv/generated-files.yaml | 7 + > .../ctlv/specs/ctlv-attestation.yaml | 347 ++++++++++++++++++ > MAINTAINERS | 9 + > .../generated/ctlv_attestation_gen.c | 234 ++++++++++++ > .../generated/ctlv_attestation_gen.h | 198 ++++++++++ > include/uapi/linux/ctlv_attestation_gen.h | 252 +++++++++++++ > include/uapi/linux/ctlv_families_gen.h | 1 + > 10 files changed, 1234 insertions(+) > create mode 100644 Documentation/ctlv/abi/ctlv-attestation.yaml > create mode 100644 Documentation/ctlv/specs/ctlv-attestation.yaml > create mode 100644 drivers/attestation/generated/ctlv_attestation_gen.c > create mode 100644 drivers/attestation/generated/ctlv_attestation_gen.h > create mode 100644 include/uapi/linux/ctlv_attestation_gen.h > > diff --git a/Documentation/ctlv/abi/ctlv-attestation.yaml b/Documentation/ctlv/abi/ctlv-attestation.yaml > new file mode 100644 > index 000000000000..a857e5ce0039 > --- /dev/null > +++ b/Documentation/ctlv/abi/ctlv-attestation.yaml > @@ -0,0 +1,184 @@ > +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) > +%YAML 1.2 > +--- > +# Checked-in ABI snapshot of the ctlv-attestation family, written by > +# "make -C tools/ctlv abi-update". > +# > +# The checker compares this family's declarations and inherited stub fills > +# against this file. Updating it is how a UAPI change gets reviewed; an update > +# that removes or renumbers anything, narrows a bound, or makes a placement > +# required is an ABI break, whatever this file says afterwards. > +family: {name: ctlv-attestation, id: 1, inherits: ctlv, post-init: true, > + pre-fini: true} > +enums: > + evidence-representation: {raw: 1} > + evidence-blob-class: {primary: 1} > + mr-log-event: {info: 1, extend: 2} > +flags: > + mr-device-caps: {read: 0, extend: 1} > + mr-caps: {read: 0, extend: 1} > +attr-groups: > + device: > + id: 1 > + attrs: > + generation: {id: 1, type: uint, max: 4294967295} > + caps: {id: 2, type: nested} > + info: {id: 3, type: nested} > + cap: > + id: 2 > + attrs: > + evidence: {id: 1, type: nested} > + mr: {id: 2, type: nested} > + min-challenge-length: {id: 3, type: uint} > + max-challenge-length: {id: 4, type: uint} > + max-total-output-length: {id: 5, type: uint} > + mr-flags: {id: 6, flags: mr-device-caps} > + object: {id: 7, type: nested, max-occurrences: 16} > + blob-class: {id: 8, enum: evidence-blob-class} > + format: {id: 9, type: string, min-length: 1, max-length: 128} > + representation: {id: 10, enum: evidence-representation} > + max-length: {id: 11, type: uint} > + evidence: > + id: 3 > + attrs: > + challenge: {id: 1, type: binary, max-length: 4096} > + object: {id: 2, type: nested, max-occurrences: 16} > + blob-class: {id: 3, enum: evidence-blob-class} > + format: {id: 4, type: string, min-length: 1, max-length: 128} > + representation: {id: 5, enum: evidence-representation} > + data: {id: 6, blob: output, backings: [va], max-length: 4294967295} > + object-length: {id: 7, type: uint, max-occurrences: 16} > + mr: > + id: 4 > + attrs: > + id: {id: 1, type: uint, max: 4294967295} > + name: {id: 2, type: string, min-length: 1, max-length: 128} > + hash-algo: {id: 3, type: uint, max: 20} > + supported-hash-algo: {id: 4, type: uint, max: 20, max-occurrences: 21} > + register-index: {id: 5, type: uint, max: 4294967295} > + caps: {id: 6, flags: mr-caps} > + item: {id: 7, type: nested, max-occurrences: unlimited} > + value: {id: 8, type: nested, max-occurrences: 21} > + data: {id: 9, type: binary, min-length: 16, max-length: 64} > + generation: {id: 10, type: uint, max: 4294967295} > + selection: {id: 11, type: nested, max-occurrences: 256} > + start-generation: {id: 12, type: uint, max: 4294967295} > + end-generation: {id: 13, type: uint, max: 4294967295} > + log: > + id: 5 > + attrs: > + entry: {id: 1, type: nested, max-occurrences: unlimited} > + event: {id: 2, enum: mr-log-event} > + mr: {id: 3, type: nested} > + notification: > + id: 6 > + attrs: > + entry: {id: 1, type: nested} > +attr-sets: > + device-info: {id: 1, stub: true} > + evidence-object-cap: {id: 2} > + evidence-cap: {id: 3} > + mr-device-cap: {id: 4} > + device-caps: {id: 5} > + device-reply: {id: 6} > + evidence-object-request: {id: 7} > + evidence-request: {id: 8} > + evidence-reply: {id: 9} > + mr-props: {id: 10} > + mr-dump-entry: {id: 11} > + mr-id-request: {id: 12} > + mr-read-request: {id: 13} > + mr-value: {id: 14} > + mr-read-reply: {id: 15} > + mr-extend-request: {id: 16} > + mr-change-reply: {id: 17} > + mr-log-info: {id: 18} > + mr-log-entry: {id: 19} > + mr-log-event: {id: 20} > + mr-log-selection: {id: 21} > + mr-log-request: {id: 22} > + mr-log-reply: {id: 23} > +ops: > + device-get: > + abi: {id: 1, type: action, fd-access: read} > + reply: > + attrs: > + - device.caps: > + optional-attrs: > + - cap.evidence: > + attrs: > + - cap.min-challenge-length > + - cap.max-challenge-length > + - cap.max-total-output-length > + - cap.object: > + attrs: [cap.blob-class, cap.format, cap.representation, > + cap.max-length] > + - cap.mr: {attrs: [cap.mr-flags]} > + - device.info: {attrs: [device-info]} > + evidence-get: > + abi: {id: 2, type: action, availability: dynamic, optional: true} > + request: > + attrs: > + - evidence.challenge > + - evidence.object: > + attrs: [evidence.blob-class, evidence.format, > + evidence.representation, evidence.data] > + reply: > + attrs: [evidence.object-length] > + optional-attrs: [mr.generation] > + mr-get: > + abi: {id: 3, type: action, fd-access: read, optional: true} > + request: {attrs: [mr.id]} > + reply: > + attrs: [mr.name, mr.supported-hash-algo, mr.caps] > + optional-attrs: [mr.register-index] > + mr-dump: > + abi: {id: 4, type: query, fd-access: read, optional: true} > + reply: > + attrs: > + - mr.item: > + attrs: [mr.id, mr.name, mr.supported-hash-algo, mr.caps] > + optional-attrs: [mr.register-index] > + mr-read: > + abi: {id: 5, type: query, fd-access: read, optional: true} > + request: {attrs: [mr.id]} > + reply: > + attrs: > + - mr.generation > + - mr.value: {attrs: [mr.hash-algo, mr.data]} > + mr-extend: > + abi: {id: 6, type: action, optional: true} > + request: > + attrs: > + - mr.id > + - mr.value: {attrs: [mr.hash-algo, mr.data]} > + reply: {attrs: [mr.generation]} > + mr-log-entry-appended: > + abi: {id: 7, type: event} > + reply: > + attrs: > + - notification.entry: > + attrs: [mr.generation, mr.id, log.event] > + optional-attrs: > + - mr.value: {attrs: [mr.hash-algo, mr.data]} > + - log.mr: > + attrs: [mr.name, mr.supported-hash-algo, mr.caps] > + optional-attrs: [mr.register-index] > + mr-log-get: > + abi: {id: 8, type: query, fd-access: read, optional: true} > + request: > + optional-attrs: > + - mr.selection: {attrs: [mr.id]} > + - mr.start-generation > + - mr.end-generation > + reply: > + optional-attrs: > + - mr.start-generation > + - mr.end-generation > + - log.entry: > + attrs: [mr.generation, mr.id, log.event] > + optional-attrs: > + - mr.value: {attrs: [mr.hash-algo, mr.data]} > + - log.mr: > + attrs: [mr.name, mr.supported-hash-algo, mr.caps] > + optional-attrs: [mr.register-index] > diff --git a/Documentation/ctlv/abi/families.registry.yaml b/Documentation/ctlv/abi/families.registry.yaml > index 2c9b9e7eee15..fa511b709fc1 100644 > --- a/Documentation/ctlv/abi/families.registry.yaml > +++ b/Documentation/ctlv/abi/families.registry.yaml > @@ -5,3 +5,4 @@ > # Updated deliberately by "make -C tools/ctlv abi-update". > families: > - ctlv > + - ctlv-attestation > diff --git a/Documentation/ctlv/families.yaml b/Documentation/ctlv/families.yaml > index bf1dabdba5c9..d78025a9072c 100644 > --- a/Documentation/ctlv/families.yaml > +++ b/Documentation/ctlv/families.yaml > @@ -11,3 +11,4 @@ > > families: > - ctlv > + - ctlv-attestation > diff --git a/Documentation/ctlv/generated-files.yaml b/Documentation/ctlv/generated-files.yaml > index 6773e0be0883..669f1f8d51b4 100644 > --- a/Documentation/ctlv/generated-files.yaml > +++ b/Documentation/ctlv/generated-files.yaml > @@ -15,3 +15,10 @@ families: > uapi-header: include/uapi/linux/ctlv_gen.h > kernel-header: include/linux/ctlv_gen.h > kernel-source: drivers/ctlv/ctlv_gen.c > + > + - name: ctlv-attestation > + source: Documentation/ctlv/specs/ctlv-attestation.yaml > + outputs: > + uapi-header: include/uapi/linux/ctlv_attestation_gen.h > + kernel-header: drivers/attestation/generated/ctlv_attestation_gen.h > + kernel-source: drivers/attestation/generated/ctlv_attestation_gen.c > diff --git a/Documentation/ctlv/specs/ctlv-attestation.yaml b/Documentation/ctlv/specs/ctlv-attestation.yaml > new file mode 100644 > index 000000000000..c0d7fc8db18e > --- /dev/null > +++ b/Documentation/ctlv/specs/ctlv-attestation.yaml > @@ -0,0 +1,347 @@ > +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) > +%YAML 1.2 > +--- > +family: > + name: ctlv-attestation > + inherits: ctlv > + post-init: true > + pre-fini: true > + > +enums: > + - name: evidence-representation > + values: > + - raw > + > + - name: evidence-blob-class > + values: > + - primary > + > + - name: mr-log-event Name collision/confusion: 'mr-log-event' is simultaneously an enum (values info/extend, used by log.event), an attr-set (`CTLV_ATTESTATION_SET_MR_LOG_EVENT`) and effectively the reply set of the event op 'mr-log-entry-appended'. The event op is named mr-log-entry-appended but its set is mr-log-event and it wraps 'notification.entry' whose set is mr-log-entry. Pick one naming scheme; the enum and set sharing a name will bite as soon as a name-keyed table is generated. > + values: > + - info > + - extend > + > +flags: > + - name: mr-device-caps > + values: > + - read > + - extend > + > + - name: mr-caps > + values: > + - read > + - extend > + > +attr-groups: > + - name: device > + attrs: > + # Reserved until provider-driven state changes are introduced. Do not add (and freeze in the ABI snapshot) an attribute that nothing in this series uses. The device.generation attribute (ID 1, max 4294967295) appears in no attr-set and no op: device-reply carries only device.caps and device.info. It is dead UAPI, yet it burns attr ID 1 of group 'device', adds the exported `CTLV_ATTESTATION_ATTR_DEVICE_GENERATION` macro and an unused `ctlv_attestation_device_generation_put()` inline in the kernel header. Remove it; an attribute can be added compatibly when the feature arrives. The ABI snapshot treats removal as a break, so adding it now makes it permanent. > + - name: generation > + type: uint > + max: 4294967295 > + - name: caps > + attrs: device-caps > + - name: info > + attrs: device-info > + > + - name: cap > + attrs: > + - name: evidence > + attrs: evidence-cap > + - name: mr > + attrs: mr-device-cap > + - name: min-challenge-length The three capability lengths (min-challenge-length, max-challenge-length, max-total-output-length) and cap.max-length / evidence.object-length are 'type: uint' without a max, i.e. generated with `U64_MAX` bounds, whereas their consumers are bounded: evidence.challenge has max-length 4096, evidence.data has max-length 4294967295 (`U32_MAX`). A provider could therefore advertise a max-challenge-length of 2^63 that the request schema can never accept. Bound them to the same limits in the spec (and the ABI would then need no later narrowing, which is by its own rule a break). > + type: uint > + - name: max-challenge-length > + type: uint > + - name: max-total-output-length > + type: uint > + - name: mr-flags > + flags: mr-device-caps > + - name: object > + attrs: evidence-object-cap > + max-occurrences: 16 > + - name: blob-class > + enum: evidence-blob-class > + - name: format > + type: string > + min-length: 1 > + max-length: 128 > + - name: representation > + enum: evidence-representation > + - name: max-length > + type: uint > + > + - name: evidence > + attrs: > + - name: challenge challenge has max-length 4096 but no min-length; yet cap.min-challenge-length exists. Schema-level a zero-length challenge is valid; the semantics (empty challenge == no nonce?) are nowhere specified. Also, the 'evidence' request attribute is required (attrs:) so a provider that does not take a challenge still needs the caller to send one. Document or make the attribute optional. > + type: binary > + max-length: 4096 > + - name: object > + attrs: evidence-object-request > + max-occurrences: 16 > + - name: blob-class > + enum: evidence-blob-class > + - name: format > + type: string > + min-length: 1 > + max-length: 128 > + - name: representation > + enum: evidence-representation > + - name: data > + blob: > + direction: output > + allowed-backings: [ va ] > + max-length: 4294967295 > + alignment: 1 max-length `U32_MAX` for an output blob: nothing in the spec relates it to cap.max-length / max-total-output-length, and 4 GiB-1 per object is not a realistic attestation object size. If intentional say why; otherwise bound it. The ABI snapshot also records no alignment for this blob, so alignment is not under ABI check. > + - name: object-length object-length is a repeated uint (max-occurrences 16) reported in the reply, positional with request.object. Nothing in the schema ties the number of reply entries to the number of request objects; that invariant must be enforced by the handler. Document it in the spec. > + type: uint > + max-occurrences: 16 > + > + - name: mr > + attrs: > + - name: id > + type: uint > + max: 4294967295 > + - name: name > + type: string > + min-length: 1 > + max-length: 128 > + - name: hash-algo Magic numbers: 'max: 20' (and max-occurrences: 21 on supported-hash-algo) hard-codes the value range of `enum hash_algo` from `include/uapi/linux/hash_info.h` with no comment. In this tree that enum runs to `HASH_ALGO_SHA3_512` = 22 (`HASH_ALGO__LAST` = 23), so 20 silently excludes SHA3-256/384/512 and the choice is undocumented; 20 is also `HASH_ALGO_STREEBOG_512`, not a 'last' marker. If hash-algo is meant to be the `hash_info.h` numbering, say so and justify the cut-off; if not, define a CTLV enum. As is, it is an ABI constant nobody can review. Also the bounds do not relate hash-algo to the digest length: data is 16..64 bytes for any algo, so the handler must check length == digest size for hash-algo. > + type: uint > + max: 20 > + - name: supported-hash-algo > + type: uint > + max: 20 > + max-occurrences: 21 21 = number of values 0..20 for supported-hash-algo; as a set of distinct algorithms the schema cannot say 'unique', so duplicates are valid input (for mr.value in the extend request this matters: two values with the same hash-algo for one MR). Handler must reject. > + - name: register-index > + type: uint > + max: 4294967295 > + - name: caps > + flags: mr-caps > + - name: item > + attrs: mr-dump-entry > + max-occurrences: unlimited > + - name: value > + attrs: mr-value > + max-occurrences: 21 > + - name: data > + type: binary > + min-length: 16 > + max-length: 64 > + - name: generation > + type: uint > + max: 4294967295 > + - name: selection > + attrs: mr-log-selection > + max-occurrences: 256 > + - name: start-generation > + type: uint > + max: 4294967295 > + - name: end-generation > + type: uint > + max: 4294967295 > + > + - name: log > + attrs: > + - name: entry > + attrs: mr-log-entry > + max-occurrences: unlimited > + - name: event > + enum: mr-log-event > + - name: mr > + attrs: mr-log-info > + > + - name: notification > + attrs: > + - name: entry > + attrs: mr-log-entry > + > +attr-sets: > + - name: device-info > + stub: true > + > + - name: evidence-object-cap > + attrs: > + - cap.blob-class > + - cap.format > + - cap.representation > + - cap.max-length > + > + - name: evidence-cap > + attrs: > + - cap.min-challenge-length > + - cap.max-challenge-length > + - cap.max-total-output-length > + - cap.object > + > + - name: mr-device-cap > + attrs: cap.mr-flags > + > + - name: device-caps > + optional-attrs: > + - cap.evidence > + - cap.mr > + > + - name: device-reply > + attrs: > + - device.caps > + - device.info > + > + - name: evidence-object-request > + attrs: > + - evidence.blob-class > + - evidence.format > + - evidence.representation > + - evidence.data > + > + - name: evidence-request > + attrs: > + - evidence.challenge > + - evidence.object > + > + - name: evidence-reply > + attrs: evidence.object-length > + optional-attrs: > + - mr.generation evidence-reply carries an optional mr.generation: an 'mr' group attribute inside the reply of an 'evidence' operation. The semantics (generation of the MR set at the time the evidence was produced) are nowhere documented in the spec, and the MR generation counter is not otherwise tied to evidence-get. Needs a description; ABI attributes with no documentation are hard to review. > + > + - name: mr-props Redundant sets. mr-props, mr-dump-entry and mr-log-info are three copies of the same member list (name, supported-hash-algo, caps, optional register-index; mr-dump-entry adds id), mr-id-request and mr-read-request are identical (just mr.id) and mr-log-selection is a third copy of {mr.id}. Each set takes an ID and is part of the ABI registry (sets 1..23 are frozen in the snapshot), and each costs a node-schema array in the generated code. Define one set and reuse it (op-specific naming buys nothing, stubs are the only place where a set ID is externally visible). > + attrs: > + - mr.name > + - mr.supported-hash-algo > + - mr.caps > + optional-attrs: mr.register-index > + > + - name: mr-dump-entry > + attrs: > + - mr.id > + - mr.name > + - mr.supported-hash-algo > + - mr.caps > + optional-attrs: mr.register-index > + > + - name: mr-id-request > + attrs: mr.id > + > + - name: mr-read-request > + attrs: mr.id > + > + - name: mr-value > + attrs: > + - mr.hash-algo > + - mr.data > + > + - name: mr-read-reply > + attrs: > + - mr.generation > + - mr.value > + > + - name: mr-extend-request > + attrs: > + - mr.id > + - mr.value > + > + - name: mr-change-reply > + attrs: mr.generation > + > + - name: mr-log-info > + attrs: > + - mr.name > + - mr.supported-hash-algo > + - mr.caps > + optional-attrs: mr.register-index > + > + - name: mr-log-entry > + attrs: > + - mr.generation > + - mr.id > + - log.event > + optional-attrs: > + - mr.value > + - log.mr > + > + - name: mr-log-event > + attrs: notification.entry > + > + - name: mr-log-selection > + attrs: mr.id > + > + - name: mr-log-request > + optional-attrs: > + - mr.selection > + - mr.start-generation > + - mr.end-generation > + > + - name: mr-log-reply > + optional-attrs: > + - mr.start-generation > + - mr.end-generation > + - log.entry > + > +ops: > + - name: device-get > + type: action > + fd-access: read > + reply: > + attrs: device-reply > + > + - name: evidence-get evidence-get is declared 'fd-access: read-write' although it neither modifies device state nor needs write permission in the sense of mr-extend; every other read-type action is 'read'. The ABI snapshot omits fd-access for evidence-get (default read-write), so this is frozen. If requiring a writable fd is intentional (freshness/nonce consumption?), document it; otherwise it forces read-only openers to be denied attestation. > + type: action > + fd-access: read-write > + availability: dynamic > + optional: true > + request: > + attrs: evidence-request > + reply: > + attrs: evidence-reply > + > + - name: mr-get > + type: action > + fd-access: read > + optional: true > + request: > + attrs: mr-id-request > + reply: > + attrs: mr-props > + > + - name: mr-dump > + type: query > + fd-access: read > + optional: true > + reply: > + attrs: mr.item > + suggested-reply-length: 4096 > + > + - name: mr-read > + type: query > + fd-access: read > + optional: true > + request: > + attrs: mr-read-request > + reply: > + attrs: mr-read-reply > + suggested-reply-length: 4096 > + > + - name: mr-extend > + type: action > + fd-access: read-write > + optional: true > + request: > + attrs: mr-extend-request > + reply: > + attrs: mr-change-reply > + > + - name: mr-log-entry-appended > + type: event > + reply: > + attrs: mr-log-event > + > + - name: mr-log-get > + type: query > + fd-access: read > + optional: true > + request: > + attrs: mr-log-request > + reply: > + attrs: mr-log-reply > + suggested-reply-length: 131072 131072 for mr-log-get is a magic number with no rationale, and the generated `static_assert` only compares against `CTLV_MAX_INLINE_MESSAGE_LEN`. Add a comment. > diff --git a/MAINTAINERS b/MAINTAINERS > index 0b565a07f55e..96fdd3e45a29 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS MAINTAINERS: the M: address (jiri@nvidia.com) differs from the CTLV entry added in patch 13 (jiri@resnulli.us); use one. 'L: linux-security-module' for a driver family whose core lives in `drivers/ctlv/` and that is driven through CTLV looks arbitrary; consider listing the CTLV list too. > @@ -4331,6 +4331,15 @@ F: rust/kernel/sync/atomic.rs > F: rust/kernel/sync/atomic/ > F: rust/kernel/sync/refcount.rs > > +ATTESTATION SUBSYSTEM > +M: Jiri Pirko > +L: linux-security-module@vger.kernel.org > +S: Supported > +F: Documentation/ctlv/abi/ctlv-attestation* > +F: Documentation/ctlv/specs/ctlv-attestation* > +F: drivers/attestation/ > +F: include/uapi/linux/ctlv_attestation* > + > ATTO EXPRESSSAS SAS/SATA RAID SCSI DRIVER > M: Bradley Grove > L: linux-scsi@vger.kernel.org > diff --git a/drivers/attestation/generated/ctlv_attestation_gen.c b/drivers/attestation/generated/ctlv_attestation_gen.c > new file mode 100644 > index 000000000000..c9fbeae00e38 > --- /dev/null > +++ b/drivers/attestation/generated/ctlv_attestation_gen.c > @@ -0,0 +1,234 @@ > +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) > +/* Do not edit, regenerate with tools/ctlv/ctlv-regen.sh, from: */ > +/* Documentation/ctlv/specs/ctlv-attestation.yaml */ > +/* CTLV-GEN kernel source */ > + > +#define _CTLV_GENERATED_METADATA_ONLY Generated .c: includes `` and `` explicitly, although `ctlv_attestation_gen.h` already pulls both in via `` (and `ctlv_gen.h` via the UAPI header). Redundant includes are generator noise; and is used instead of , which is non-idiomatic for kernel code (`drivers/ctlv/ctlv_gen.c` does the same, so this is a generator-wide nit). Also this unconditional define of `_CTLV_GENERATED_METADATA_ONLY` hides all accessors from the .h, so none of the `CTLV_IN_*`/`CTLV_PUT_*` inlines in the header are compile-tested by the generated .c. > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include "ctlv_attestation_gen.h" > + > +static const struct ctlv_node_schema device_get_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(0, 0, 0), > +}; > + > +static const struct ctlv_node_schema device_get_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 2, 2), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_DEVICE_CAPS, 1, 3, 2, 0), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_DEVICE_INFO, 1, 0, 0, 0), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_CAP_EVIDENCE, 1, 5, 4, 4), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_CAP_MR, 1, 9, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_CAP_MIN_CHALLENGE_LENGTH, 1, 0, U64_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_CAP_MAX_CHALLENGE_LENGTH, 1, 0, U64_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_CAP_MAX_TOTAL_OUTPUT_LENGTH, 1, 0, U64_MAX), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_CAP_OBJECT, 16, 10, 4, 4), > + CTLV_NODE_SCHEMA_FLAGS(CTLV_ATTESTATION_ATTR_CAP_MR_FLAGS, 1, > + CTLV_ATTESTATION_MR_DEVICE_CAPS_MASK), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_CAP_BLOB_CLASS, 1, 1), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_CAP_FORMAT, 1, 1, 128), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_CAP_REPRESENTATION, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_CAP_MAX_LENGTH, 1, 0, U64_MAX), > +}; > + > +/* Extension points selected by this tree. */ > +static const struct ctlv_stub_schema device_get_reply_stub_schemas[] = { > + CTLV_STUB_SCHEMA(CTLV_FAMILY_ATTESTATION, CTLV_ATTESTATION_SET_DEVICE_INFO, 2), > +}; > + > +static const struct ctlv_node_schema evidence_get_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 2, 2), > + CTLV_NODE_SCHEMA_BINARY(CTLV_ATTESTATION_ATTR_EVIDENCE_CHALLENGE, 1, 0, 4096), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT, 16, 3, 4, 4), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_EVIDENCE_BLOB_CLASS, 1, 1), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_EVIDENCE_FORMAT, 1, 1, 128), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_EVIDENCE_REPRESENTATION, 1, 1), > + CTLV_NODE_SCHEMA_BLOB(CTLV_ATTESTATION_ATTR_EVIDENCE_DATA, 1, U32_MAX, 1, > + BIT(CTLV_BLOB_TYPE_VA), > + CTLV_BLOB_DIRECTION_OUTPUT), > +}; > + > +static const struct ctlv_node_schema evidence_get_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 2, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT_LENGTH, 16, 0, U64_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_GENERATION, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_get_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_get_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 4, 3), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_MR_NAME, 1, 1, 128), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, 21, 0, 20), > + CTLV_NODE_SCHEMA_FLAGS(CTLV_ATTESTATION_ATTR_MR_CAPS, 1, CTLV_ATTESTATION_MR_CAPS_MASK), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_dump_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(0, 0, 0), > +}; > + > +static const struct ctlv_node_schema mr_dump_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 1, 1), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_ITEM, CTLV_NODE_SCHEMA_UNLIMITED, 2, 5, 4), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_MR_NAME, 1, 1, 128), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, 21, 0, 20), > + CTLV_NODE_SCHEMA_FLAGS(CTLV_ATTESTATION_ATTR_MR_CAPS, 1, CTLV_ATTESTATION_MR_CAPS_MASK), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_read_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_read_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 2, 2), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_VALUE, 21, 3, 2, 2), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, 1, 0, 20), > + CTLV_NODE_SCHEMA_BINARY(CTLV_ATTESTATION_ATTR_MR_DATA, 1, 16, 64), > +}; > + > +static const struct ctlv_node_schema mr_extend_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 2, 2), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_VALUE, 21, 3, 2, 2), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, 1, 0, 20), > + CTLV_NODE_SCHEMA_BINARY(CTLV_ATTESTATION_ATTR_MR_DATA, 1, 16, 64), > +}; > + > +static const struct ctlv_node_schema mr_extend_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_GENERATION, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_log_entry_appended_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 1, 1), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_NOTIFICATION_ENTRY, 1, 2, 5, 3), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_LOG_EVENT, 1, 2), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_VALUE, 21, 7, 2, 2), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_LOG_MR, 1, 9, 4, 3), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, 1, 0, 20), > + CTLV_NODE_SCHEMA_BINARY(CTLV_ATTESTATION_ATTR_MR_DATA, 1, 16, 64), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_MR_NAME, 1, 1, 128), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, 21, 0, 20), > + CTLV_NODE_SCHEMA_FLAGS(CTLV_ATTESTATION_ATTR_MR_CAPS, 1, CTLV_ATTESTATION_MR_CAPS_MASK), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_log_get_request_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 3, 0), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_SELECTION, 256, 4, 1, 1), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_START_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_END_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > +}; > + > +static const struct ctlv_node_schema mr_log_get_reply_node_schemas[] = { > + CTLV_NODE_SCHEMA_ROOT(1, 3, 0), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_START_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_END_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_LOG_ENTRY, CTLV_NODE_SCHEMA_UNLIMITED, 4, 5, 3), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_GENERATION, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, U32_MAX), > + CTLV_NODE_SCHEMA_ENUM(CTLV_ATTESTATION_ATTR_LOG_EVENT, 1, 2), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_MR_VALUE, 21, 9, 2, 2), > + CTLV_NODE_SCHEMA_NEST(CTLV_ATTESTATION_ATTR_LOG_MR, 1, 11, 4, 3), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, 1, 0, 20), > + CTLV_NODE_SCHEMA_BINARY(CTLV_ATTESTATION_ATTR_MR_DATA, 1, 16, 64), > + CTLV_NODE_SCHEMA_STRING(CTLV_ATTESTATION_ATTR_MR_NAME, 1, 1, 128), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, 21, 0, 20), > + CTLV_NODE_SCHEMA_FLAGS(CTLV_ATTESTATION_ATTR_MR_CAPS, 1, CTLV_ATTESTATION_MR_CAPS_MASK), > + CTLV_NODE_SCHEMA_UINT(CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, 1, 0, U32_MAX), > +}; > + > +/* The ops this family declares, in declaration order. */ > +const struct ctlv_op_schema ctlv_attestation_op_schemas[] = { > + CTLV_OP_SCHEMA_ACTION(CTLV_ATTESTATION_OP_DEVICE_GET, CTLV_OP_FD_ACCESS_READ, > + CTLV_OP_AVAILABILITY_FIXED, 16, 4016, > + CTLV_SCHEMA_TREE(device_get_request), > + CTLV_SCHEMA_TREE_STUBS(device_get_reply)), > + CTLV_OP_SCHEMA_ACTION(CTLV_ATTESTATION_OP_EVIDENCE_GET, CTLV_OP_FD_ACCESS_READ_WRITE, > + CTLV_OP_AVAILABILITY_DYNAMIC, 8992, 424, > + CTLV_SCHEMA_TREE(evidence_get_request), > + CTLV_SCHEMA_TREE(evidence_get_reply), .optional = true), > + CTLV_OP_SCHEMA_ACTION(CTLV_ATTESTATION_OP_MR_GET, CTLV_OP_FD_ACCESS_READ, > + CTLV_OP_AVAILABILITY_FIXED, 40, 720, CTLV_SCHEMA_TREE(mr_get_request), > + CTLV_SCHEMA_TREE(mr_get_reply), .optional = true), > + CTLV_OP_SCHEMA_QUERY(CTLV_ATTESTATION_OP_MR_DUMP, CTLV_OP_FD_ACCESS_READ, > + CTLV_OP_AVAILABILITY_FIXED, 16, 184, 4096, > + CTLV_SCHEMA_TREE(mr_dump_request), CTLV_SCHEMA_TREE(mr_dump_reply), > + .optional = true), > + CTLV_OP_SCHEMA_QUERY(CTLV_ATTESTATION_OP_MR_READ, CTLV_OP_FD_ACCESS_READ, > + CTLV_OP_AVAILABILITY_FIXED, 40, 112, 4096, > + CTLV_SCHEMA_TREE(mr_read_request), CTLV_SCHEMA_TREE(mr_read_reply), > + .optional = true), > + CTLV_OP_SCHEMA_ACTION(CTLV_ATTESTATION_OP_MR_EXTEND, CTLV_OP_FD_ACCESS_READ_WRITE, > + CTLV_OP_AVAILABILITY_FIXED, 2560, 40, > + CTLV_SCHEMA_TREE(mr_extend_request), > + CTLV_SCHEMA_TREE(mr_extend_reply), .optional = true), > + CTLV_OP_SCHEMA_EVENT(CTLV_ATTESTATION_OP_MR_LOG_ENTRY_APPENDED, 3368, > + CTLV_SCHEMA_TREE(mr_log_entry_appended_reply)), > + CTLV_OP_SCHEMA_QUERY(CTLV_ATTESTATION_OP_MR_LOG_GET, CTLV_OP_FD_ACCESS_READ, > + CTLV_OP_AVAILABILITY_FIXED, 10304, 200, 131072, > + CTLV_SCHEMA_TREE(mr_log_get_request), > + CTLV_SCHEMA_TREE(mr_log_get_reply), .optional = true), > +}; > + > +/* The family ID is its position in the central registry. */ > +const struct ctlv_family_schema ctlv_attestation_schema = { > + .name = "ctlv-attestation", > + .family_id = 1, > + .ops = ctlv_attestation_op_schemas, > + .ops_count = ARRAY_SIZE(ctlv_attestation_op_schemas), > +}; > + > +/* Maximum uevent cost for this family chain. */ > +static_assert(107 <= CTLV_UEVENT_MAX_LEN); > +static_assert(4 <= CTLV_UEVENT_MAX_VARS); > + > +/* Guards for generated maxima. */ > +static_assert(131072 <= CTLV_MAX_INLINE_MESSAGE_LEN); > +static_assert(3368 <= CTLV_MAX_EVENT_QUEUE_LEN); > +static_assert(3 <= CTLV_MAX_DECLARED_NEST_DEPTH); > + > +/* Local action and query bindings in declaration order. */ > +static const struct ctlv_op ctlv_attestation_ops[] = { > + CTLV_OP_ACTION(ctlv_attestation_device_get), > + CTLV_OP_ACTION(ctlv_attestation_evidence_get), > + CTLV_OP_ACTION(ctlv_attestation_mr_get), > + CTLV_OP_QUERY(ctlv_attestation_mr_dump), > + CTLV_OP_QUERY(ctlv_attestation_mr_read), > + CTLV_OP_ACTION(ctlv_attestation_mr_extend), > + CTLV_OP_QUERY(ctlv_attestation_mr_log_get), > +}; > + > +/* Family descriptor used by ctlv_create(). */ > +const struct ctlv_family ctlv_attestation_family = { > + .schema = &ctlv_attestation_schema, > + .parent = &ctlv_family, > + .ops = ctlv_attestation_ops, > + .ops_count = ARRAY_SIZE(ctlv_attestation_ops), > + .pre = ctlv_attestation_op_pre, > + .post = ctlv_attestation_op_post, > + .priv_size = ctlv_attestation_priv_size, > + .init = ctlv_attestation_init, > + .post_init = ctlv_attestation_post_init, > + .pre_fini = ctlv_attestation_pre_fini, > + .fini = ctlv_attestation_fini, > +}; > +EXPORT_SYMBOL_NS_GPL(ctlv_attestation_family, "CTLV"); The descriptor is exported in namespace "CTLV" from `drivers/attestation/generated`, i.e. the symbol is exported by whichever module links this file, but the importer (TDX family, patch 19/20) must then also `MODULE_IMPORT_NS("CTLV")` only if it is in a separate module; the export namespace here is the *core's* namespace, not an attestation one. An attestation-specific namespace would be less confusing. Also nothing in this patch uses the export. > diff --git a/drivers/attestation/generated/ctlv_attestation_gen.h b/drivers/attestation/generated/ctlv_attestation_gen.h > new file mode 100644 > index 000000000000..a40ed0757756 > --- /dev/null > +++ b/drivers/attestation/generated/ctlv_attestation_gen.h > @@ -0,0 +1,198 @@ > +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ > +/* Do not edit, regenerate with tools/ctlv/ctlv-regen.sh, from: */ > +/* Documentation/ctlv/specs/ctlv-attestation.yaml */ > +/* CTLV-GEN kernel header */ > + > +/* Kernel metadata and family API of the ctlv-attestation CTLV family. */ > + > +#ifndef _LINUX_CTLV_ATTESTATION_GEN_H > +#define _LINUX_CTLV_ATTESTATION_GEN_H > + > +#include > +#include > +#include > + > +#include > + > +/* Ops this family declares, in declaration order. */ > +extern const struct ctlv_op_schema ctlv_attestation_op_schemas[]; > + > +extern const struct ctlv_family_schema ctlv_attestation_schema; > + > +/* Implemented by this family, one per action and query it declares. */ > +int ctlv_attestation_device_get_action(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, > + struct ctlv_cursor *reply); > +int ctlv_attestation_evidence_get_action(void *priv, struct ctlv_op_ctx *ctx, All of these prototypes (7 handlers, `op_pre`/`op_post`, `priv_size`, init, `post_init`, `pre_fini`, fini) are declarations of functions that do not exist anywhere in the tree at this commit. Fine as spec-first only because the .c is not built; anyone adding the Makefile line early gets undefined references. Please say so in the commit message. > + const struct ctlv_cursor *request, > + struct ctlv_cursor *reply); > +int ctlv_attestation_mr_get_action(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, struct ctlv_cursor *reply); > +int ctlv_attestation_mr_dump_query(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, struct ctlv_cursor *reply); > +int ctlv_attestation_mr_read_query(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, struct ctlv_cursor *reply); > +int ctlv_attestation_mr_extend_action(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, struct ctlv_cursor *reply); > +int ctlv_attestation_mr_log_get_query(void *priv, struct ctlv_op_ctx *ctx, > + const struct ctlv_cursor *request, struct ctlv_cursor *reply); > + > +/* Family-wide hooks around every effective non-core op. */ > +int ctlv_attestation_op_pre(void *priv, struct ctlv_op_ctx *ctx); > +void ctlv_attestation_op_post(void *priv, struct ctlv_op_ctx *ctx); > + > +/* Core-allocated family priv lifecycle. */ > +size_t ctlv_attestation_priv_size(void); > +int ctlv_attestation_init(struct ctlv_device *ctlvdev, const void *init_info, void *priv); > +int ctlv_attestation_post_init(struct ctlv_device *ctlvdev, void *priv); > +void ctlv_attestation_pre_fini(struct ctlv_device *ctlvdev, void *priv); > +void ctlv_attestation_fini(struct ctlv_device *ctlvdev, void *priv); > + > +extern const struct ctlv_family ctlv_attestation_family; > + > +#ifndef _CTLV_GENERATED_METADATA_ONLY > + > +/* Optional publication and dynamic availability helpers. */ > +CTLV_OP_PROVIDE(ctlv_attestation_evidence_get, CTLV_ATTESTATION_OP_EVIDENCE_GET) > +CTLV_OP_ENABLE(ctlv_attestation_evidence_get, CTLV_ATTESTATION_OP_EVIDENCE_GET) > +CTLV_OP_DISABLE(ctlv_attestation_evidence_get, CTLV_ATTESTATION_OP_EVIDENCE_GET) > +CTLV_OP_PROVIDE(ctlv_attestation_mr_get, CTLV_ATTESTATION_OP_MR_GET) > +CTLV_OP_PROVIDE(ctlv_attestation_mr_dump, CTLV_ATTESTATION_OP_MR_DUMP) > +CTLV_OP_PROVIDE(ctlv_attestation_mr_read, CTLV_ATTESTATION_OP_MR_READ) > +CTLV_OP_PROVIDE(ctlv_attestation_mr_extend, CTLV_ATTESTATION_OP_MR_EXTEND) > +CTLV_OP_PROVIDE(ctlv_attestation_mr_log_get, CTLV_ATTESTATION_OP_MR_LOG_GET) > + > +/* Reading a validated message. A blob has a resolver instead of a getter. */ > +CTLV_IN_REF(ctlv_attestation_evidence_get_evidence_challenge, > + &ctlv_attestation_op_schemas[1].request, CTLV_ATTESTATION_ATTR_EVIDENCE_CHALLENGE, 0, 0, > + CTLV_SCHEMA_BINARY) > +CTLV_IN_HAS(ctlv_attestation_evidence_get_evidence_challenge) > +CTLV_IN_BINARY(ctlv_attestation_evidence_get_evidence_challenge) > +CTLV_IN_REF(ctlv_attestation_evidence_get_evidence_object, &ctlv_attestation_op_schemas[1].request, Getters hard-code &`ctlv_attestation_op_schemas[1]` (array index of the op, 'declaration order') and a (node, slot) pair. Reordering ops in the YAML silently renumbers these, but that is covered by regeneration; however the ABI snapshot (op IDs) and the array index are two different numberings that must stay in sync - consider an assertion in the generated .c (e.g. `static_assert` on `op_schemas[1]`.`op_id`) so a hand-edit/mismatch is caught at build time. > + CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT, 0, 1, CTLV_SCHEMA_NEST) > +#define ctlv_attestation_evidence_get_evidence_object_for_each(_attr, _nest) \ > + CTLV_IN_FOR_EACH(ctlv_attestation_evidence_get_evidence_object, _attr, _nest) > +CTLV_IN_REF(ctlv_attestation_evidence_get_object_evidence_blob_class, Naming: `___` yields `ctlv_attestation_evidence_get_object_evidence_blob_class`, `ctlv_attestation_mr_get_mr_id`, `ctlv_attestation_mr_extend_value_mr_data` ... 'evidence' and 'mr' appear stuttered (group name repeated after the nest name). These are the public accessor names that handlers will use for years; patch 13 documents a different scheme. Fix either the docs or the generator. > + &ctlv_attestation_op_schemas[1].request, CTLV_ATTESTATION_ATTR_EVIDENCE_BLOB_CLASS, 2, > + 0, CTLV_SCHEMA_ENUM) > +CTLV_IN_HAS(ctlv_attestation_evidence_get_object_evidence_blob_class) > +CTLV_IN_U64(ctlv_attestation_evidence_get_object_evidence_blob_class) > +CTLV_IN_REF(ctlv_attestation_evidence_get_object_evidence_format, > + &ctlv_attestation_op_schemas[1].request, CTLV_ATTESTATION_ATTR_EVIDENCE_FORMAT, 2, 1, > + CTLV_SCHEMA_STRING) > +CTLV_IN_HAS(ctlv_attestation_evidence_get_object_evidence_format) > +CTLV_IN_STRING(ctlv_attestation_evidence_get_object_evidence_format) > +CTLV_IN_REF(ctlv_attestation_evidence_get_object_evidence_representation, > + &ctlv_attestation_op_schemas[1].request, CTLV_ATTESTATION_ATTR_EVIDENCE_REPRESENTATION, > + 2, 2, CTLV_SCHEMA_ENUM) > +CTLV_IN_HAS(ctlv_attestation_evidence_get_object_evidence_representation) > +CTLV_IN_U64(ctlv_attestation_evidence_get_object_evidence_representation) > +CTLV_IN_REF(ctlv_attestation_evidence_get_object_evidence_data, > + &ctlv_attestation_op_schemas[1].request, CTLV_ATTESTATION_ATTR_EVIDENCE_DATA, 2, 3, > + CTLV_SCHEMA_BLOB) > +CTLV_IN_HAS(ctlv_attestation_evidence_get_object_evidence_data) > +CTLV_IN_BLOB(ctlv_attestation_evidence_get_object_evidence_data) > +CTLV_IN_REF(ctlv_attestation_mr_get_mr_id, &ctlv_attestation_op_schemas[2].request, > + CTLV_ATTESTATION_ATTR_MR_ID, 0, 0, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_get_mr_id) > +CTLV_IN_U64(ctlv_attestation_mr_get_mr_id) > +CTLV_IN_REF(ctlv_attestation_mr_read_mr_id, &ctlv_attestation_op_schemas[4].request, > + CTLV_ATTESTATION_ATTR_MR_ID, 0, 0, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_read_mr_id) > +CTLV_IN_U64(ctlv_attestation_mr_read_mr_id) > +CTLV_IN_REF(ctlv_attestation_mr_extend_mr_id, &ctlv_attestation_op_schemas[5].request, > + CTLV_ATTESTATION_ATTR_MR_ID, 0, 0, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_extend_mr_id) > +CTLV_IN_U64(ctlv_attestation_mr_extend_mr_id) > +CTLV_IN_REF(ctlv_attestation_mr_extend_mr_value, &ctlv_attestation_op_schemas[5].request, > + CTLV_ATTESTATION_ATTR_MR_VALUE, 0, 1, CTLV_SCHEMA_NEST) > +#define ctlv_attestation_mr_extend_mr_value_for_each(_attr, _nest) \ > + CTLV_IN_FOR_EACH(ctlv_attestation_mr_extend_mr_value, _attr, _nest) > +CTLV_IN_REF(ctlv_attestation_mr_extend_value_mr_hash_algo, &ctlv_attestation_op_schemas[5].request, > + CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, 2, 0, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_extend_value_mr_hash_algo) > +CTLV_IN_U64(ctlv_attestation_mr_extend_value_mr_hash_algo) > +CTLV_IN_REF(ctlv_attestation_mr_extend_value_mr_data, &ctlv_attestation_op_schemas[5].request, > + CTLV_ATTESTATION_ATTR_MR_DATA, 2, 1, CTLV_SCHEMA_BINARY) > +CTLV_IN_HAS(ctlv_attestation_mr_extend_value_mr_data) > +CTLV_IN_BINARY(ctlv_attestation_mr_extend_value_mr_data) > +CTLV_IN_REF(ctlv_attestation_mr_log_get_mr_selection, &ctlv_attestation_op_schemas[7].request, > + CTLV_ATTESTATION_ATTR_MR_SELECTION, 0, 0, CTLV_SCHEMA_NEST) > +#define ctlv_attestation_mr_log_get_mr_selection_for_each(_attr, _nest) \ > + CTLV_IN_FOR_EACH(ctlv_attestation_mr_log_get_mr_selection, _attr, _nest) > +CTLV_IN_REF(ctlv_attestation_mr_log_get_mr_start_generation, > + &ctlv_attestation_op_schemas[7].request, CTLV_ATTESTATION_ATTR_MR_START_GENERATION, 0, > + 1, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_log_get_mr_start_generation) > +CTLV_IN_U64(ctlv_attestation_mr_log_get_mr_start_generation) > +CTLV_IN_REF(ctlv_attestation_mr_log_get_mr_end_generation, &ctlv_attestation_op_schemas[7].request, > + CTLV_ATTESTATION_ATTR_MR_END_GENERATION, 0, 2, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_log_get_mr_end_generation) > +CTLV_IN_U64(ctlv_attestation_mr_log_get_mr_end_generation) > +CTLV_IN_REF(ctlv_attestation_mr_log_get_selection_mr_id, &ctlv_attestation_op_schemas[7].request, > + CTLV_ATTESTATION_ATTR_MR_ID, 1, 0, CTLV_SCHEMA_UINT) > +CTLV_IN_HAS(ctlv_attestation_mr_log_get_selection_mr_id) > +CTLV_IN_U64(ctlv_attestation_mr_log_get_selection_mr_id) > + > +/* Writing a reply. An append is atomic; a nest ends with ctlv_nest_end(). */ > +CTLV_PUT_U64(ctlv_attestation_device_generation, CTLV_ATTESTATION_ATTR_DEVICE_GENERATION, > + CTLV_SCHEMA_UINT) > +CTLV_NEST_START(ctlv_attestation_device_caps, CTLV_ATTESTATION_ATTR_DEVICE_CAPS, CTLV_SCHEMA_NEST) The put/nest helpers are emitted for every attribute of every group, regardless of whether any reply uses it (e.g. `ctlv_attestation_evidence_challenge_put`, `ctlv_attestation_evidence_blob_class_put`, `ctlv_attestation_mr_selection_start` and ...`_mr_start_generation_put` are request-only attributes and are never written by the kernel; conversely `ctlv_attestation_device_generation_put` is unused entirely). All are static inline so there are no unused warnings, but it makes the writable surface of replies untyped relative to the schema (the validation then happens at runtime). > +CTLV_NEST_START(ctlv_attestation_device_info, CTLV_ATTESTATION_ATTR_DEVICE_INFO, CTLV_SCHEMA_NEST) > +CTLV_NEST_START(ctlv_attestation_cap_evidence, CTLV_ATTESTATION_ATTR_CAP_EVIDENCE, CTLV_SCHEMA_NEST) > +CTLV_NEST_START(ctlv_attestation_cap_mr, CTLV_ATTESTATION_ATTR_CAP_MR, CTLV_SCHEMA_NEST) > +CTLV_PUT_U64(ctlv_attestation_cap_min_challenge_length, > + CTLV_ATTESTATION_ATTR_CAP_MIN_CHALLENGE_LENGTH, CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_cap_max_challenge_length, > + CTLV_ATTESTATION_ATTR_CAP_MAX_CHALLENGE_LENGTH, CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_cap_max_total_output_length, > + CTLV_ATTESTATION_ATTR_CAP_MAX_TOTAL_OUTPUT_LENGTH, CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_cap_mr_flags, CTLV_ATTESTATION_ATTR_CAP_MR_FLAGS, CTLV_SCHEMA_FLAGS) > +CTLV_NEST_START(ctlv_attestation_cap_object, CTLV_ATTESTATION_ATTR_CAP_OBJECT, CTLV_SCHEMA_NEST) > +CTLV_PUT_U64(ctlv_attestation_cap_blob_class, CTLV_ATTESTATION_ATTR_CAP_BLOB_CLASS, > + CTLV_SCHEMA_ENUM) > +CTLV_PUT_STRING(ctlv_attestation_cap_format, CTLV_ATTESTATION_ATTR_CAP_FORMAT, CTLV_SCHEMA_STRING) > +CTLV_PUT_U64(ctlv_attestation_cap_representation, CTLV_ATTESTATION_ATTR_CAP_REPRESENTATION, > + CTLV_SCHEMA_ENUM) > +CTLV_PUT_U64(ctlv_attestation_cap_max_length, CTLV_ATTESTATION_ATTR_CAP_MAX_LENGTH, > + CTLV_SCHEMA_UINT) > +CTLV_PUT_BINARY(ctlv_attestation_evidence_challenge, CTLV_ATTESTATION_ATTR_EVIDENCE_CHALLENGE, > + CTLV_SCHEMA_BINARY) > +CTLV_NEST_START(ctlv_attestation_evidence_object, CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT, > + CTLV_SCHEMA_NEST) > +CTLV_PUT_U64(ctlv_attestation_evidence_blob_class, CTLV_ATTESTATION_ATTR_EVIDENCE_BLOB_CLASS, > + CTLV_SCHEMA_ENUM) > +CTLV_PUT_STRING(ctlv_attestation_evidence_format, CTLV_ATTESTATION_ATTR_EVIDENCE_FORMAT, > + CTLV_SCHEMA_STRING) > +CTLV_PUT_U64(ctlv_attestation_evidence_representation, > + CTLV_ATTESTATION_ATTR_EVIDENCE_REPRESENTATION, CTLV_SCHEMA_ENUM) > +CTLV_PUT_U64(ctlv_attestation_evidence_object_length, CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT_LENGTH, > + CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_mr_id, CTLV_ATTESTATION_ATTR_MR_ID, CTLV_SCHEMA_UINT) > +CTLV_PUT_STRING(ctlv_attestation_mr_name, CTLV_ATTESTATION_ATTR_MR_NAME, CTLV_SCHEMA_STRING) > +CTLV_PUT_U64(ctlv_attestation_mr_hash_algo, CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_mr_supported_hash_algo, CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, > + CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_mr_register_index, CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, > + CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_mr_caps, CTLV_ATTESTATION_ATTR_MR_CAPS, CTLV_SCHEMA_FLAGS) > +CTLV_NEST_START(ctlv_attestation_mr_item, CTLV_ATTESTATION_ATTR_MR_ITEM, CTLV_SCHEMA_NEST) > +CTLV_NEST_START(ctlv_attestation_mr_value, CTLV_ATTESTATION_ATTR_MR_VALUE, CTLV_SCHEMA_NEST) > +CTLV_PUT_BINARY(ctlv_attestation_mr_data, CTLV_ATTESTATION_ATTR_MR_DATA, CTLV_SCHEMA_BINARY) > +CTLV_PUT_U64(ctlv_attestation_mr_generation, CTLV_ATTESTATION_ATTR_MR_GENERATION, CTLV_SCHEMA_UINT) > +CTLV_NEST_START(ctlv_attestation_mr_selection, CTLV_ATTESTATION_ATTR_MR_SELECTION, CTLV_SCHEMA_NEST) > +CTLV_PUT_U64(ctlv_attestation_mr_start_generation, CTLV_ATTESTATION_ATTR_MR_START_GENERATION, > + CTLV_SCHEMA_UINT) > +CTLV_PUT_U64(ctlv_attestation_mr_end_generation, CTLV_ATTESTATION_ATTR_MR_END_GENERATION, > + CTLV_SCHEMA_UINT) > +CTLV_NEST_START(ctlv_attestation_log_entry, CTLV_ATTESTATION_ATTR_LOG_ENTRY, CTLV_SCHEMA_NEST) > +CTLV_PUT_U64(ctlv_attestation_log_event, CTLV_ATTESTATION_ATTR_LOG_EVENT, CTLV_SCHEMA_ENUM) > +CTLV_NEST_START(ctlv_attestation_log_mr, CTLV_ATTESTATION_ATTR_LOG_MR, CTLV_SCHEMA_NEST) > +CTLV_NEST_START(ctlv_attestation_notification_entry, CTLV_ATTESTATION_ATTR_NOTIFICATION_ENTRY, > + CTLV_SCHEMA_NEST) > + > +/* Building one event, passed to ctlv_event_emit() or ctlv_event_abort() once. */ > +CTLV_EVENT_CREATE(ctlv_attestation_mr_log_entry_appended, CTLV_ATTESTATION_OP_MR_LOG_ENTRY_APPENDED) Missing: no `_fill`/`_provide` for the stub (`CTLV_STUB`...) because the family only declares it; fine. > +#endif /* _CTLV_GENERATED_METADATA_ONLY */ > + > +#endif /* _LINUX_CTLV_ATTESTATION_GEN_H */ > diff --git a/include/uapi/linux/ctlv_attestation_gen.h b/include/uapi/linux/ctlv_attestation_gen.h > new file mode 100644 > index 000000000000..888bbf06618b > --- /dev/null > +++ b/include/uapi/linux/ctlv_attestation_gen.h enum evidence-representation and enum evidence-blob-class each define exactly one value (RAW = 1, PRIMARY = 1) and nothing in the series uses another: speculative generality frozen into UAPI. Drop them (use a plain presence/format attribute) or add a second consumer. > @@ -0,0 +1,252 @@ > +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ > +/* Do not edit, regenerate with tools/ctlv/ctlv-regen.sh, from: */ > +/* Documentation/ctlv/specs/ctlv-attestation.yaml */ > +/* CTLV-GEN uapi header */ > + > +/* > + * Constants of the ctlv-attestation CTLV family. Attr and op IDs are complete; the wire format > + * carrying them is in . > + * > + * The inherited ctlv header is included here, so one include covers the whole effective schema. > + */ > + > +#ifndef _UAPI_LINUX_CTLV_ATTESTATION_GEN_H > +#define _UAPI_LINUX_CTLV_ATTESTATION_GEN_H > + > +#include > +#include > +#include > +#include > + > +/* enum evidence-representation */ > +enum _ctlv_attestation_evidence_representation { > + CTLV_ATTESTATION_EVIDENCE_REPRESENTATION_RAW = 1, > +}; > + > +/* enum evidence-blob-class */ > +enum _ctlv_attestation_evidence_blob_class { > + CTLV_ATTESTATION_EVIDENCE_BLOB_CLASS_PRIMARY = 1, > +}; > + > +/* enum mr-log-event */ > +enum _ctlv_attestation_mr_log_event { > + CTLV_ATTESTATION_MR_LOG_EVENT_INFO = 1, > + CTLV_ATTESTATION_MR_LOG_EVENT_EXTEND, > +}; > + > +/* flags mr-device-caps */ > +enum _ctlv_attestation_mr_device_caps_bit { > + CTLV_ATTESTATION_MR_DEVICE_CAPS_READ_BIT, > + CTLV_ATTESTATION_MR_DEVICE_CAPS_EXTEND_BIT, > +}; > + > +#define CTLV_ATTESTATION_MR_DEVICE_CAPS_READ _BITULL(CTLV_ATTESTATION_MR_DEVICE_CAPS_READ_BIT) > +#define CTLV_ATTESTATION_MR_DEVICE_CAPS_EXTEND _BITULL(CTLV_ATTESTATION_MR_DEVICE_CAPS_EXTEND_BIT) > +#define CTLV_ATTESTATION_MR_DEVICE_CAPS_MASK \ > + (CTLV_ATTESTATION_MR_DEVICE_CAPS_READ | \ > + CTLV_ATTESTATION_MR_DEVICE_CAPS_EXTEND) > + > +/* flags mr-caps */ > +enum _ctlv_attestation_mr_caps_bit { > + CTLV_ATTESTATION_MR_CAPS_READ_BIT, > + CTLV_ATTESTATION_MR_CAPS_EXTEND_BIT, > +}; > + > +#define CTLV_ATTESTATION_MR_CAPS_READ _BITULL(CTLV_ATTESTATION_MR_CAPS_READ_BIT) > +#define CTLV_ATTESTATION_MR_CAPS_EXTEND _BITULL(CTLV_ATTESTATION_MR_CAPS_EXTEND_BIT) > +#define CTLV_ATTESTATION_MR_CAPS_MASK \ > + (CTLV_ATTESTATION_MR_CAPS_READ | \ > + CTLV_ATTESTATION_MR_CAPS_EXTEND) > + > +/* attr groups */ > +enum _ctlv_attestation_group { > + CTLV_ATTESTATION_GROUP_DEVICE = 1, > + CTLV_ATTESTATION_GROUP_CAP, > + CTLV_ATTESTATION_GROUP_EVIDENCE, > + CTLV_ATTESTATION_GROUP_MR, > + CTLV_ATTESTATION_GROUP_LOG, > + CTLV_ATTESTATION_GROUP_NOTIFICATION, > +}; > + > +#define _CTLV_ATTESTATION_ATTR(_group, _attr) CTLV_ATTR(CTLV_FAMILY_ATTESTATION, (_group), (_attr)) > + > +/* attrs of group device */ > +#define _CTLV_ATTESTATION_ATTR_DEVICE(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_DEVICE, _CTLV_ATTESTATION_ATTR_DEVICE_##_attr) > + > +enum _ctlv_attestation_attr_device { > + _CTLV_ATTESTATION_ATTR_DEVICE_GENERATION = 1, > + _CTLV_ATTESTATION_ATTR_DEVICE_CAPS, > + _CTLV_ATTESTATION_ATTR_DEVICE_INFO, > +}; > + > +#define CTLV_ATTESTATION_ATTR_DEVICE_GENERATION _CTLV_ATTESTATION_ATTR_DEVICE(GENERATION) > +#define CTLV_ATTESTATION_ATTR_DEVICE_CAPS _CTLV_ATTESTATION_ATTR_DEVICE(CAPS) > +#define CTLV_ATTESTATION_ATTR_DEVICE_INFO _CTLV_ATTESTATION_ATTR_DEVICE(INFO) > + > +/* attrs of group cap */ > +#define _CTLV_ATTESTATION_ATTR_CAP(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_CAP, _CTLV_ATTESTATION_ATTR_CAP_##_attr) > + > +enum _ctlv_attestation_attr_cap { > + _CTLV_ATTESTATION_ATTR_CAP_EVIDENCE = 1, > + _CTLV_ATTESTATION_ATTR_CAP_MR, > + _CTLV_ATTESTATION_ATTR_CAP_MIN_CHALLENGE_LENGTH, > + _CTLV_ATTESTATION_ATTR_CAP_MAX_CHALLENGE_LENGTH, > + _CTLV_ATTESTATION_ATTR_CAP_MAX_TOTAL_OUTPUT_LENGTH, > + _CTLV_ATTESTATION_ATTR_CAP_MR_FLAGS, > + _CTLV_ATTESTATION_ATTR_CAP_OBJECT, > + _CTLV_ATTESTATION_ATTR_CAP_BLOB_CLASS, > + _CTLV_ATTESTATION_ATTR_CAP_FORMAT, > + _CTLV_ATTESTATION_ATTR_CAP_REPRESENTATION, > + _CTLV_ATTESTATION_ATTR_CAP_MAX_LENGTH, > +}; > + > +#define CTLV_ATTESTATION_ATTR_CAP_EVIDENCE _CTLV_ATTESTATION_ATTR_CAP(EVIDENCE) > +#define CTLV_ATTESTATION_ATTR_CAP_MR _CTLV_ATTESTATION_ATTR_CAP(MR) > +#define CTLV_ATTESTATION_ATTR_CAP_MIN_CHALLENGE_LENGTH \ > + _CTLV_ATTESTATION_ATTR_CAP(MIN_CHALLENGE_LENGTH) > +#define CTLV_ATTESTATION_ATTR_CAP_MAX_CHALLENGE_LENGTH \ > + _CTLV_ATTESTATION_ATTR_CAP(MAX_CHALLENGE_LENGTH) > +#define CTLV_ATTESTATION_ATTR_CAP_MAX_TOTAL_OUTPUT_LENGTH \ > + _CTLV_ATTESTATION_ATTR_CAP(MAX_TOTAL_OUTPUT_LENGTH) > +#define CTLV_ATTESTATION_ATTR_CAP_MR_FLAGS _CTLV_ATTESTATION_ATTR_CAP(MR_FLAGS) > +#define CTLV_ATTESTATION_ATTR_CAP_OBJECT _CTLV_ATTESTATION_ATTR_CAP(OBJECT) > +#define CTLV_ATTESTATION_ATTR_CAP_BLOB_CLASS _CTLV_ATTESTATION_ATTR_CAP(BLOB_CLASS) > +#define CTLV_ATTESTATION_ATTR_CAP_FORMAT _CTLV_ATTESTATION_ATTR_CAP(FORMAT) > +#define CTLV_ATTESTATION_ATTR_CAP_REPRESENTATION _CTLV_ATTESTATION_ATTR_CAP(REPRESENTATION) > +#define CTLV_ATTESTATION_ATTR_CAP_MAX_LENGTH _CTLV_ATTESTATION_ATTR_CAP(MAX_LENGTH) > + > +/* attrs of group evidence */ > +#define _CTLV_ATTESTATION_ATTR_EVIDENCE(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_EVIDENCE, \ > + _CTLV_ATTESTATION_ATTR_EVIDENCE_##_attr) > + > +enum _ctlv_attestation_attr_evidence { > + _CTLV_ATTESTATION_ATTR_EVIDENCE_CHALLENGE = 1, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_BLOB_CLASS, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_FORMAT, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_REPRESENTATION, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_DATA, > + _CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT_LENGTH, > +}; > + > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_CHALLENGE _CTLV_ATTESTATION_ATTR_EVIDENCE(CHALLENGE) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT _CTLV_ATTESTATION_ATTR_EVIDENCE(OBJECT) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_BLOB_CLASS _CTLV_ATTESTATION_ATTR_EVIDENCE(BLOB_CLASS) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_FORMAT _CTLV_ATTESTATION_ATTR_EVIDENCE(FORMAT) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_REPRESENTATION \ > + _CTLV_ATTESTATION_ATTR_EVIDENCE(REPRESENTATION) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_DATA _CTLV_ATTESTATION_ATTR_EVIDENCE(DATA) > +#define CTLV_ATTESTATION_ATTR_EVIDENCE_OBJECT_LENGTH _CTLV_ATTESTATION_ATTR_EVIDENCE(OBJECT_LENGTH) > + > +/* attrs of group mr */ > +#define _CTLV_ATTESTATION_ATTR_MR(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_MR, _CTLV_ATTESTATION_ATTR_MR_##_attr) > + > +enum _ctlv_attestation_attr_mr { > + _CTLV_ATTESTATION_ATTR_MR_ID = 1, > + _CTLV_ATTESTATION_ATTR_MR_NAME, > + _CTLV_ATTESTATION_ATTR_MR_HASH_ALGO, > + _CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO, > + _CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX, > + _CTLV_ATTESTATION_ATTR_MR_CAPS, > + _CTLV_ATTESTATION_ATTR_MR_ITEM, > + _CTLV_ATTESTATION_ATTR_MR_VALUE, > + _CTLV_ATTESTATION_ATTR_MR_DATA, > + _CTLV_ATTESTATION_ATTR_MR_GENERATION, > + _CTLV_ATTESTATION_ATTR_MR_SELECTION, > + _CTLV_ATTESTATION_ATTR_MR_START_GENERATION, > + _CTLV_ATTESTATION_ATTR_MR_END_GENERATION, > +}; > + > +#define CTLV_ATTESTATION_ATTR_MR_ID _CTLV_ATTESTATION_ATTR_MR(ID) > +#define CTLV_ATTESTATION_ATTR_MR_NAME _CTLV_ATTESTATION_ATTR_MR(NAME) > +#define CTLV_ATTESTATION_ATTR_MR_HASH_ALGO _CTLV_ATTESTATION_ATTR_MR(HASH_ALGO) > +#define CTLV_ATTESTATION_ATTR_MR_SUPPORTED_HASH_ALGO _CTLV_ATTESTATION_ATTR_MR(SUPPORTED_HASH_ALGO) > +#define CTLV_ATTESTATION_ATTR_MR_REGISTER_INDEX _CTLV_ATTESTATION_ATTR_MR(REGISTER_INDEX) > +#define CTLV_ATTESTATION_ATTR_MR_CAPS _CTLV_ATTESTATION_ATTR_MR(CAPS) > +#define CTLV_ATTESTATION_ATTR_MR_ITEM _CTLV_ATTESTATION_ATTR_MR(ITEM) > +#define CTLV_ATTESTATION_ATTR_MR_VALUE _CTLV_ATTESTATION_ATTR_MR(VALUE) > +#define CTLV_ATTESTATION_ATTR_MR_DATA _CTLV_ATTESTATION_ATTR_MR(DATA) > +#define CTLV_ATTESTATION_ATTR_MR_GENERATION _CTLV_ATTESTATION_ATTR_MR(GENERATION) > +#define CTLV_ATTESTATION_ATTR_MR_SELECTION _CTLV_ATTESTATION_ATTR_MR(SELECTION) > +#define CTLV_ATTESTATION_ATTR_MR_START_GENERATION _CTLV_ATTESTATION_ATTR_MR(START_GENERATION) > +#define CTLV_ATTESTATION_ATTR_MR_END_GENERATION _CTLV_ATTESTATION_ATTR_MR(END_GENERATION) > + > +/* attrs of group log */ > +#define _CTLV_ATTESTATION_ATTR_LOG(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_LOG, _CTLV_ATTESTATION_ATTR_LOG_##_attr) > + > +enum _ctlv_attestation_attr_log { > + _CTLV_ATTESTATION_ATTR_LOG_ENTRY = 1, > + _CTLV_ATTESTATION_ATTR_LOG_EVENT, > + _CTLV_ATTESTATION_ATTR_LOG_MR, > +}; > + > +#define CTLV_ATTESTATION_ATTR_LOG_ENTRY _CTLV_ATTESTATION_ATTR_LOG(ENTRY) > +#define CTLV_ATTESTATION_ATTR_LOG_EVENT _CTLV_ATTESTATION_ATTR_LOG(EVENT) > +#define CTLV_ATTESTATION_ATTR_LOG_MR _CTLV_ATTESTATION_ATTR_LOG(MR) > + > +/* attrs of group notification */ > +#define _CTLV_ATTESTATION_ATTR_NOTIFICATION(_attr) \ > + _CTLV_ATTESTATION_ATTR(CTLV_ATTESTATION_GROUP_NOTIFICATION, \ > + _CTLV_ATTESTATION_ATTR_NOTIFICATION_##_attr) > + > +enum _ctlv_attestation_attr_notification { > + _CTLV_ATTESTATION_ATTR_NOTIFICATION_ENTRY = 1, > +}; > + > +#define CTLV_ATTESTATION_ATTR_NOTIFICATION_ENTRY _CTLV_ATTESTATION_ATTR_NOTIFICATION(ENTRY) > + > +/* attr sets */ > +enum _ctlv_attestation_set { > + CTLV_ATTESTATION_SET_DEVICE_INFO = 1, > + CTLV_ATTESTATION_SET_EVIDENCE_OBJECT_CAP, > + CTLV_ATTESTATION_SET_EVIDENCE_CAP, > + CTLV_ATTESTATION_SET_MR_DEVICE_CAP, > + CTLV_ATTESTATION_SET_DEVICE_CAPS, > + CTLV_ATTESTATION_SET_DEVICE_REPLY, > + CTLV_ATTESTATION_SET_EVIDENCE_OBJECT_REQUEST, > + CTLV_ATTESTATION_SET_EVIDENCE_REQUEST, > + CTLV_ATTESTATION_SET_EVIDENCE_REPLY, > + CTLV_ATTESTATION_SET_MR_PROPS, > + CTLV_ATTESTATION_SET_MR_DUMP_ENTRY, > + CTLV_ATTESTATION_SET_MR_ID_REQUEST, > + CTLV_ATTESTATION_SET_MR_READ_REQUEST, > + CTLV_ATTESTATION_SET_MR_VALUE, > + CTLV_ATTESTATION_SET_MR_READ_REPLY, > + CTLV_ATTESTATION_SET_MR_EXTEND_REQUEST, > + CTLV_ATTESTATION_SET_MR_CHANGE_REPLY, > + CTLV_ATTESTATION_SET_MR_LOG_INFO, > + CTLV_ATTESTATION_SET_MR_LOG_ENTRY, > + CTLV_ATTESTATION_SET_MR_LOG_EVENT, Attr set IDs (23 of them) are exposed in the UAPI header although only `DEVICE_INFO` (the stub) can ever appear on the wire/in introspection. If sets are not ABI-visible, they needlessly bloat the UAPI; if they are (they are listed in the ABI snapshot), then the duplicates called out in the spec become permanent. > + CTLV_ATTESTATION_SET_MR_LOG_SELECTION, > + CTLV_ATTESTATION_SET_MR_LOG_REQUEST, > + CTLV_ATTESTATION_SET_MR_LOG_REPLY, > +}; > + > +/* ops */ > +enum _ctlv_attestation_op { > + _CTLV_ATTESTATION_OP_DEVICE_GET = 1, > + _CTLV_ATTESTATION_OP_EVIDENCE_GET, > + _CTLV_ATTESTATION_OP_MR_GET, > + _CTLV_ATTESTATION_OP_MR_DUMP, > + _CTLV_ATTESTATION_OP_MR_READ, > + _CTLV_ATTESTATION_OP_MR_EXTEND, > + _CTLV_ATTESTATION_OP_MR_LOG_ENTRY_APPENDED, > + _CTLV_ATTESTATION_OP_MR_LOG_GET, > +}; > + > +#define _CTLV_ATTESTATION_OP(_op) CTLV_OP(CTLV_FAMILY_ATTESTATION, _CTLV_ATTESTATION_OP_##_op) > +#define CTLV_ATTESTATION_OP_DEVICE_GET _CTLV_ATTESTATION_OP(DEVICE_GET) > +#define CTLV_ATTESTATION_OP_EVIDENCE_GET _CTLV_ATTESTATION_OP(EVIDENCE_GET) > +#define CTLV_ATTESTATION_OP_MR_GET _CTLV_ATTESTATION_OP(MR_GET) > +#define CTLV_ATTESTATION_OP_MR_DUMP _CTLV_ATTESTATION_OP(MR_DUMP) > +#define CTLV_ATTESTATION_OP_MR_READ _CTLV_ATTESTATION_OP(MR_READ) > +#define CTLV_ATTESTATION_OP_MR_EXTEND _CTLV_ATTESTATION_OP(MR_EXTEND) > +#define CTLV_ATTESTATION_OP_MR_LOG_ENTRY_APPENDED _CTLV_ATTESTATION_OP(MR_LOG_ENTRY_APPENDED) > +#define CTLV_ATTESTATION_OP_MR_LOG_GET _CTLV_ATTESTATION_OP(MR_LOG_GET) > + > +#endif /* _UAPI_LINUX_CTLV_ATTESTATION_GEN_H */ > diff --git a/include/uapi/linux/ctlv_families_gen.h b/include/uapi/linux/ctlv_families_gen.h > index a649483ab3f5..2ea3068868be 100644 > --- a/include/uapi/linux/ctlv_families_gen.h > +++ b/include/uapi/linux/ctlv_families_gen.h > @@ -10,6 +10,7 @@ > > enum _ctlv_family { > CTLV_FAMILY_ROOT, > + CTLV_FAMILY_ATTESTATION, > }; > > #endif /* _UAPI_LINUX_CTLV_FAMILIES_GEN_H */ > -- > 2.55.0 > Summary: - I regenerated at this commit (`ctlv-regen.sh` -c, validate, abi-check): generated files match the spec and ABI snapshot, so no generator mismatch found. - UAPI/ABI quality: device.generation is dead (unused by any set or op) yet frozen in the ABI; hash-algo 'max: 20' / 21 occurrences are unexplained magic numbers against `hash_info.h` (which now extends to 22); capability lengths are unbounded (`U64_MAX`) while consumers are bounded; evidence-get requires read-write fd access with no rationale. - Spec redundancy: mr-props / mr-dump-entry / mr-log-info, mr-id-request / mr-read-request / mr-log-selection are near-identical sets, each burning a permanent set ID; 'mr-log-event' names an enum and a set and the event's reply set. - Series/commit message: 1200 lines of generated C/H that are not built and reference ~13 undefined functions; commit message should say so. Single-valued enums are speculative. - MAINTAINERS uses a different e-mail than patch 13; accessor names are stuttered and do not match the naming documented in patch 13.