[PATCH v5 1/3] bloblist: add api to get blob with size

bloblist_find function only returns the pointer of blob data, which is fine for those self-describing data like FDT. But as a common scenario, an interface is needed to retrieve both the pointer and the size of the blob data.
Add a few ut test cases for the new api.
Signed-off-by: Raymond Mao raymond.mao@linaro.org Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- Changes in v2 - Rename function argument. - Add ut tests. Changes in v3 - None. Changes in v4 - None. Changes in v5 - None.
common/bloblist.c | 17 +++++++++++++++-- include/bloblist.h | 18 ++++++++++++++++++ test/common/bloblist.c | 4 ++++ 3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 110bb9dc44..ab48a3cdb9 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -222,14 +222,27 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, }
void *bloblist_find(uint tag, int size) +{ + void *blob = NULL; + int blob_size; + + blob = bloblist_get_blob(tag, &blob_size); + + if (size && size != blob_size) + return NULL; + + return blob; +} + +void *bloblist_get_blob(uint tag, int *sizep) { struct bloblist_rec *rec;
rec = bloblist_findrec(tag); if (!rec) return NULL; - if (size && size != rec->size) - return NULL; + + *sizep = rec->size;
return (void *)rec + rec_hdr_size(rec); } diff --git a/include/bloblist.h b/include/bloblist.h index f999391f74..52ba0ddcf8 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -250,6 +250,24 @@ static inline void *bloblist_check_magic(ulong addr) return ptr; }
+#if CONFIG_IS_ENABLED(BLOBLIST) +/** + * bloblist_get_blob() - Find a blob and get the size of it + * + * Searches the bloblist and returns the blob with the matching tag + * + * @tag: Tag to search for (enum bloblist_tag_t) + * @sizep: Size of the blob found + * Return: pointer to bloblist if found, or NULL if not found + */ +void *bloblist_get_blob(uint tag, int *sizep); +#else +static inline void *bloblist_get_blob(uint tag, int *sizep) +{ + return NULL; +} +#endif + /** * bloblist_find() - Find a blob * diff --git a/test/common/bloblist.c b/test/common/bloblist.c index 4bca62110a..324127596f 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -98,10 +98,12 @@ static int bloblist_test_blob(struct unit_test_state *uts) struct bloblist_hdr *hdr; struct bloblist_rec *rec, *rec2; char *data; + int size = 0;
/* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); + ut_assertnull(bloblist_get_blob(TEST_TAG, &size)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); @@ -114,6 +116,8 @@ static int bloblist_test_blob(struct unit_test_state *uts) ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); ut_asserteq_addr(rec + 1, data); + ut_asserteq_addr(bloblist_get_blob(TEST_TAG, &size), data); + ut_asserteq(size, TEST_SIZE);
/* Check the data is zeroed */ ut_assertok(check_zero(data, TEST_SIZE));

