* [PATCH v2 0/2] ACPI: sysfs: Expose BDAT data region
@ 2026-10-12 23:06 Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 1/2] ACPI: sysfs: Fix data_attr leak when creating a data file fails Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
0 siblings, 2 replies; 6+ messages in thread
From: Jamie Nguyen @ 2026-10-12 23:06 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Tony Luck, Punit Agrawal, linux-acpi, linux-kernel
The BIOS Data ACPI Table (BDAT) points to a firmware data structure that
carries memory training results and other boot-time data. Patch 2 exposes
that data as /sys/firmware/acpi/tables/data/BDAT, like the existing BERT
and CCEL data files.
Patch 1 fixes a leak in the existing data file code, where data_attr is
not freed if sysfs_create_bin_file() fails. It moves the file creation and
the cleanup into acpi_table_data_init(), and patch 2 builds on that.
Changes in v2:
- New patch 1, fixing the data_attr leak for BERT and CCEL as well.
- Patch 2: the BDAT callback only checks the table and sets the address
and size of the data, and returns -ENOMEM if mapping the header fails.
v1: https://lore.kernel.org/r/20261009232955.866131-1-jamien@nvidia.com
Tested on an arm64 server (64K pages):
- The file matches a /dev/mem dump of the data region taken in the same
boot, byte for byte, and decodes with valid CRCs.
- With lockdown=integrity, /dev/mem is refused and the file still reads.
- Malformed BDAT tables loaded via initrd table upgrade (test-only change
adding BDAT to table_sigs[]) are rejected without creating a file: no
"BDATHEAD" signature, size below the header, non-memory address space,
zero address, and a table shorter than struct acpi_table_bdat.
- With a test-only change that makes sysfs_create_bin_file() fail with
-EEXIST for one BDAT table, kmemleak reports its data_attr as leaked
without patch 1, and the data_attr is freed with patch 1 applied.
Jamie Nguyen (2):
ACPI: sysfs: Fix data_attr leak when creating a data file fails
ACPI: sysfs: Expose BDAT data region
Documentation/ABI/testing/sysfs-firmware-acpi | 12 ++++
drivers/acpi/sysfs.c | 69 ++++++++++++++++---
2 files changed, 71 insertions(+), 10 deletions(-)
base-commit: af32da41b0327b9c6a37856ba82b6760d6c8d10e
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] ACPI: sysfs: Fix data_attr leak when creating a data file fails
2026-10-12 23:06 [PATCH v2 0/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
@ 2026-10-12 23:06 ` Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
1 sibling, 0 replies; 6+ messages in thread
From: Jamie Nguyen @ 2026-10-12 23:06 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Tony Luck, Punit Agrawal, linux-acpi, linux-kernel
acpi_table_data_init() allocates the data_attr for a table's data file
and passes it to the table's init callback. The BERT and CCEL callbacks
free data_attr when the table is invalid, but return the result of
sysfs_create_bin_file() directly, so data_attr is leaked if creating the
file fails.
Create the file and free data_attr on failure in acpi_table_data_init()
instead, so that the callbacks only check the table and set the address
and size of the data.
Fixes: 7dae6326ed76 ("ACPI / sysfs: Extend ACPI sysfs to provide access to boot error region")
Assisted-by: LLM
Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
---
drivers/acpi/sysfs.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index dd4a99f09efea65..ae3b3ee0552d198 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -448,14 +448,13 @@ static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
struct acpi_table_bert *bert = th;
if (bert->header.length < sizeof(struct acpi_table_bert) ||
- bert->region_length < sizeof(struct acpi_bert_region)) {
- kfree(data_attr);
+ bert->region_length < sizeof(struct acpi_bert_region))
return -EINVAL;
- }
+
data_attr->addr = bert->address;
data_attr->attr.size = bert->region_length;
- return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
+ return 0;
}
static int acpi_ccel_data_init(void *th, struct acpi_data_attr *data_attr)
@@ -463,14 +462,13 @@ static int acpi_ccel_data_init(void *th, struct acpi_data_attr *data_attr)
struct acpi_table_ccel *ccel = th;
if (ccel->header.length < sizeof(struct acpi_table_ccel) ||
- !ccel->log_area_start_address || !ccel->log_area_minimum_length) {
- kfree(data_attr);
+ !ccel->log_area_start_address || !ccel->log_area_minimum_length)
return -EINVAL;
- }
+
data_attr->addr = ccel->log_area_start_address;
data_attr->attr.size = ccel->log_area_minimum_length;
- return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
+ return 0;
}
static struct acpi_data_obj {
@@ -486,7 +484,7 @@ static struct acpi_data_obj {
static int acpi_table_data_init(struct acpi_table_header *th, struct acpi_table_attr *table_attr)
{
struct acpi_data_attr *data_attr;
- int i;
+ int i, ret;
for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) {
if (ACPI_COMPARE_NAMESEG(th->signature, acpi_data_objs[i].name)) {
@@ -498,7 +496,13 @@ static int acpi_table_data_init(struct acpi_table_header *th, struct acpi_table_
data_attr->attr.attr.mode = 0400;
strscpy(data_attr->filename, table_attr->filename);
data_attr->attr.attr.name = data_attr->filename;
- return acpi_data_objs[i].fn(th, data_attr);
+ ret = acpi_data_objs[i].fn(th, data_attr);
+ if (!ret)
+ ret = sysfs_create_bin_file(tables_data_kobj,
+ &data_attr->attr);
+ if (ret)
+ kfree(data_attr);
+ return ret;
}
}
return 0;
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region
2026-10-12 23:06 [PATCH v2 0/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 1/2] ACPI: sysfs: Fix data_attr leak when creating a data file fails Jamie Nguyen
@ 2026-10-12 23:06 ` Jamie Nguyen
2026-10-13 2:12 ` Jamie Nguyen
1 sibling, 1 reply; 6+ messages in thread
From: Jamie Nguyen @ 2026-10-12 23:06 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Tony Luck, Punit Agrawal, linux-acpi, linux-kernel
The BIOS Data ACPI Table (BDAT) points to a firmware data structure that
carries memory training results and other boot-time data. The table is
only a pointer: /sys/firmware/acpi/tables/BDAT holds the ACPI header and
a Generic Address Structure, and the data itself lives in reserved
memory.
Expose the data as /sys/firmware/acpi/tables/data/BDAT, as is already
done for BERT and CCEL. Unlike those tables, BDAT carries no length, so
check the "BDATHEAD" signature at the start of the data structure and
take the size from its BiosDataStructSize field. Reject sizes smaller
than that header, and document the new file in Documentation/ABI.
The BDAT specification is published by the UEFI Forum [1].
Link: https://uefi.org/sites/default/files/resources/BDAT_Spec_v4_0_9%20%282%29.pdf # [1]
Assisted-by: LLM
Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
---
Documentation/ABI/testing/sysfs-firmware-acpi | 12 +++++
drivers/acpi/sysfs.c | 45 +++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi
index fa33dda331f2440..5fb50a72d468f5c 100644
--- a/Documentation/ABI/testing/sysfs-firmware-acpi
+++ b/Documentation/ABI/testing/sysfs-firmware-acpi
@@ -275,3 +275,15 @@ Description:
remote_region_id: ID associated with access by agents
non-local to this range of addresses.
+
+What: /sys/firmware/acpi/tables/data/BDAT
+Date: October 2026
+Contact: Jamie Nguyen <jamien@nvidia.com>
+Description:
+ The BIOS data structure referenced by the ACPI BDAT (BIOS Data
+ ACPI Table). It starts with a "BDATHEAD" header and holds data
+ published by firmware, such as memory training results. The
+ file size is the structure size given in that header.
+
+ The format is defined by the BDAT Interface Specification,
+ published by the UEFI Forum. The file is readable by root only.
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index ae3b3ee0552d198..7581bb73df8222d 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -471,12 +471,57 @@ static int acpi_ccel_data_init(void *th, struct acpi_data_attr *data_attr)
return 0;
}
+/*
+ * The BDAT table only holds the address of the BIOS data structure. Its
+ * size is in the structure's own header ("BDAT Interface Specification"
+ * v4.0, section 4).
+ */
+struct acpi_bdat_data_header {
+ char signature[8]; /* "BDATHEAD" */
+ u32 size; /* whole structure, including this header */
+ u16 crc16;
+ u16 reserved;
+ u16 primary_version;
+ u16 secondary_version;
+ u32 oem_offset;
+ u32 reserved1;
+ u32 reserved2;
+} __packed;
+
+static int acpi_bdat_data_init(void *th, struct acpi_data_attr *data_attr)
+{
+ struct acpi_table_bdat *bdat = th;
+ struct acpi_bdat_data_header hdr;
+ void __iomem *base;
+
+ if (bdat->header.length < sizeof(struct acpi_table_bdat) ||
+ bdat->gas.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY ||
+ !bdat->gas.address)
+ return -EINVAL;
+
+ base = acpi_os_map_iomem(bdat->gas.address, sizeof(hdr));
+ if (!base)
+ return -ENOMEM;
+ memcpy_fromio(&hdr, base, sizeof(hdr));
+ acpi_os_unmap_iomem(base, sizeof(hdr));
+
+ if (memcmp(hdr.signature, "BDATHEAD", sizeof(hdr.signature)) ||
+ hdr.size < sizeof(hdr))
+ return -EINVAL;
+
+ data_attr->addr = bdat->gas.address;
+ data_attr->attr.size = hdr.size;
+
+ return 0;
+}
+
static struct acpi_data_obj {
char *name;
int (*fn)(void *, struct acpi_data_attr *);
} acpi_data_objs[] = {
{ ACPI_SIG_BERT, acpi_bert_data_init },
{ ACPI_SIG_CCEL, acpi_ccel_data_init },
+ { ACPI_SIG_BDAT, acpi_bdat_data_init },
};
#define NUM_ACPI_DATA_OBJS ARRAY_SIZE(acpi_data_objs)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region
2026-10-12 23:06 ` [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
@ 2026-10-13 2:12 ` Jamie Nguyen
2026-10-13 10:53 ` Rafael J. Wysocki (Intel)
0 siblings, 1 reply; 6+ messages in thread
From: Jamie Nguyen @ 2026-10-13 2:12 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Tony Luck, Punit Agrawal, linux-acpi, linux-kernel
The Sashiko review of this patch [1] notes that acpi_data_show() maps
the whole data region on every read(), and that the unmaps are deferred
by RCU, so repeated reads could pile up mappings and exhaust vmalloc
space.
That code isn't changed by this series. acpi_data_show() has mapped the
whole region on every read since BERT support was added in 7dae6326ed76
("ACPI / sysfs: Extend ACPI sysfs to provide access to boot error
region"), and BERT and CCEL use the same path.
I measured it with v2 on an arm64 server, with 4K and 64K pages and the
90754-byte BDAT region:
- Looping full-file reads, with 1 to 64 readers, kept at most about 4500
deferred mappings (426 MiB) in flight. The count stayed flat and went
back to baseline within 2 s of stopping.
- The worst case, tight loops of 1-byte reads, peaked at about 34k
mappings and 4.6 GiB of address space, and also drained within 2 s.
At those rates, exhausting the 126 TiB of vmalloc space would need the
deferred unmaps to stop completing for more than half an hour.
If it's worth tightening anyway, acpi_data_show() could map only the
range being read, which caps each mapping at two pages for all three
tables. I can send that as a separate patch.
[1] https://sashiko.dev/#/patchset/20261012230632.3574987-1-jamien%40nvidia.com
Jamie
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region
2026-10-13 2:12 ` Jamie Nguyen
@ 2026-10-13 10:53 ` Rafael J. Wysocki (Intel)
2026-10-13 18:11 ` Jamie Nguyen
0 siblings, 1 reply; 6+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-10-13 10:53 UTC (permalink / raw)
To: Jamie Nguyen
Cc: Rafael J. Wysocki, Len Brown, Tony Luck, Punit Agrawal,
linux-acpi, linux-kernel
On Tue, Oct 13, 2026 at 4:13 AM Jamie Nguyen <jamien@nvidia.com> wrote:
>
> The Sashiko review of this patch [1] notes that acpi_data_show() maps
> the whole data region on every read(), and that the unmaps are deferred
> by RCU, so repeated reads could pile up mappings and exhaust vmalloc
> space.
>
> That code isn't changed by this series. acpi_data_show() has mapped the
> whole region on every read since BERT support was added in 7dae6326ed76
> ("ACPI / sysfs: Extend ACPI sysfs to provide access to boot error
> region"), and BERT and CCEL use the same path.
>
> I measured it with v2 on an arm64 server, with 4K and 64K pages and the
> 90754-byte BDAT region:
>
> - Looping full-file reads, with 1 to 64 readers, kept at most about 4500
> deferred mappings (426 MiB) in flight. The count stayed flat and went
> back to baseline within 2 s of stopping.
> - The worst case, tight loops of 1-byte reads, peaked at about 34k
> mappings and 4.6 GiB of address space, and also drained within 2 s.
>
> At those rates, exhausting the 126 TiB of vmalloc space would need the
> deferred unmaps to stop completing for more than half an hour.
>
> If it's worth tightening anyway, acpi_data_show() could map only the
> range being read, which caps each mapping at two pages for all three
> tables. I can send that as a separate patch.
Yes, please!
> [1] https://sashiko.dev/#/patchset/20261012230632.3574987-1-jamien%40nvidia.com
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region
2026-10-13 10:53 ` Rafael J. Wysocki (Intel)
@ 2026-10-13 18:11 ` Jamie Nguyen
0 siblings, 0 replies; 6+ messages in thread
From: Jamie Nguyen @ 2026-10-13 18:11 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Tony Luck, Punit Agrawal, linux-acpi, linux-kernel
On Tue, Oct 13, 2026 at 3:53 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > If it's worth tightening anyway, acpi_data_show() could map only the
> > range being read, which caps each mapping at two pages for all three
> > tables. I can send that as a separate patch.
>
> Yes, please!
Posted here:
https://lore.kernel.org/r/20261013180728.957618-1-jamien@nvidia.com
Jamie
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-13 18:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 23:06 [PATCH v2 0/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 1/2] ACPI: sysfs: Fix data_attr leak when creating a data file fails Jamie Nguyen
2026-10-12 23:06 ` [PATCH v2 2/2] ACPI: sysfs: Expose BDAT data region Jamie Nguyen
2026-10-13 2:12 ` Jamie Nguyen
2026-10-13 10:53 ` Rafael J. Wysocki (Intel)
2026-10-13 18:11 ` Jamie Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®