Repository navigation
feat(hii): read the HII database from the HIID ACPI table - #26
Conversation
Linux exposes no file that holds the HII database, and /sys/firmware/efi/systab does not list its address, so extract_db() reads the address from the OCP HiiDB efivar and then the memory from /dev/mem. That fails where /dev/mem cannot reach the database (aarch64, whose EFI runtime memory is nomap) and a UEFI variable copy is limited by one efivarfs read to about 4 MB. Try the vendor ACPI table "HIID" first: its body after the 36-byte ACPI header is the HII database, read from /sys/firmware/acpi/tables/HIID with no /dev/mem. When the table is missing or unreadable, print the reason to stderr and fall back to the OCP variable and /dev/mem as before. Document both ways in the README. Tested: cargo build.
|
@rybackhung : Huge thanks for the contribution! Would you also like to share the EFI System Table patch? :) |
|
@xaionaro That is also my preferred approach, as it aligns with the UEFI specification and the edk2 implementation. Unfortunately, the Linux kernel does not yet expose the HII Database through a userspace interface (e.g., In practice, this approach works on x86 systems but fails on aarch64 systems (NVIDIA Grace platforms) because EFI runtime memory is marked as Neither |
|
@rybackhung : I actually tried your patch for systab (adapted a bit with claude) on some of the hosts, and it worked. I believe that was a useful change :) |
Upstream's dd60b6c (PR #26, #26) reads the vendor ACPI table HIID whole, without a size cap. The table has no public spec; its body after the 36-byte ACPI header is the HII database. extract_db_acpi now reads the table through read_db_bytes, which caps it at MAX_ALLOWED_FILESIZE. extract_db takes the configuration table's, the HIID table's, the OCP HiiDB variable's and /dev/mem's paths from HiiSourcePaths, so that unit tests read files of their own; it still tries the configuration table first, then the HIID table. HIIDB_ACPI_PATH's comment cites Linux v6.11 drivers/char/mem.c:612 and claims no efivarfs read limit. Test Plan: cargo clippy --all-targets -- -D warnings and cargo test --lib: pass, with a new test for the table read. Signed-off-by: Dmitrii Okunev <xaionaro@meta.com>
extract_db read only HIID, the table that upstream's PR #26 reads. Vendor firmware publishes the HII database in an ACPI table with no public spec: a vendor EDK2 driver names it QHII, and its earlier revision named it HIID. extract_db now reads the vendor ACPI table QHII or HIID, each from /sys/firmware/acpi/tables/<signature> by its exact name and checked against its own signature. The tables are equal; it tries them in that fixed order only so that its result is deterministic. It moves on past a table that is absent or fails its checks: its header, checksum or structure, or its length over MAX_ALLOWED_FILESIZE (TooLong), none of which reads memory. It stops at any other error, such as EACCES, before a later table. With no table read, the error is AcpiTablesInvalid, which names each table with its error; extract_db then reads the OCP HiiDB efivar, as before. The debug log names the table read and each table skipped. The EFI configuration table's fallback reason now ends "falling back to the HII ACPI tables". HiidInvalid and validate_hiid_table, which now check either table, become AcpiTableInvalid and validate_acpi_table, and read_db_bytes' error for a file over MAX_ALLOWED_FILESIZE is typed (DbFileTooBig) and says "longer than its maximum of 16777216 bytes". publish-hiidb's acpi-table now installs a QHII table, the ACPI table extract_db tries first, so the scenario hii-acpi, and the comments and tests that describe that table, name QHII; it gets the modes acpi-table-hiid and acpi-table-junk-qhii, for the QEMU scenarios hii-acpi-hiid and hii-acpi-two-tables. Test Plan: - Unit tests: every check of a table, a signature that differs in its last byte included, holds for each signature; hii_db_published sees each table and fails when it cannot check one. - cargo clippy --all-targets -- -D warnings on x86_64, i686 and aarch64, and --lib --bins on the macOS targets; cargo clippy -p uefisettings-qemu-guest --all-targets --all-features and publish-hiidb's for x86_64-unknown-uefi, -D warnings; cargo test --lib --bins; cargo fmt --check. Signed-off-by: Dmitrii Okunev <xaionaro@meta.com>
Linux exposes no file that holds the HII database, and /sys/firmware/efi/systab does not list its address, so extract_db() reads the address from the OCP HiiDB efivar and then the memory from /dev/mem. That fails where /dev/mem cannot reach the database (aarch64, whose EFI runtime memory is nomap) and a UEFI variable copy is limited by one efivarfs read to about 4 MB.
Try the vendor ACPI table "HIID" first: its body after the 36-byte ACPI header is the HII database, read from
/sys/firmware/acpi/tables/HIID with no /dev/mem. When the table is missing or unreadable, print the reason to stderr and fall back to the OCP variable and /dev/mem as before.
Document both ways in the README.
Tested: cargo build.