Move default eventlog size from efi to tpm for using in both efi and measured boot.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v5 - Move eventlog size kconfig from EFI to TPM2, so that it can be used by both EFI and MEASURED_BOOT.
doc/usage/measured_boot.rst | 1 - drivers/tpm/Kconfig | 9 +++++++++ include/efi_tcg2.h | 2 -- lib/efi_loader/Kconfig | 9 --------- lib/efi_loader/efi_tcg2.c | 15 ++++++++------- 5 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst index 05c439e9ac..488dd546f1 100644 --- a/doc/usage/measured_boot.rst +++ b/doc/usage/measured_boot.rst @@ -24,7 +24,6 @@ Requirements
* A hardware TPM 2.0 supported by an enabled U-Boot driver * CONFIG_EFI_TCG2_PROTOCOL=y -* CONFIG_EFI_TCG2_PROTOCOL_EVENTLOG_SIZE=y * optional CONFIG_EFI_TCG2_PROTOCOL_MEASURE_DTB=y will measure the loaded DTB in PCR 1
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig index d59102d9a6..01bc686d36 100644 --- a/drivers/tpm/Kconfig +++ b/drivers/tpm/Kconfig @@ -209,6 +209,15 @@ config TPM2_MMIO to the device using the standard TPM Interface Specification (TIS) protocol.
+config TPM2_EVENT_LOG_SIZE + int "EventLog size" + depends on TPM_V2 + default 65536 + help + Define the size of the EventLog. Note that this is going to be + allocated twice. One for the eventlog it self and one for the + configuration table that is required from the TCG2 spec + endif # TPM_V2
endmenu diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index 8dfb1bc952..7ed8880991 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -28,8 +28,6 @@ #define EFI_TCG2_MAX_PCR_INDEX 23 #define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
-#define TPM2_EVENT_LOG_SIZE CONFIG_EFI_TCG2_PROTOCOL_EVENTLOG_SIZE - typedef u32 efi_tcg_event_log_bitmap; typedef u32 efi_tcg_event_log_format; typedef u32 efi_tcg_event_algorithm_bitmap; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c46ffe3a9d..d703e901ed 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -437,15 +437,6 @@ config EFI_TCG2_PROTOCOL Provide a EFI_TCG2_PROTOCOL implementation using the TPM hardware of the platform.
-config EFI_TCG2_PROTOCOL_EVENTLOG_SIZE - int "EFI_TCG2_PROTOCOL EventLog size" - depends on EFI_TCG2_PROTOCOL - default 65536 - help - Define the size of the EventLog for EFI_TCG2_PROTOCOL. Note that - this is going to be allocated twice. One for the eventlog it self - and one for the configuration table that is required from the spec - config EFI_TCG2_PROTOCOL_MEASURE_DTB bool "Measure DTB with EFI_TCG2_PROTOCOL" depends on EFI_TCG2_PROTOCOL diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index a15c73162e..6dba8b1406 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -111,7 +111,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, /* if ExitBootServices hasn't been called update the normal log */ if (!event_log.ebs_called) { if (event_log.truncated || - event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) { + event_log.pos + event_size > CONFIG_TPM2_EVENT_LOG_SIZE) { event_log.truncated = true; return EFI_VOLUME_FULL; } @@ -124,7 +124,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, return ret;
/* if GetEventLog has been called update FinalEventLog as well */ - if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) + if (event_log.final_pos + event_size > CONFIG_TPM2_EVENT_LOG_SIZE) return EFI_VOLUME_FULL;
log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos); @@ -822,12 +822,12 @@ static efi_status_t create_final_event(void) * EFI_TCG2_GET_EVENT_LOGS need to be stored in an instance of an * EFI_CONFIGURATION_TABLE */ - ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, TPM2_EVENT_LOG_SIZE, + ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, CONFIG_TPM2_EVENT_LOG_SIZE, &event_log.final_buffer); if (ret != EFI_SUCCESS) goto out;
- memset(event_log.final_buffer, 0xff, TPM2_EVENT_LOG_SIZE); + memset(event_log.final_buffer, 0xff, CONFIG_TPM2_EVENT_LOG_SIZE); final_event = event_log.final_buffer; final_event->number_of_events = 0; final_event->version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION; @@ -913,7 +913,8 @@ static efi_status_t efi_init_event_log(void) if (tcg2_platform_get_tpm2(&dev)) return EFI_DEVICE_ERROR;
- ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, + CONFIG_TPM2_EVENT_LOG_SIZE, (void **)&event_log.buffer); if (ret != EFI_SUCCESS) return ret; @@ -922,7 +923,7 @@ static efi_status_t efi_init_event_log(void) * initialize log area as 0xff so the OS can easily figure out the * last log entry */ - memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); + memset(event_log.buffer, 0xff, CONFIG_TPM2_EVENT_LOG_SIZE);
/* * The log header is defined to be in SHA1 event log entry format. @@ -939,7 +940,7 @@ static efi_status_t efi_init_event_log(void) * platforms can use different ways to do so. */ elog.log = event_log.buffer; - elog.log_size = TPM2_EVENT_LOG_SIZE; + elog.log_size = CONFIG_TPM2_EVENT_LOG_SIZE; rc = tcg2_log_prepare_buffer(dev, &elog, false); if (rc) { ret = (rc == -ENOBUFS) ? EFI_BUFFER_TOO_SMALL : EFI_DEVICE_ERROR;

On Tue, 14 Jan 2025 at 17:20, Raymond Mao raymond.mao@linaro.org wrote:
Move default eventlog size from efi to tpm for using in both efi and measured boot.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v5
- Move eventlog size kconfig from EFI to TPM2, so that it can be used by both EFI and MEASURED_BOOT.
doc/usage/measured_boot.rst | 1 - drivers/tpm/Kconfig | 9 +++++++++ include/efi_tcg2.h | 2 -- lib/efi_loader/Kconfig | 9 --------- lib/efi_loader/efi_tcg2.c | 15 ++++++++------- 5 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst index 05c439e9ac..488dd546f1 100644 --- a/doc/usage/measured_boot.rst +++ b/doc/usage/measured_boot.rst @@ -24,7 +24,6 @@ Requirements
- A hardware TPM 2.0 supported by an enabled U-Boot driver
- CONFIG_EFI_TCG2_PROTOCOL=y
-* CONFIG_EFI_TCG2_PROTOCOL_EVENTLOG_SIZE=y
- optional CONFIG_EFI_TCG2_PROTOCOL_MEASURE_DTB=y will measure the loaded DTB in PCR 1
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig index d59102d9a6..01bc686d36 100644 --- a/drivers/tpm/Kconfig +++ b/drivers/tpm/Kconfig @@ -209,6 +209,15 @@ config TPM2_MMIO to the device using the standard TPM Interface Specification (TIS) protocol.
+config TPM2_EVENT_LOG_SIZE
int "EventLog size"
depends on TPM_V2
default 65536
help
Define the size of the EventLog. Note that this is going to be
allocated twice. One for the eventlog it self and one for the
configuration table that is required from the TCG2 spec
endif # TPM_V2
endmenu diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index 8dfb1bc952..7ed8880991 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -28,8 +28,6 @@ #define EFI_TCG2_MAX_PCR_INDEX 23 #define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
-#define TPM2_EVENT_LOG_SIZE CONFIG_EFI_TCG2_PROTOCOL_EVENTLOG_SIZE
typedef u32 efi_tcg_event_log_bitmap; typedef u32 efi_tcg_event_log_format; typedef u32 efi_tcg_event_algorithm_bitmap; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c46ffe3a9d..d703e901ed 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -437,15 +437,6 @@ config EFI_TCG2_PROTOCOL Provide a EFI_TCG2_PROTOCOL implementation using the TPM hardware of the platform.
-config EFI_TCG2_PROTOCOL_EVENTLOG_SIZE
int "EFI_TCG2_PROTOCOL EventLog size"
depends on EFI_TCG2_PROTOCOL
default 65536
help
Define the size of the EventLog for EFI_TCG2_PROTOCOL. Note that
this is going to be allocated twice. One for the eventlog it self
and one for the configuration table that is required from the spec
config EFI_TCG2_PROTOCOL_MEASURE_DTB bool "Measure DTB with EFI_TCG2_PROTOCOL" depends on EFI_TCG2_PROTOCOL diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index a15c73162e..6dba8b1406 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -111,7 +111,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, /* if ExitBootServices hasn't been called update the normal log */ if (!event_log.ebs_called) { if (event_log.truncated ||
event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) {
event_log.pos + event_size > CONFIG_TPM2_EVENT_LOG_SIZE) { event_log.truncated = true; return EFI_VOLUME_FULL; }
@@ -124,7 +124,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, return ret;
/* if GetEventLog has been called update FinalEventLog as well */
if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE)
if (event_log.final_pos + event_size > CONFIG_TPM2_EVENT_LOG_SIZE) return EFI_VOLUME_FULL; log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos);
@@ -822,12 +822,12 @@ static efi_status_t create_final_event(void) * EFI_TCG2_GET_EVENT_LOGS need to be stored in an instance of an * EFI_CONFIGURATION_TABLE */
ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, TPM2_EVENT_LOG_SIZE,
ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, CONFIG_TPM2_EVENT_LOG_SIZE, &event_log.final_buffer); if (ret != EFI_SUCCESS) goto out;
memset(event_log.final_buffer, 0xff, TPM2_EVENT_LOG_SIZE);
memset(event_log.final_buffer, 0xff, CONFIG_TPM2_EVENT_LOG_SIZE); final_event = event_log.final_buffer; final_event->number_of_events = 0; final_event->version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
@@ -913,7 +913,8 @@ static efi_status_t efi_init_event_log(void) if (tcg2_platform_get_tpm2(&dev)) return EFI_DEVICE_ERROR;
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA,
CONFIG_TPM2_EVENT_LOG_SIZE, (void **)&event_log.buffer); if (ret != EFI_SUCCESS) return ret;
@@ -922,7 +923,7 @@ static efi_status_t efi_init_event_log(void) * initialize log area as 0xff so the OS can easily figure out the * last log entry */
memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
memset(event_log.buffer, 0xff, CONFIG_TPM2_EVENT_LOG_SIZE); /* * The log header is defined to be in SHA1 event log entry format.
@@ -939,7 +940,7 @@ static efi_status_t efi_init_event_log(void) * platforms can use different ways to do so. */ elog.log = event_log.buffer;
elog.log_size = TPM2_EVENT_LOG_SIZE;
elog.log_size = CONFIG_TPM2_EVENT_LOG_SIZE; rc = tcg2_log_prepare_buffer(dev, &elog, false); if (rc) { ret = (rc == -ENOBUFS) ? EFI_BUFFER_TOO_SMALL : EFI_DEVICE_ERROR;
-- 2.25.1
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc a default buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Remove patch dependency. - Remove the fallback to FDT when BLOBLIST is selected. Changes in v3 - Malloc an 8KB buffer when user eventlog buffer does not exist. Changes in v4 - Replace the default eventlog size with TPM2_EVENT_LOG_SIZE. Changes in v5 - Replace TPM2_EVENT_LOG_SIZE with CONFIG_TPM2_EVENT_LOG_SIZE. - Add an inline TODO comment.
lib/tpm_tcg2.c | 61 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-)
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a35..2d9076f091 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank, u32 *bank_num) @@ -615,15 +617,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
+ if (elog->found) + return 0; + /* - * Initialize the log buffer if no log was discovered and the buffer is - * valid. User's can pass in their own buffer as a fallback if no - * memory region is found. + * Initialize the log buffer if no log was discovered. + * User can pass in their own buffer as a fallback if no memory region + * is found, else malloc a buffer if it does not exist. */ - if (!elog->found && elog->log_size) - rc = tcg2_log_init(dev, elog); + if (!elog->log_size) { + elog->log = malloc(CONFIG_TPM2_EVENT_LOG_SIZE); + if (!elog->log) + return -ENOMEM; + + memset(elog->log, 0, CONFIG_TPM2_EVENT_LOG_SIZE); + elog->log_size = CONFIG_TPM2_EVENT_LOG_SIZE; + }
- return rc; + return tcg2_log_init(dev, elog); }
int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, @@ -676,10 +687,25 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) const __be32 *size_prop; int asize; int ssize; + struct ofnode_phandle_args args; + phys_addr_t a; + fdt_size_t s;
*addr = NULL; *size = 0;
+ *addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size); + if (*addr && *size) + return 0; + /* + * TODO: + * replace BLOBLIST with a new kconfig for handoff all components + * (fdt, tpm event log, etc...) from previous boot stage via bloblist + * mandatorily following Firmware Handoff spec. + */ + else if (CONFIG_IS_ENABLED(BLOBLIST)) + return -ENODEV; + addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); if (!addr_prop) addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); @@ -694,22 +720,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size)
*addr = map_physmem(a, s, MAP_NOCACHE); *size = (u32)s; - } else { - struct ofnode_phandle_args args; - phys_addr_t a; - fdt_size_t s;
- if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, - 0, &args)) - return -ENODEV; + return 0; + }
- a = ofnode_get_addr_size(args.node, "reg", &s); - if (a == FDT_ADDR_T_NONE) - return -ENOMEM; + if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 0, &args)) + return -ENODEV;
- *addr = map_physmem(a, s, MAP_NOCACHE); - *size = (u32)s; - } + a = ofnode_get_addr_size(args.node, "reg", &s); + if (a == FDT_ADDR_T_NONE) + return -ENOMEM; + + *addr = map_physmem(a, s, MAP_NOCACHE); + *size = (u32)s;
return 0; }

