spec sync v2.4 - #3888
Merged
Merged
Conversation
The Configurable Device Personality feature (Feature ID 22h, Log Page 1Dh) had only bare enum stubs for its Feature and Log IDs, with none of the underlying data structures. ECN139 finalizes the CDP definitions in the NVMe Base Specification 2.4, and both TP4195 (Restore Manufacturing Default Settings) and TP4200 (Lockdown Persistence Personality) build on this same infrastructure, so it needs to land before either of those. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add Personality Identifier 02h (Lockdown Persistence Personality) on top of the Configurable Device Personality scaffolding, plus its Command Dword 11 (LDPE) and Get Features Completion Queue Entry Dword 1 (LDPS) fields. This personality lets a host persist the Lockdown command's prohibitions across power cycles. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…s (TP4215) Add the RUHS bit to the FID Supported and Effects Data Structure scope field, indicating that modifying a feature's attributes may impact Reclaim Unit Handles. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add the Purge Required (PREQ) bit to the Sanitize and Sanitize
Namespace commands, the Purged (PRGD) bit to the Sanitize Status log
page, and the Sanitize Purge Request and Reporting Supported (SPRRS)
bit to the Identify Controller Sanitize Capabilities field, letting a
host require that a sanitize operation purge user data (as defined by
IEEE Std 2883) or fail. Wire up the new nvme_init_sanitize_{nvm,ns}()
parameter, the --preq CLI flag on both sanitize commands, and print
support.
Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add the Minimum Idle I/O Exit Latency Limit (MIIELL) field to the Power State Descriptor and the Idle I/O Exit Latency Limit (IIELL) attribute to the Power Management feature, letting a host cap the maximum additional command completion latency it will accept from power optimizations while idle. CTRATT's IIELLSS support/scope bits were already present; this adds the fields that actually carry the limit. Wire up print support in id-ctrl and get/set-feature output. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add the Voltage Threshold (Feature ID 26h) and Voltage Measurement (Feature ID 27h) features, letting a host monitor the NVM subsystem's main voltage rail via up to 4 voltage sensors: programmable overvoltage/undervoltage thresholds with an AER one-shot event, and a Voltage Measurement log page (27h) tracking interval measurements against a configurable log threshold. CTRATT's VMS bit and the Feature/Log ID enum values were already present; this adds the underlying structures: 4 Voltage Sensor descriptors and MSVMT in Identify Controller, the Voltage Measurement log page, the Start Voltage Measurements data structure, the SMART Informative Warning byte (VLTHW), and the one-shot AER event. Wire up id-ctrl and SMART print support, and generic get/set-feature decode for both new features. The Voltage Measurement log page's detailed pretty-printer is left for a follow-up (falls back to the generic raw-log path for now). Note: several Voltage Sensor and log-page fields sit at byte offsets that aren't naturally 4-byte-aligned relative to their containing struct (a real spec quirk, not a transcription error), so those fields/structs use per-member or whole-struct __attribute__((packed)) to avoid the compiler silently inserting padding. Signed-off-by: Daniel Wagner <dwagner@suse.com>
There was a problem hiding this comment.
Pull request overview
Synchronizes libnvme and nvme-cli with NVMe Base Specification 2.4 and related command-set specifications.
Changes:
- Adds new protocol types, command initializers, feature fields, logs, and NVMe-MI PDA operations.
- Exposes new lockdown, sanitize, live-migration, and reporting functionality through the CLI.
- Updates tests, exported symbols, installation rules, and specification documentation.
Reviewed changes
Copilot reviewed 28 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/nvme-print-stdout.c |
Prints new controller, SMART, sanitize, voltage, and rate-limiting fields. |
src/nvme-print-json.c |
Adds JSON output for new controller, SMART, sanitize, and voltage fields. |
src/nvme-cmds-security.c |
Adds controller selection to Lockdown commands. |
src/nvme-cmds-sanitize.c |
Adds Purge Required support. |
README.md |
Links the specification coverage document. |
plugins/lm/lm-nvme.c |
Updates live-migration command construction. |
libnvme/tests/mi.c |
Updates MI command tests for new encodings. |
libnvme/tests/meson.build |
Registers new type tests. |
libnvme/tests/ioctl/misc.c |
Updates command-construction tests. |
libnvme/tests/ioctl/logs.c |
Updates log command tests. |
libnvme/src/nvme/util.c |
Adds string conversions for new values. |
libnvme/src/nvme/nvme-types.h |
Exposes the new command-set types. |
libnvme/src/nvme/nvme-types-zns.h |
Extends Zoned Namespace definitions. |
libnvme/src/nvme/nvme-types-slm.h |
Introduces Subsystem Local Memory types. |
libnvme/src/nvme/nvme-types-nvm.h |
Adds NVM 2.4-related structures and fields. |
libnvme/src/nvme/nvme-types-mi.h |
Adds NVMe-MI protocol definitions. |
libnvme/src/nvme/nvme-types-base.h |
Expands base-spec structures, enums, and bitfields. |
libnvme/src/nvme/nvme-cmds-nvm.h |
Adds NVM command initializers. |
libnvme/src/nvme/nvme-cmds-fabrics.h |
Adds Fabrics command helpers. |
libnvme/src/nvme/nvme-cmds-base.h |
Adds and extends base command initializers. |
libnvme/src/nvme/mi.h |
Declares new MI PDA APIs. |
libnvme/src/nvme/mi.c |
Implements MI PDA operations. |
libnvme/src/nvme/mi-types.h |
Extends internal MI message definitions. |
libnvme/src/meson.build |
Installs the new public header. |
libnvme/src/libnvme-mi.ld |
Exports new MI symbols. |
libnvme/examples/mi-mctp.c |
Displays additional MI port information. |
Documentation/SPEC-COVERAGE.md |
Adds chapter-level specification tracking. |
Documentation/nvme-sanitize.txt |
Documents Purge Required. |
Documentation/nvme-log-sanitize.txt |
Documents the Purged status bit. |
Documentation/nvme-lockdown.txt |
Documents controller selection options. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…4222) Add the Controller-scoped Command and Feature Lockdown capability (CCFLS bit in Identify Controller OACS), letting a host target a Lockdown command's prohibitions at a specific controller or the secondary controllers of a specific primary controller, instead of only the whole NVM subsystem. Adds the Controller Select (CSEL) field to the Lockdown command's Command Dword 10 and the corresponding Controller Select Specific (CSS) field to Command Dword 14, plus the Controller-scoped Enhanced Command and Feature Lockdown log page format (requested via the existing Log Specific Parameter/Identifier mechanism already used by other logs). Wire up the new --csel/--css flags on `nvme lockdown` and OACS print support. The Enhanced log page's pretty-printer is left for a follow-up, same as the Voltage Measurement log from TP4210. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add the Port Capabilities (PRTCAP) field to the Port Information Data Structure returned by the Read MI Data Structure command, exposing the CIAPS and AEMS bits that were previously part of an undecoded reserved byte. Wire up an AEMS print line in the mi-mctp example. Two other pieces of TP6042 are deliberately left out of scope: - The behavioral requirements for how a Management Endpoint responder handles malformed ROR/NMIMT/CIAP field values are responder-side protocol compliance rules; libnvme only implements the host (requester) side. - The new BPOPL bit lives in the Management Endpoint State data structure for the Get State command, which libnvme doesn't implement at all yet (a separate, larger, pre-existing gap predating this TP) — adding one bit to a structure/command that doesn't exist isn't actionable on its own. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Add enum nvme_mi_form_factor covering the full Form Factor value table (PCIe, Ethernet, and vendor-specific variants) used by the Upstream Connector Element Descriptor in the VPD Topology MultiRecord Area, including the new SFF-TA-1042 E2 9.5mm value this TP adds. The underlying Upstream Connector Element Descriptor structure didn't exist in libnvme at all — only the element-type tag did — so this also adds struct nvme_mi_vpd_usce for its fixed header fields; the trailing Upstream Port Descriptor list is implementation-specific sized per spec, so it's left as an opaque trailing array. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Adds the Rate Limiting Feature (28h) and log page (28h) that let a host limit the bandwidth and IOPS of a target (e.g. controller) in the NVM subsystem, along with the supporting OAES/AEC notification bit, async event notice value, and NVM command set specific Identify Controller Rate Limiting Attributes/Soft Limit Max Controllers fields. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Adds the CXL HDM Support Information (CHSI) field to the Identify Controller data structure and the new Host Addressable Namespaces log page (85h), which reports which SLM memory namespaces are accessible via PCIe BAR or CXL HDM host memory addressing. This seeds nvme-types-slm.h for the Subsystem Local Memory (SLM) Command Set (CSI 03h). The SLM command set itself (memory namespace Identify data structures, SLM Read/Write/Copy/Fill commands) remains unimplemented in libnvme; only the log page and Identify field this TP defines are added here. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Adds the NVMe-MI PDA Read (0Dh), PDA Write (0Eh), and PDA Write Zeroes (0Fh) commands for out-of-band access to the new optional Persistent Data Area, along with the Data Format (DFORMAT) enum and the PDA Size (PDAS) / Supported Data Format (SDFORMAT) fields on the 2-Wire Port Specific Data structure that advertise support and size. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Adds struct nvme_tdisp_device_interface_report and the TDISP Information (TI) bitfield enum describing the NVMe class-specific DEVICE_SPECIFIC_INFO payload returned by a PCIe TDISP GET_DEVICE_INTERFACE_REPORT request. Unlike other command-set gaps, no NVMe Admin, I/O, or MI command transfers this structure: it is produced by the device's Device Security Module and consumed by a platform TEE Security Module entirely through the PCIe TDISP protocol, outside any NVMe command/response path libnvme implements. This is added as a pure type definition for decoding a report obtained via some other TDISP/SPDM stack, with no corresponding libnvme command wrapper. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…lity (TP4195) Add Personality Identifier 03h on top of the Configurable Device Personality scaffolding, along with the rest of the Restore Manufacturing Default Settings capability it belongs to: - Personality Identifier 03h (Revert to Subsystem Manufacturing Settings), which uses no data buffer and no personality-specific command fields. - New Generic Command Status value 0x2D, Failed to Restore Configuration, returned when a restore operation cannot complete. - Identify Controller Restore Manufacturing Configuration Attributes (RMDCA, byte 362) with RDCCS/RDNCS/RDSCS support bits. - The new Manufacturer Default Configuration Status log page (Log Page Identifier 24h), reporting DCCS/DNCS/DSCS status bits. - Namespace Management gains a Restore Default Namespace Configuration operation (SEL 2h). - Capacity Management gains a Restore Default Capacity Management Configuration operation (OPER 5h); added enum nvme_capacity_mgmt_oper since no OPER values were previously named. Added command helpers for all three restore operations and CLI print support for RMDCA. Verified struct/field offsets with a standalone test program against the integrated Base Specification 2.4. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…ec 2.4) Figure 103 (Generic Command Status Values) defines 0x2B "Sanitize Namespace Failed" and 0x2C "Sanitize Namespace In Progress", referenced by the Namespace Sanitize Operation admin command restriction tables (Figure 145/146), but neither had a named constant in enum nvme_status_field. Signed-off-by: Daniel Wagner <dwagner@suse.com>
… Track Receive Gap analysis of Base Spec 2.4 chapter 5.2 found four Admin commands with opcodes defined but no nvme_init_* constructor, unlike every other command in this file: - Abort (5.2.1): adds nvme_init_abort() with CDW10 CID/SQID fields. - Asynchronous Event Request (5.2.2) and Keep Alive (5.2.15): trivial constructors, all command specific fields are reserved. - Track Receive (5.2.31): was asymmetric with Track Send, which already had a constructor. Adds nvme_init_lm_track_receive() plus the Tracked Memory Change Data Structure and descriptor types it returns (Figures 556-559), offsets verified against the spec with offsetof. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Deep gap analysis of Base Spec 2.4 section 5.2.12 (Get Features) found: - Abort (5.2.1) Figure 148 CQE Dword0 IANP bit had no representation: adds enum nvme_abort_cqe_dw0. - 17 of the 44 Feature Identifiers had no nvme_init_get_features_*/ nvme_init_set_features_* constructor, unlike every other feature in this file: Spinup Control, Power Loss Signaling Config, Flexible Data Placement, FDP Events, Namespace Admin Label, Configurable Device Personality, Power Limit, Power Threshold, Power Measurement, Voltage Threshold, Voltage Measurement, Embedded Management Controller Address, Host Management Agent Address, the three Host Metadata features, and Boot Partition Write Protection Config. These were reachable through the generic nvme_get_features()/ nvme_set_features() API and already wired into the CLI, so this closes an API-completeness gap in the typed constructor layer rather than a functional one. All of the per-feature CDW/CQE bitfield macros and data structures these constructors use already existed from earlier TP work; only the constructors themselves were missing. Added one new type, enum nvme_host_metadata_cdw11/_ea, for the Host Metadata GDHM/EA fields which had no representation at all. Verified struct sizes (nvme_mgmt_addr_desc, nvme_host_metadata, nvme_voltage_measurement_start_data) and the Voltage Threshold bit packing against the spec with a standalone test program. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Gap analysis of section 5.2.13 found the Log Page Identifier enum complete, but 4 of the log pages it defines had no nvme_init_get_log_* constructor: - Device Personalities (0x1D) and Voltage Measurement (0x27): the backing structs already existed from earlier TP work, only the constructors were missing. - Cross-Controller Reset (0x1E) and Lost Host Communication (0x1F): neither had any struct at all. Added struct nvme_cross_ctrl_reset_log/ _entry (with the Remove Completed log-specific-parameter bit and CCRS/CCRF status enums) and struct nvme_lost_host_comm_log/_entry, plus their constructors in nvme-cmds-fabrics.h alongside the other message-based-transport log pages (Discovery/Host Discovery/AVE Discovery) that already have working infrastructure there. Verified all new struct offsets against the spec's byte tables with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Gap analysis of section 5.2.14 (Identify command) found:
- enum nvme_identify_cns missing 2 values new in Base Spec 2.4:
NVME_IDENTIFY_CNS_UNDERLYING_CTRL_LIST (0x21) and
NVME_IDENTIFY_CNS_EXPORTED_NVM_SUBSYS_TEMPLATE_UUID_LIST (0x22).
- 6 CNS values had no nvme_init_identify_* constructor:
- 0x1D (Get Underlying Namespace List), 0x1E (Get Ports List), and
0x20 (Supported Controller State Formats) had no backing struct at
all despite predating 2.4. Added struct nvme_underlying_ns_list/
_entry, struct nvme_ports_list/nvme_fabrics_transport_entry, and
struct nvme_supported_ctrl_state_formats.
- 0x1F and 0x21 reuse existing structs (nvme_id_independent_id_ns,
nvme_ctrl_list respectively), only the constructor was missing.
- 0x22 gets a new, minimal UUID-list-only struct, consistent with
the "thinnest possible addition" used elsewhere for
Exported-NVM-Subsystem-adjacent decode-only types, without taking
on the larger deferred Exported NVM Subsystem feature itself.
Verified all new struct sizes and offsets against the spec's byte
tables with a standalone test program before committing.
Signed-off-by: Daniel Wagner <dwagner@suse.com>
Field-level audit of the Lockdown command found NVME_LOCKDOWN_CDW14_UIDX_MASK set to 0x3f (6 bits) instead of 0x7f (7 bits), the only outlier among every other UUID Index field in the codebase (Get Log Page, Identify, Set/Get Features all correctly use 0x7f per Figure 782). Truncated bit 6 of any UUID index >= 64 passed to nvme_init_lockdown(). Signed-off-by: Daniel Wagner <dwagner@suse.com>
Gap analysis of Base Spec 2.4 chapter 5.4 (Message-Based Transport Admin Commands) found: - Cross-Controller Reset (5.4.1, opcode 0x38): the admin command itself had no constructor (only its log page was added previously). Adds nvme_init_cross_ctrl_reset(), enum nvme_cross_ctrl_reset_cdw10, enum nvme_cross_ctrl_reset_cqe_dw0 (IRS/V/CLRI), and the 3 missing command-specific status codes 0x3F/0x40/0x41. - Discovery Information Management (5.4.2): already fully correct (nvme_init_dim_send's TAS field matches the spec exactly). No gap; its Extended Discovery Information Entry payload is deliberately left as a raw buffer, consistent with how other deeply-nested variable formats are handled elsewhere in this codebase. - Fabric Zoning Lookup/Receive/Send (5.4.3-5.4.5): none had a constructor. Adds all three, plus enum nvme_fabric_zoning_recv_cdw12/_cqe_dw0 and _send_cdw12. Status codes 0x30/0x31/0x33/0x34 already existed and are shared correctly across all three. - Manage Exported Port (5.4.6): deferred, part of the larger Exported NVM Subsystem family. - Send Discovery Log Page (5.4.7): no constructor. Adds nvme_init_send_discovery_log_page() plus enum nvme_send_discovery_log_page_rlps/_cdw10/_cqe_dw0. Verified all new bit-packed CDW10 fields against the spec's bit ranges before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Field-level dive into the remaining 5.2 commands that had only had a constructor-existence check so far (Capacity Management, Controller Data Queue, Device Self-test, Directive Send/Receive, Firmware Commit, Firmware Image Download, Format NVM, Namespace Attachment, Namespace Management, Security Send/Receive, Migration Send/Receive) found all of them correct except two real bugs: - NVME_SC_EXCEEDS_MAX_NS_SANITIZE was 0x3C instead of 0x12 (Figure 455). The dedicated libnvme_sanitize_ns_status_to_string() decoder could never match the real status a controller returns for this command. 0x12 is already used by NVME_SC_FW_NEEDS_MAX_TIME for Firmware Commit, but command specific status is scoped per opcode, so the numeric collision is expected and harmless - the two names are used in separate, command-specific decode paths, never the same switch statement. - nvme_init_lm_track_send() had no way to supply the data buffer required by the Track Memory Changes management operation when starting tracking (TACT set), making that operation uncallable. Added struct nvme_lm_track_memory_changes_data and struct nvme_lm_memory_range_tracking_descriptor (Figures 566/567), the TACT enum, and a data/len parameter pair on the constructor, updating its two existing call sites. The descriptor struct needs __attribute__((packed)): its natural 16-byte alignment would otherwise silently break the spec's tight 12-byte array stride, caught by offsetof()/sizeof() verification before committing. Migration Receive/Send's "Exported NVM Subsystem State" operations (SEL 1h/3h) remain deliberately unwired, consistent with the rest of the Exported NVM Subsystem family being out of scope for this pass. Signed-off-by: Daniel Wagner <dwagner@suse.com>
….2.4) First piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). This command has no command specific fields at all, so it's just an opcode with no data buffer - the smallest gap in that family. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Second piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). Implements the Create Exported NVM Subsystem management operation (SEL 00h), the first of the family's operations that needs to exist before any of the others (List/Get/Associate all operate on an already-created subsystem): - nvme_init_manage_export_nvms_receive(): generic constructor for the command, taking the SEL/MOS/MOSE/MOSI/offset/NUMDL fields shared across all 6 management operations this opcode supports. - nvme_init_manage_export_nvms_receive_create(): Create-specific wrapper (TR/ENSTI in Command Dword 11, RA in the message-based-only MOS field), plus struct nvme_exported_nvm_subsys_create_data for the 256-byte SUBNQN data buffer and the CQE Dword0 ESUBID decode. Verified the new struct's size against the spec with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Third piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). Implements the Delete management operation (SEL 01h): - nvme_init_manage_export_nvms_send(): generic constructor for the command, taking the SEL/MOS/MOSE (Command Dword 10) and ESUBIDV/ESUBID (Command Dword 14) fields shared across all 6 management operations this opcode supports. - nvme_init_manage_export_nvms_send_delete(): Delete-specific wrapper. The target Exported NVM Subsystem is identified either by ESUBID (Command Dword 14, no data buffer needed) or by SUBNQN in the data buffer, per the ESUBIDV bit - added struct nvme_exported_nvm_subsys_nqn_data for the latter case. - NVME_SC_CONTROLLER_ACTIVE (0x42): new command specific status code, shared between Delete and the not-yet-implemented Associate Controllers operation. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…(5.2.18) Fourth piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). Implements the 4 remaining SEL 01h-04h List operations, each reusing the nvme_init_manage_export_nvms_receive() base constructor added for Create: - List Exported NVM Subsystems (01h): struct nvme_exported_nvm_subsys_list/ _descriptor, starting point is the Exported NVM Subsystem Identifier in the MOSI field. - List Exported Namespaces (02h): struct nvme_exported_ns_list/_descriptor, starting point is the command's own NSID field (exclusive, unlike the other three which are inclusive). - List Exported Controllers (03h, message-based transports only): struct nvme_exported_ctrl_list/_descriptor, starting point is the Exported Controller Identifier in the MOSE field. - List Exported Ports (04h, memory-based transports only): struct nvme_exported_port_list/_descriptor, starting point is the Exported Port Identifier in the MOSE field. The Exported NVM Subsystem List Data Structure's byte-range table in the spec PDF is garbled by an extraction artifact (inconsistent stride between listed descriptor offsets); resolved by deriving the layout from the unambiguous single-descriptor figure instead (260 bytes: 256-byte NQN + 2 reserved + 2-byte identifier). Verified all 4 new descriptor and list-header struct sizes/offsets against the spec with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Fifth piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). Implements both management operations of this command (opcode 0x31): - nvme_init_manage_export_ns(): generic constructor, taking the SEL/MOS (Command Dword 10) and ESUBIDV/ESUBID (Command Dword 14) fields shared by both operations. - nvme_init_manage_export_ns_associate() / _disassociate(): operation specific wrappers, with struct nvme_associate_ns_data (576 bytes) and struct nvme_disassociate_ns_data (320 bytes) for their data buffers. The Associate/Disassociate Namespace Data Structure figures in the spec PDF label their offset column "Bits" but the numbers are actually byte offsets - confirmed by cross-checking the two 256-byte NQN fields (ENSNQN, UNSNQN), which only make sense as byte counts. Verified both struct layouts against the spec with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…(5.2.19) Sixth piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory). Implements the 5 remaining SEL operations, completing this command: - Change Access Mode (02h, message-based only): RA bit in the MOS field, reuses struct nvme_exported_nvm_subsys_nqn_data from Delete for the identify-by-NQN case. - Grant Host Access (03h) / Revoke Host Access (04h, message-based only): share struct nvme_exported_subsys_mgmt_data, a 256-byte header (NUMHENT/NUMENSE counts) followed by two back-to-back variable-length lists (struct nvme_exported_subsys_mgmt_host_entry, struct nvme_exported_subsys_mgmt_subsys_entry, 320 bytes each) - left as a raw trailing byte buffer since C can't express two differently-sized variable-length lists as fixed struct members. New status codes NVME_SC_INVALID_HOST (0x35) and NVME_SC_INVALID_NVM_SUBSYSTEM (0x36). - Associate Controllers (05h, memory-based only): struct nvme_exported_ctrl_assoc_data/_descriptor. New status code NVME_SC_INVALID_EXPORTED_ASSOCIATION (0x43). - Set Exported Configuration State (06h): data buffer format is Exported NVM Subsystem Template specific, left as an opaque buffer matching the established pattern for other template-defined payloads. New status code NVME_SC_INVALID_EXPORTED_CONFIG_STATE (0x44) and its CQE Dword0 BITLOC/DWLOC decode. Verified all new struct sizes/offsets against the spec with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Final piece of the deferred Exported NVM Subsystem command family (see plan_exported_nvm_subsystem_family in project memory) - this completes the whole family and, with it, the entire Base Spec 2.4 chapter 5 (Admin Command Set) gap analysis. Implements both management operations of this message-based-transport- only command (opcode 0x35): - nvme_init_manage_export_port(): generic constructor for the SEL/MOS fields shared by both operations. - nvme_init_manage_export_port_create(): GEPID bit in the MOS field, struct nvme_exported_port_create_data (320 bytes: SUBNQN, EPID, PIDUD, TRSVCID) and the CQE Dword0 EPID decode for controller-assigned IDs. - nvme_init_manage_export_port_delete(): struct nvme_exported_port_delete_data (320 bytes: SUBNQN, EPID). Placed in nvme-cmds-fabrics.h alongside the other message-based- transport-only commands added earlier in this audit (Cross-Controller Reset, Fabric Zoning, Send Discovery Log Page). Verified both struct sizes/offsets against the spec with a standalone test program before committing. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Gap analysis of Base Spec 2.4 chapters 6 (Fabrics Command Set) and 7 (I/O Commands) found both largely complete already: - Chapter 6: all 6 Fabrics Command Types present and correct. Property Get/Set and Authentication Send/Receive verified field-correct. Connect/Disconnect are implemented as full connection-management functions in fabrics.c rather than simple passthru constructors, appropriate given they manage queue/connection lifecycle. - Chapter 7: opcode table complete (8/8). Flush, I/O Management Receive/Send, and all 4 Reservation commands were already fully correct, including the newer Dispersed Namespace Reservation Support (DISNSRS) bit. One real gap: the Cancel command (opcode 0x18) had no constructor at all. Adds nvme_init_cancel(), enum nvme_cancel_acode (Command Dword 11 Action Code), the Command Dword 10 CID/SQID fields, the CQE Dword0 CEDA/CMDA decode, and NVME_SC_INVALID_CMD_ID (0x84) - a command specific status code that was entirely unnamed despite the same numeric value already being used, correctly, by three other command-scoped status constants (command specific status is scoped per opcode, so the reuse is expected). Signed-off-by: Daniel Wagner <dwagner@suse.com>
…stics NVM Command Set Spec 1.3 section 4.1.3.8 (Feature Identifier 1Ch) had no nvme_init_get_features_perf_characteristics()/nvme_init_set_features_perf_characteristics() wrappers, even though the CDW11 bitfield macros, decode helper, and data structures (struct nvme_perf_characteristics and friends) already existed. Signed-off-by: Daniel Wagner <dwagner@suse.com>
NVM Command Set Spec 1.3 Figure 116 (Media Reallocated Event Type Specific Data Structure) packs the 8-byte LBA field at byte offset 4, right after the 2-byte NLBAM field, for a total structure size of 16 bytes matching the FDP Event's type_specific[16] field. Without __attribute__((packed)), natural alignment pads __le64 lba to offset 8, growing the struct to 24 bytes and misplacing every field after NLBAM relative to the real on-the-wire layout. Signed-off-by: Daniel Wagner <dwagner@suse.com>
…S decode NVM Command Set Spec 1.3 Figure 123 (Identify Namespace Data Structure) defines NSFEAT bit 6 (Multiple Atomicity Mode, MAM) and bit 7 (Optional Read Performance, OPTRPERF) which were entirely missing from enum nvme_id_nsfeat. enum nvme_id_ns_mc's two doc comments were swapped relative to their bit values: NVME_NS_MC_EXTENDED (bit 0) was documented as the separate buffer bit and NVME_NS_MC_SEPARATE (bit 1) as the extended LBA bit, backwards from Figure 123's MTELBAS/MTSBS definitions. The struct nvme_id_ns.kpios field (Key Per I/O Status) had no shift/mask decode enum at all, unlike every other bitfield byte in the struct and unlike the analogous controller-level KPIOC field which already has one. Signed-off-by: Daniel Wagner <dwagner@suse.com>
NVM Command Set Spec 1.3 Figure 129 (I/O Command Set Specific Identify Controller Data Structure) defines bitfields for the Key Per I/O Capabilities (KPIOCAP: KPIOS bit0, KPIOSC bit1) and Admin Optional Command Support (AOCS: RALBAS bit0) fields, but struct nvme_id_ctrl_nvm had no shift/mask decode enums for either, unlike every other multi-bit field in the struct (e.g. RLA already has one). Signed-off-by: Daniel Wagner <dwagner@suse.com>
NVM Command Set Spec 1.3 section 4.1.5.8 / Figure 132 allows up to 64 Namespace Granularity descriptors when the LBA Format Extension Enable (LBAFEE) field is set in the Host Behavior Support feature, but NVME_ID_ND_DESCRIPTOR_MAX was hardcoded to 16 (the pre-LBAFEE limit). Consumers (nvme-print-stdout.c, nvme-print-json.c) iterate up to glist->num_descriptors, a device-reported 0's based value with no bound to the old 16-entry array, so a device reporting more than 16 descriptors caused an out-of-bounds read of struct nvme_id_ns_granularity_list.entry[]. Bumped the array to 64 entries and shrank the trailing reserved region accordingly to keep the struct at the required 4096 bytes. Signed-off-by: Daniel Wagner <dwagner@suse.com>
NVM Command Set Spec 1.3 Figure 140 (LBA Status Descriptor Entry) defines the LBA Range Status (LBARS) field as bits 2:0 of the Status byte, with four defined values (000b-011b), but there was no shift/mask/value enum for it, unlike the sibling completion-condition field which already has enum nvme_lba_status_cmpc. Signed-off-by: Daniel Wagner <dwagner@suse.com>
ZNS Command Set Spec Figure 38 (Zone Descriptor Data Structure) packs Zone Type (ZT) into bits 3:0 of the zt byte, Zone State (ZS) into bits 7:4 of the zs byte, and Reset/Finish Zone Recommended Time Limit (RZRTL/FZRTL) into bits 3:2/1:0 of the zai byte, but none of these had shift/mask decode enums or macros. Callers were expected to know the magic ">> 4" shift for ZS themselves (nvme-cli's print code does this correctly, but nothing in libnvme documented or provided it), and the ZT/RZRTL/FZRTL bitfields had no decode support at all despite being read directly as raw bytes elsewhere. Signed-off-by: Daniel Wagner <dwagner@suse.com>
ZNS Command Set Spec Figure 42 defines the Zone Capacity Changed (ZCC) bit in Completion Queue Entry Dword 0 for the Zone Management Send command, but there was no decode enum/macro for it at all. Signed-off-by: Daniel Wagner <dwagner@suse.com>
ZNS Command Set Spec Figure 43 (Asynchronous Event Information - Notice, Zoned Namespace Command Set) defines value EFh for the Zone Descriptor Changed event, but enum nvme_ae_info_notice had no entry for it despite already having NVME_FEAT_AE_ZDCN (the corresponding Set Features enable bit) and NVME_LOG_LID_ZNS_CHANGED_ZONES (the log page it's paired with). Signed-off-by: Daniel Wagner <dwagner@suse.com>
ZNS Command Set Spec Rev 1.5 Figure 51 (I/O Command Set Specific Identify Controller Data Structure for the Zoned Namespace Command Set) defines Zoned Controller Attributes (ZCTRATT), Total/Unallocated Active/Open/ZRWA Resources (TAR/UAR/TOR/UOR/TZRWAR/UZRWAR), and a Version (VER) field at bytes 4-35, none of which existed in struct nvme_zns_id_ctrl -- it only had zasl followed by 4095 bytes of reserved. This header's DOC comment still claimed to target Revision 1.4; these fields were added by an ECN folded into 1.5. Also added decode enums for the ZOC (VZC/ZAE), OZCS (RAZB/ZRWASUP), and ZRWACAP (EXPFLUSHSUP) bitfields in nvme_zns_id_ns -- nvme-cli's print code already hand-decoded these bits correctly (show_nvme_id_ns_zoned_zoc/ozcs, stdout_zns_id_ns_zrwacap) but libnvme itself provided no shift/mask macros for them. Signed-off-by: Daniel Wagner <dwagner@suse.com>
ZNS Command Set Spec Figure 54 (I/O Namespace Management - Host Specific Fields) defines the Allocate ZRWA Resources (AZR) bit in the znsco byte, but there was no enum for it despite the field already being documented in the struct's doc comment. Signed-off-by: Daniel Wagner <dwagner@suse.com>
Track which chapters of each NVMe specification have been verified field-by-field against libnvme, and when, so future audits know what is already covered. Signed-off-by: Daniel Wagner <dwagner@suse.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bring the libnvme APIs in sync with the base spec version v2.4 (and associated sub specs). Obviously, this is done by AI.
I started to reviewed the commits and so far all looks very sane and consistent. It found real bugs in the spec and also in the implementation, e.g.
Given it almost doesn't change existing code, only adds the missing pieces the regression risk is low.
Fixes: #3774