Hi Raymond,
On Tue, 14 Jan 2025 at 08:20, Raymond Mao raymond.mao@linaro.org wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc a default buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
Changes in v4
- Replace the default eventlog size with TPM2_EVENT_LOG_SIZE.
Changes in v5
- Replace TPM2_EVENT_LOG_SIZE with CONFIG_TPM2_EVENT_LOG_SIZE.
- Add an inline TODO comment.
lib/tpm_tcg2.c | 61 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nit in case you respin again: -ENODEV is for driver model, when there is no device. It is actually handling specially by driver model. So -ENOENT is what I try to use for things that don't exist but aren't devices.
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a35..2d9076f091 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank, u32 *bank_num) @@ -615,15 +617,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
if (elog->found)
return 0;
/*
* Initialize the log buffer if no log was discovered and the buffer is
* valid. User's can pass in their own buffer as a fallback if no
* memory region is found.
* Initialize the log buffer if no log was discovered.
* User can pass in their own buffer as a fallback if no memory region
* is found, else malloc a buffer if it does not exist. */
if (!elog->found && elog->log_size)
rc = tcg2_log_init(dev, elog);
if (!elog->log_size) {
elog->log = malloc(CONFIG_TPM2_EVENT_LOG_SIZE);
if (!elog->log)
return -ENOMEM;
memset(elog->log, 0, CONFIG_TPM2_EVENT_LOG_SIZE);
elog->log_size = CONFIG_TPM2_EVENT_LOG_SIZE;
}
return rc;
return tcg2_log_init(dev, elog);
}
int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, @@ -676,10 +687,25 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) const __be32 *size_prop; int asize; int ssize;
struct ofnode_phandle_args args;
phys_addr_t a;
fdt_size_t s; *addr = NULL; *size = 0;
*addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size);
if (*addr && *size)
return 0;
/*
* TODO:
* replace BLOBLIST with a new kconfig for handoff all components
* (fdt, tpm event log, etc...) from previous boot stage via bloblist
* mandatorily following Firmware Handoff spec.
*/
else if (CONFIG_IS_ENABLED(BLOBLIST))
return -ENODEV;
addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); if (!addr_prop) addr_prop = dev_read_prop(dev, "linux,sml-base", &asize);
@@ -694,22 +720,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size)
*addr = map_physmem(a, s, MAP_NOCACHE); *size = (u32)s;
} else {
struct ofnode_phandle_args args;
phys_addr_t a;
fdt_size_t s;
if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0,
0, &args))
return -ENODEV;
return 0;
}
a = ofnode_get_addr_size(args.node, "reg", &s);
if (a == FDT_ADDR_T_NONE)
return -ENOMEM;
if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 0, &args))
return -ENODEV;
*addr = map_physmem(a, s, MAP_NOCACHE);
*size = (u32)s;
}
a = ofnode_get_addr_size(args.node, "reg", &s);
if (a == FDT_ADDR_T_NONE)
return -ENOMEM;
*addr = map_physmem(a, s, MAP_NOCACHE);
*size = (u32)s; return 0;
}
2.25.1
Regards, SImon

On Wed, 15 Jan 2025 at 03:17, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Tue, 14 Jan 2025 at 08:20, Raymond Mao raymond.mao@linaro.org wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc a default buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
Changes in v4
- Replace the default eventlog size with TPM2_EVENT_LOG_SIZE.
Changes in v5
- Replace TPM2_EVENT_LOG_SIZE with CONFIG_TPM2_EVENT_LOG_SIZE.
- Add an inline TODO comment.
lib/tpm_tcg2.c | 61 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nit in case you respin again: -ENODEV is for driver model, when there is no device. It is actually handling specially by driver model. So -ENOENT is what I try to use for things that don't exist but aren't devices.
+1,
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a35..2d9076f091 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank, u32 *bank_num) @@ -615,15 +617,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
if (elog->found)
return 0;
/*
* Initialize the log buffer if no log was discovered and the buffer is
* valid. User's can pass in their own buffer as a fallback if no
* memory region is found.
* Initialize the log buffer if no log was discovered.
* User can pass in their own buffer as a fallback if no memory region
* is found, else malloc a buffer if it does not exist. */
if (!elog->found && elog->log_size)
rc = tcg2_log_init(dev, elog);
if (!elog->log_size) {
elog->log = malloc(CONFIG_TPM2_EVENT_LOG_SIZE);
if (!elog->log)
return -ENOMEM;
memset(elog->log, 0, CONFIG_TPM2_EVENT_LOG_SIZE);
elog->log_size = CONFIG_TPM2_EVENT_LOG_SIZE;
Why are you doing this? There are 2 ways to pass an EventLog to the kernel. Either via a config table from EFI, or using sml-base and sml-size in a DT (which are both required). IOW you will create an EventLog no one will discover
Cheers /Ilias
}
return rc;
return tcg2_log_init(dev, elog);
}
int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, @@ -676,10 +687,25 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) const __be32 *size_prop; int asize; int ssize;
struct ofnode_phandle_args args;
phys_addr_t a;
fdt_size_t s; *addr = NULL; *size = 0;
*addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size);
if (*addr && *size)
return 0;
/*
* TODO:
* replace BLOBLIST with a new kconfig for handoff all components
* (fdt, tpm event log, etc...) from previous boot stage via bloblist
* mandatorily following Firmware Handoff spec.
*/
else if (CONFIG_IS_ENABLED(BLOBLIST))
return -ENODEV;
addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); if (!addr_prop) addr_prop = dev_read_prop(dev, "linux,sml-base", &asize);
@@ -694,22 +720,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size)
*addr = map_physmem(a, s, MAP_NOCACHE); *size = (u32)s;
} else {
struct ofnode_phandle_args args;
phys_addr_t a;
fdt_size_t s;
if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0,
0, &args))
return -ENODEV;
return 0;
}
a = ofnode_get_addr_size(args.node, "reg", &s);
if (a == FDT_ADDR_T_NONE)
return -ENOMEM;
if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 0, &args))
return -ENODEV;
*addr = map_physmem(a, s, MAP_NOCACHE);
*size = (u32)s;
}
a = ofnode_get_addr_size(args.node, "reg", &s);
if (a == FDT_ADDR_T_NONE)
return -ENOMEM;
*addr = map_physmem(a, s, MAP_NOCACHE);
*size = (u32)s; return 0;
}
2.25.1
Regards, SImon

Hi Ilias,
On Thu, 16 Jan 2025 at 07:35, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Wed, 15 Jan 2025 at 03:17, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Tue, 14 Jan 2025 at 08:20, Raymond Mao raymond.mao@linaro.org
wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc a default buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
Changes in v4
- Replace the default eventlog size with TPM2_EVENT_LOG_SIZE.
Changes in v5
- Replace TPM2_EVENT_LOG_SIZE with CONFIG_TPM2_EVENT_LOG_SIZE.
- Add an inline TODO comment.
lib/tpm_tcg2.c | 61
++++++++++++++++++++++++++++++++++----------------
1 file changed, 42 insertions(+), 19 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nit in case you respin again: -ENODEV is for driver model, when there is no device. It is actually handling specially by driver model. So -ENOENT is what I try to use for things that don't exist but aren't devices.
+1,
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a35..2d9076f091 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32
*active_bank,
u32 *bank_num)
@@ -615,15 +617,24 @@ int tcg2_log_prepare_buffer(struct udevice
*dev, struct tcg2_event_log *elog,
elog->found = log.found; }
if (elog->found)
return 0;
/*
* Initialize the log buffer if no log was discovered and the
buffer is
* valid. User's can pass in their own buffer as a fallback
if no
* memory region is found.
* Initialize the log buffer if no log was discovered.
* User can pass in their own buffer as a fallback if no
memory region
* is found, else malloc a buffer if it does not exist. */
if (!elog->found && elog->log_size)
rc = tcg2_log_init(dev, elog);
if (!elog->log_size) {
elog->log = malloc(CONFIG_TPM2_EVENT_LOG_SIZE);
if (!elog->log)
return -ENOMEM;
memset(elog->log, 0, CONFIG_TPM2_EVENT_LOG_SIZE);
elog->log_size = CONFIG_TPM2_EVENT_LOG_SIZE;
Why are you doing this? There are 2 ways to pass an EventLog to the kernel. Either via a config table from EFI, or using sml-base and sml-size in a DT (which are both required). IOW you will create an EventLog no one will discover
My understanding is that it is still added to those tables (e.g. EFI). Linux does not see the bloblist structure.
Regards, Simon

On Sat, 18 Jan 2025 at 06:31, Simon Glass sjg@chromium.org wrote:
Hi Ilias,
On Thu, 16 Jan 2025 at 07:35, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Wed, 15 Jan 2025 at 03:17, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Tue, 14 Jan 2025 at 08:20, Raymond Mao raymond.mao@linaro.org wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc a default buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
Changes in v4
- Replace the default eventlog size with TPM2_EVENT_LOG_SIZE.
Changes in v5
- Replace TPM2_EVENT_LOG_SIZE with CONFIG_TPM2_EVENT_LOG_SIZE.
- Add an inline TODO comment.
lib/tpm_tcg2.c | 61 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nit in case you respin again: -ENODEV is for driver model, when there is no device. It is actually handling specially by driver model. So -ENOENT is what I try to use for things that don't exist but aren't devices.
+1,
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a35..2d9076f091 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank, u32 *bank_num) @@ -615,15 +617,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
if (elog->found)
return 0;
/*
* Initialize the log buffer if no log was discovered and the buffer is
* valid. User's can pass in their own buffer as a fallback if no
* memory region is found.
* Initialize the log buffer if no log was discovered.
* User can pass in their own buffer as a fallback if no memory region
* is found, else malloc a buffer if it does not exist. */
if (!elog->found && elog->log_size)
rc = tcg2_log_init(dev, elog);
if (!elog->log_size) {
elog->log = malloc(CONFIG_TPM2_EVENT_LOG_SIZE);
if (!elog->log)
return -ENOMEM;
memset(elog->log, 0, CONFIG_TPM2_EVENT_LOG_SIZE);
elog->log_size = CONFIG_TPM2_EVENT_LOG_SIZE;
Why are you doing this? There are 2 ways to pass an EventLog to the kernel. Either via a config table from EFI, or using sml-base and sml-size in a DT (which are both required). IOW you will create an EventLog no one will discover
My understanding is that it is still added to those tables (e.g. EFI). Linux does not see the bloblist structure.
No that's not what happens. We either explicitly allocate memory from the EFI subsystem and use that, or parse the DT and map whatever the DT tells us, If you want to use malloc for allocating a non-EFI consumed EventLog you have to inject these values to a DT otherwise the OS won't be able to find it.
Regards, Simon
participants (3)
-
Ilias Apalodimas
-
Raymond Mao
-
Simon Glass