Skip to contentSkip to conversation

tpm: Add reserved memory event log

PATCH Superseded Eddie James 3 participants 11 messages Jan 13, 2023 – Jan 26, 2023

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover tpm: Add reserved memory event log

Some platforms may desire to pass the event log up to linux in the form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it. Since the memory is mapped, not allocated, change all the event log allocation functions to managed allocations so that the memory can be either automatically freed or unmapped.

Changes since v1:
- Use managed memory

Eddie James (2):
tpm: Use managed allocation for bios event log
tpm: Add reserved memory event log

 drivers/char/tpm/eventlog/acpi.c |  5 ++--
 drivers/char/tpm/eventlog/efi.c  | 13 +++++-----
 drivers/char/tpm/eventlog/of.c   | 41 ++++++++++++++++++++++++++++++--
 drivers/char/tpm/tpm-chip.c      |  1 -
 4 files changed, 49 insertions(+), 11 deletions(-)
Signature · 1 line
2.31.1
#1 lore raw

PATCH v2 1/2 tpm: Use managed allocation for bios event log

Since the bios event log is freed in the device release function, let devres handle the deallocation. This will allow other memory allocation/mapping functions to be used for the bios event log.

---
 drivers/char/tpm/eventlog/acpi.c |  5 +++--
 drivers/char/tpm/eventlog/efi.c  | 13 +++++++------
 drivers/char/tpm/eventlog/of.c   |  3 ++-
 drivers/char/tpm/tpm-chip.c      |  1 -
 4 files changed, 12 insertions(+), 10 deletions(-)
drivers/char/tpm/eventlog/acpi.c +3 -2
index 0913d3eb8d51..40360e599bc3 100644
@@ -14,6 +14,7 @@
  * Access to the event log extended by the TCG BIOS of PC platform
  */
 
+#include <linux/device.h>
 #include <linux/seq_file.h>
 #include <linux/fs.h>
 #include <linux/security.h>
@@ -135,7 +136,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 	}
 
 	/* malloc EventLog space */
-	log->bios_event_log = kmalloc(len, GFP_KERNEL);
+	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;
 
@@ -160,7 +161,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 	return format;
 
 err:
-	kfree(log->bios_event_log);
+	devm_kfree(&chip->dev, log->bios_event_log);
 	log->bios_event_log = NULL;
 	return ret;
 }
drivers/char/tpm/eventlog/efi.c +7 -6
index e6cb9d525e30..4e9d7c2bf32e 100644
@@ -6,6 +6,7 @@
  *      Thiebaud Weksteen <[email protected]>
  */
 
+#include <linux/device.h>
 #include <linux/efi.h>
 #include <linux/tpm_eventlog.h>
 
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 	}
 
 	/* malloc EventLog space */
-	log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL);
 	if (!log->bios_event_log) {
 		ret = -ENOMEM;
 		goto out;
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 			     MEMREMAP_WB);
 	if (!final_tbl) {
 		pr_err("Could not map UEFI TPM final log\n");
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 	 * Allocate memory for the 'combined log' where we will append the
 	 * 'final events log' to.
 	 */
-	tmp = krealloc(log->bios_event_log,
-		       log_size + final_events_log_size,
-		       GFP_KERNEL);
+	tmp = devm_krealloc(&chip->dev, log->bios_event_log,
+			    log_size + final_events_log_size,
+			    GFP_KERNEL);
 	if (!tmp) {
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
 		ret = -ENOMEM;
 		goto out;
 	}
drivers/char/tpm/eventlog/of.c +2 -1
index a9ce66d09a75..741ab2204b11 100644
@@ -10,6 +10,7 @@
  * Read the event log created by the firmware on PPC64
  */
 
+#include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/tpm_eventlog.h>
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
 		return -EIO;
 	}
 
-	log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;
 
drivers/char/tpm/tpm-chip.c +0 -1
index 741d8f3e8fb3..b99f55f2d4fd 100644
@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)
 	idr_remove(&dev_nums_idr, chip->dev_num);
 	mutex_unlock(&idr_lock);
 
-	kfree(chip->log.bios_event_log);
 	kfree(chip->work_space.context_buf);
 	kfree(chip->work_space.session_buf);
 	kfree(chip->allocated_banks);
Signature · 1 line
2.31.1
maintainer
#2 lore raw

Re: [PATCH v2 1/2] tpm: Use managed allocation for bios event log

Quoted 34 lines · Eddie James

Since the bios event log is freed in the device release function, let devres handle the deallocation. This will allow other memory allocation/mapping functions to be used for the bios event log.

---
 drivers/char/tpm/eventlog/acpi.c |  5 +++--
 drivers/char/tpm/eventlog/efi.c  | 13 +++++++------
 drivers/char/tpm/eventlog/of.c   |  3 ++-
 drivers/char/tpm/tpm-chip.c      |  1 -
 4 files changed, 12 insertions(+), 10 deletions(-)
drivers/char/tpm/eventlog/acpi.c +2 -1
index 0913d3eb8d51..40360e599bc3 100644
@@ -14,6 +14,7 @@
  * Access to the event log extended by the TCG BIOS of PC platform
  */
 
+#include <linux/device.h>
 #include <linux/seq_file.h>
 #include <linux/fs.h>
 #include <linux/security.h>
@@ -135,7 +136,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 	}
 
 	/* malloc EventLog space */
-	log->bios_event_log = kmalloc(len, GFP_KERNEL);
+	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;
 

drivers/char/tpm/eventlog/acpi.c int tpm_read_log_acpi(struct tpm_chip *chip) · line 164

Quoted 5 lines
drivers/char/tpm/eventlog/acpi.c +1 -1
@@ -160,7 +161,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 	return format;
 
 err:
-	kfree(log->bios_event_log);
+	devm_kfree(&chip->dev, log->bios_event_log);

I wonder do we want to do devm_kfree's at all as the memory is freed during detach, i.e. taken care by devres.

Quoted 85 lines
drivers/char/tpm/eventlog/acpi.c +0 -0
 	log->bios_event_log = NULL;
 	return ret;
 }
drivers/char/tpm/eventlog/efi.c +7 -6
index e6cb9d525e30..4e9d7c2bf32e 100644
@@ -6,6 +6,7 @@
  *      Thiebaud Weksteen <[email protected]>
  */
 
+#include <linux/device.h>
 #include <linux/efi.h>
 #include <linux/tpm_eventlog.h>
 
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 	}
 
 	/* malloc EventLog space */
-	log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL);
 	if (!log->bios_event_log) {
 		ret = -ENOMEM;
 		goto out;
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 			     MEMREMAP_WB);
 	if (!final_tbl) {
 		pr_err("Could not map UEFI TPM final log\n");
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
 	 * Allocate memory for the 'combined log' where we will append the
 	 * 'final events log' to.
 	 */
-	tmp = krealloc(log->bios_event_log,
-		       log_size + final_events_log_size,
-		       GFP_KERNEL);
+	tmp = devm_krealloc(&chip->dev, log->bios_event_log,
+			    log_size + final_events_log_size,
+			    GFP_KERNEL);
 	if (!tmp) {
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
 		ret = -ENOMEM;
 		goto out;
 	}
drivers/char/tpm/eventlog/of.c +2 -1
index a9ce66d09a75..741ab2204b11 100644
@@ -10,6 +10,7 @@
  * Read the event log created by the firmware on PPC64
  */
 
+#include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/tpm_eventlog.h>
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
 		return -EIO;
 	}
 
-	log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;
 
drivers/char/tpm/tpm-chip.c +0 -1
index 741d8f3e8fb3..b99f55f2d4fd 100644
@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)
 	idr_remove(&dev_nums_idr, chip->dev_num);
 	mutex_unlock(&idr_lock);
 
-	kfree(chip->log.bios_event_log);
 	kfree(chip->work_space.context_buf);
 	kfree(chip->work_space.session_buf);
 	kfree(chip->allocated_banks);
Signature · 1 line
2.31.1

BR, Jarkko

#3 lore raw

Re: [PATCH v2 1/2] tpm: Use managed allocation for bios event log

Quoted 34 lines · Jarkko Sakkinen
Quoted 33 lines · Eddie James

Since the bios event log is freed in the device release function, let devres handle the deallocation. This will allow other memory allocation/mapping functions to be used for the bios event log.

---
  drivers/char/tpm/eventlog/acpi.c |  5 +++--
  drivers/char/tpm/eventlog/efi.c  | 13 +++++++------
  drivers/char/tpm/eventlog/of.c   |  3 ++-
  drivers/char/tpm/tpm-chip.c      |  1 -
  4 files changed, 12 insertions(+), 10 deletions(-)
drivers/char/tpm/eventlog/acpi.c +2 -1
index 0913d3eb8d51..40360e599bc3 100644
@@ -14,6 +14,7 @@
   * Access to the event log extended by the TCG BIOS of PC platform
   */
 
+#include <linux/device.h>
  #include <linux/seq_file.h>
  #include <linux/fs.h>
  #include <linux/security.h>
@@ -135,7 +136,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
  	}
 
  	/* malloc EventLog space */
-	log->bios_event_log = kmalloc(len, GFP_KERNEL);
+	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
  	if (!log->bios_event_log)
  		return -ENOMEM;
 
Quoted 8 lines

drivers/char/tpm/eventlog/acpi.c int tpm_read_log_acpi(struct tpm_chip *chip) · line 164

Quoted 6 lines
drivers/char/tpm/eventlog/acpi.c +1 -1
@@ -160,7 +161,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
  	return format;
 
  err:
-	kfree(log->bios_event_log);
+	devm_kfree(&chip->dev, log->bios_event_log);

I wonder do we want to do devm_kfree's at all as the memory is freed during detach, i.e. taken care by devres.

I think we should since the chip/tpm driver will continue to probe without the bios event log. Therefore that memory will be wasted if there is some error during bios log setup.

Thanks,

Eddie

Quoted 87 lines
Quoted 86 lines
drivers/char/tpm/eventlog/acpi.c +0 -0
  	log->bios_event_log = NULL;
  	return ret;
  }
drivers/char/tpm/eventlog/efi.c +7 -6
index e6cb9d525e30..4e9d7c2bf32e 100644
@@ -6,6 +6,7 @@
   *      Thiebaud Weksteen <[email protected]>
   */
 
+#include <linux/device.h>
  #include <linux/efi.h>
  #include <linux/tpm_eventlog.h>
 
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
  	}
 
  	/* malloc EventLog space */
-	log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL);
  	if (!log->bios_event_log) {
  		ret = -ENOMEM;
  		goto out;
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
  			     MEMREMAP_WB);
  	if (!final_tbl) {
  		pr_err("Could not map UEFI TPM final log\n");
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
  		ret = -ENOMEM;
  		goto out;
  	}
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
  	 * Allocate memory for the 'combined log' where we will append the
  	 * 'final events log' to.
  	 */
-	tmp = krealloc(log->bios_event_log,
-		       log_size + final_events_log_size,
-		       GFP_KERNEL);
+	tmp = devm_krealloc(&chip->dev, log->bios_event_log,
+			    log_size + final_events_log_size,
+			    GFP_KERNEL);
  	if (!tmp) {
-		kfree(log->bios_event_log);
+		devm_kfree(&chip->dev, log->bios_event_log);
  		ret = -ENOMEM;
  		goto out;
  	}
drivers/char/tpm/eventlog/of.c +2 -1
index a9ce66d09a75..741ab2204b11 100644
@@ -10,6 +10,7 @@
   * Read the event log created by the firmware on PPC64
   */
 
+#include <linux/device.h>
  #include <linux/slab.h>
  #include <linux/of.h>
  #include <linux/tpm_eventlog.h>
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
  		return -EIO;
  	}
 
-	log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
  	if (!log->bios_event_log)
  		return -ENOMEM;
 
drivers/char/tpm/tpm-chip.c +0 -1
index 741d8f3e8fb3..b99f55f2d4fd 100644
@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)
  	idr_remove(&dev_nums_idr, chip->dev_num);
  	mutex_unlock(&idr_lock);
 
-	kfree(chip->log.bios_event_log);
  	kfree(chip->work_space.context_buf);
  	kfree(chip->work_space.session_buf);
  	kfree(chip->allocated_banks);
Signature · 1 line
2.31.1

BR, Jarkko

maintainer Tested-by Reviewed-by
#4 lore raw

Re: [PATCH v2 1/2] tpm: Use managed allocation for bios event log

Quoted 42 lines · Eddie James
Quoted 30 lines · Jarkko Sakkinen
Quoted 29 lines · Eddie James

Since the bios event log is freed in the device release function, let devres handle the deallocation. This will allow other memory allocation/mapping functions to be used for the bios event log.

---
  drivers/char/tpm/eventlog/acpi.c |  5 +++--
  drivers/char/tpm/eventlog/efi.c  | 13 +++++++------
  drivers/char/tpm/eventlog/of.c   |  3 ++-
  drivers/char/tpm/tpm-chip.c      |  1 -
  4 files changed, 12 insertions(+), 10 deletions(-)
drivers/char/tpm/eventlog/acpi.c +2 -1
index 0913d3eb8d51..40360e599bc3 100644
@@ -14,6 +14,7 @@
   * Access to the event log extended by the TCG BIOS of PC platform
   */
+#include <linux/device.h>
  #include <linux/seq_file.h>
  #include <linux/fs.h>
  #include <linux/security.h>
@@ -135,7 +136,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
  	}
  	/* malloc EventLog space */
-	log->bios_event_log = kmalloc(len, GFP_KERNEL);
+	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
  	if (!log->bios_event_log)
Quoted 8 lines

drivers/char/tpm/eventlog/acpi.c int tpm_read_log_acpi(struct tpm_chip *chip) · line 163

Quoted 6 lines
drivers/char/tpm/eventlog/acpi.c +1 -1
  		return -ENOMEM;
@@ -160,7 +161,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
  	return format;
  err:
-	kfree(log->bios_event_log);
+	devm_kfree(&chip->dev, log->bios_event_log);

I wonder do we want to do devm_kfree's at all as the memory is freed during detach, i.e. taken care by devres.

Quoted 3 lines

I think we should since the chip/tpm driver will continue to probe without the bios event log. Therefore that memory will be wasted if there is some error during bios log setup.

OK, I buy this!

For this patch:

If you could refine the description for the 2nd, then these would be ready to be picked.

Quoted 3 lines

Thanks,

Eddie

BR, Jarkko

#5 lore raw

PATCH v2 2/2 tpm: Add reserved memory event log

In reply to Eddie James

Some platforms may desire to pass the event log up to linux in the form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it.

---
 drivers/char/tpm/eventlog/of.c | 38 +++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)
drivers/char/tpm/eventlog/of.c +37 -1
index 741ab2204b11..c815cadf00a4 100644
@@ -12,12 +12,48 @@
 
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/tpm_eventlog.h>
 
 #include "../tpm.h"
 #include "common.h"
 
+static int tpm_read_log_memory_region(struct tpm_chip *chip)
+{
+	struct device_node *node;
+	struct resource res;
+	int rc;
+
+	node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
+	if (!node) {
+		dev_info(&chip->dev, "no phandle\n");
+		return -ENODEV;
+	}
+
+	rc = of_address_to_resource(node, 0, &res);
+	of_node_put(node);
+	if (rc) {
+		dev_info(&chip->dev, "no mem\n");
+		return rc;
+	}
+
+	chip->log.bios_event_log = devm_memremap(&chip->dev, res.start, resource_size(&res),
+						 MEMREMAP_WB);
+	if (!chip->log.bios_event_log) {
+		dev_info(&chip->dev, "err memremap\n");
+		return -ENOMEM;
+	}
+
+	chip->log.bios_event_log_end = chip->log.bios_event_log + resource_size(&res);
+
+	return chip->flags & TPM_CHIP_FLAG_TPM2 ? EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 :
+		EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+}
+
 int tpm_read_log_of(struct tpm_chip *chip)
 {
 	struct device_node *np;
@@ -39,7 +75,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
 	sizep = of_get_property(np, "linux,sml-size", NULL);
 	basep = of_get_property(np, "linux,sml-base", NULL);
 	if (sizep == NULL && basep == NULL)
-		return -ENODEV;
+		return tpm_read_log_memory_region(chip);
 	if (sizep == NULL || basep == NULL)
 		return -EIO;
 
Signature · 1 line
2.31.1
#6 lore raw
Quoted 1 line · Eddie James

Some platforms may desire to pass the event log up to linux in the

Which platforms are these that work like this?

Stefan

Quoted 70 lines

form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it.

---
  drivers/char/tpm/eventlog/of.c | 38 +++++++++++++++++++++++++++++++++-
  1 file changed, 37 insertions(+), 1 deletion(-)
drivers/char/tpm/eventlog/of.c +37 -1
index 741ab2204b11..c815cadf00a4 100644
@@ -12,12 +12,48 @@
 
  #include <linux/device.h>
  #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
  #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
  #include <linux/tpm_eventlog.h>
 
  #include "../tpm.h"
  #include "common.h"
 
+static int tpm_read_log_memory_region(struct tpm_chip *chip)
+{
+	struct device_node *node;
+	struct resource res;
+	int rc;
+
+	node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
+	if (!node) {
+		dev_info(&chip->dev, "no phandle\n");
+		return -ENODEV;
+	}
+
+	rc = of_address_to_resource(node, 0, &res);
+	of_node_put(node);
+	if (rc) {
+		dev_info(&chip->dev, "no mem\n");
+		return rc;
+	}
+
+	chip->log.bios_event_log = devm_memremap(&chip->dev, res.start, resource_size(&res),
+						 MEMREMAP_WB);
+	if (!chip->log.bios_event_log) {
+		dev_info(&chip->dev, "err memremap\n");
+		return -ENOMEM;
+	}
+
+	chip->log.bios_event_log_end = chip->log.bios_event_log + resource_size(&res);
+
+	return chip->flags & TPM_CHIP_FLAG_TPM2 ? EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 :
+		EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+}
+
  int tpm_read_log_of(struct tpm_chip *chip)
  {
  	struct device_node *np;
@@ -39,7 +75,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
  	sizep = of_get_property(np, "linux,sml-size", NULL);
  	basep = of_get_property(np, "linux,sml-base", NULL);
  	if (sizep == NULL && basep == NULL)
-		return -ENODEV;
+		return tpm_read_log_memory_region(chip);
  	if (sizep == NULL || basep == NULL)
  		return -EIO;
 
#7 lore raw
Quoted 6 lines · Stefan Berger
Quoted 1 line · Eddie James

Some platforms may desire to pass the event log up to linux in the

Which platforms are these that work like this?

Platforms booting from U-Boot without EFI. So at the moment, IBM's OpenBMC systems hope to use this.

Thanks,

Eddie

Quoted 73 lines

   Stefan

Quoted 70 lines

form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it.

---
  drivers/char/tpm/eventlog/of.c | 38 +++++++++++++++++++++++++++++++++-

  1 file changed, 37 insertions(+), 1 deletion(-)
drivers/char/tpm/eventlog/of.c +32 -0
index 741ab2204b11..c815cadf00a4 100644
@@ -12,12 +12,48 @@
     #include <linux/device.h>
   #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
   #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
   #include <linux/tpm_eventlog.h>
     #include "../tpm.h"
   #include "common.h"
   +static int tpm_read_log_memory_region(struct tpm_chip *chip)
+{
+    struct device_node *node;
+    struct resource res;
+    int rc;
+
+    node = of_parse_phandle(chip->dev.parent->of_node, 
 "memory-region", 0);
+    if (!node) {
+        dev_info(&chip->dev, "no phandle\n");
+        return -ENODEV;
+    }
+
+    rc = of_address_to_resource(node, 0, &res);
+    of_node_put(node);
+    if (rc) {
+        dev_info(&chip->dev, "no mem\n");
+        return rc;
+    }
+
+    chip->log.bios_event_log = devm_memremap(&chip->dev, res.start, 
 resource_size(&res),
+                         MEMREMAP_WB);
+    if (!chip->log.bios_event_log) {
+        dev_info(&chip->dev, "err memremap\n");
+        return -ENOMEM;
+    }
+
+    chip->log.bios_event_log_end = chip->log.bios_event_log + 
 resource_size(&res);
+
+    return chip->flags & TPM_CHIP_FLAG_TPM2 ? 

EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 :
+        EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;

drivers/char/tpm/eventlog/of.c +2 -0
+}
+

  int tpm_read_log_of(struct tpm_chip *chip)
  {
      struct device_node *np;

drivers/char/tpm/eventlog/of.c +1 -1
@@ -39,7 +75,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
       sizep = of_get_property(np, "linux,sml-size", NULL);
       basep = of_get_property(np, "linux,sml-base", NULL);
       if (sizep == NULL && basep == NULL)
-        return -ENODEV;
+        return tpm_read_log_memory_region(chip);
       if (sizep == NULL || basep == NULL)
           return -EIO;
#8 lore raw
Quoted 11 lines · Eddie James
Quoted 6 lines · Stefan Berger
Quoted 1 line · Eddie James

Some platforms may desire to pass the event log up to linux in the

Which platforms are these that work like this?

Platforms booting from U-Boot without EFI. So at the moment, IBM's OpenBMC systems hope to use this.

It may be worth to mention this in the patch description in case someone wonders which systems would take that path.

Stefan

Quoted 75 lines

Thanks,

Eddie

Quoted 69 lines

   Stefan

Quoted 66 lines

form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it.

---
  drivers/char/tpm/eventlog/of.c | 38 +++++++++++++++++++++++++++++++++-

  1 file changed, 37 insertions(+), 1 deletion(-)
drivers/char/tpm/eventlog/of.c +36 -1
index 741ab2204b11..c815cadf00a4 100644
@@ -12,12 +12,48 @@
     #include <linux/device.h>
   #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
   #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
   #include <linux/tpm_eventlog.h>
     #include "../tpm.h"
   #include "common.h"
   +static int tpm_read_log_memory_region(struct tpm_chip *chip)
+{
+    struct device_node *node;
+    struct resource res;
+    int rc;
+
+    node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
+    if (!node) {
+        dev_info(&chip->dev, "no phandle\n");
+        return -ENODEV;
+    }
+
+    rc = of_address_to_resource(node, 0, &res);
+    of_node_put(node);
+    if (rc) {
+        dev_info(&chip->dev, "no mem\n");
+        return rc;
+    }
+
+    chip->log.bios_event_log = devm_memremap(&chip->dev, res.start, resource_size(&res),
+                         MEMREMAP_WB);
+    if (!chip->log.bios_event_log) {
+        dev_info(&chip->dev, "err memremap\n");
+        return -ENOMEM;
+    }
+
+    chip->log.bios_event_log_end = chip->log.bios_event_log + resource_size(&res);
+
+    return chip->flags & TPM_CHIP_FLAG_TPM2 ? EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 :
+        EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+}
+
   int tpm_read_log_of(struct tpm_chip *chip)
   {
       struct device_node *np;
@@ -39,7 +75,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
       sizep = of_get_property(np, "linux,sml-size", NULL);
       basep = of_get_property(np, "linux,sml-base", NULL);
       if (sizep == NULL && basep == NULL)
-        return -ENODEV;
+        return tpm_read_log_memory_region(chip);
       if (sizep == NULL || basep == NULL)
           return -EIO;
maintainer
#9 lore raw
Quoted 10 lines · Stefan Berger
Quoted 7 lines · Eddie James
Quoted 5 lines · Stefan Berger
Quoted 1 line · Eddie James

Some platforms may desire to pass the event log up to linux in the

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Which platforms are these that work like this?

Platforms booting from U-Boot without EFI. So at the moment, IBM's OpenBMC systems hope to use this.

It may be worth to mention this in the patch description in case someone wonders which systems would take that path.

+1

BR, Jarkko

maintainer
#10 lore raw
In reply to Eddie James
Quoted 74 lines · Eddie James

Some platforms may desire to pass the event log up to linux in the form of a reserved memory region. Add support for this in the TPM core to find the reserved memory region and map it.

---
 drivers/char/tpm/eventlog/of.c | 38 +++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)
drivers/char/tpm/eventlog/of.c +37 -1
index 741ab2204b11..c815cadf00a4 100644
@@ -12,12 +12,48 @@
 
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/tpm_eventlog.h>
 
 #include "../tpm.h"
 #include "common.h"
 
+static int tpm_read_log_memory_region(struct tpm_chip *chip)
+{
+	struct device_node *node;
+	struct resource res;
+	int rc;
+
+	node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
+	if (!node) {
+		dev_info(&chip->dev, "no phandle\n");
+		return -ENODEV;
+	}
+
+	rc = of_address_to_resource(node, 0, &res);
+	of_node_put(node);
+	if (rc) {
+		dev_info(&chip->dev, "no mem\n");
+		return rc;
+	}
+
+	chip->log.bios_event_log = devm_memremap(&chip->dev, res.start, resource_size(&res),
+						 MEMREMAP_WB);
+	if (!chip->log.bios_event_log) {
+		dev_info(&chip->dev, "err memremap\n");
+		return -ENOMEM;
+	}
+
+	chip->log.bios_event_log_end = chip->log.bios_event_log + resource_size(&res);
+
+	return chip->flags & TPM_CHIP_FLAG_TPM2 ? EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 :
+		EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+}
+
 int tpm_read_log_of(struct tpm_chip *chip)
 {
 	struct device_node *np;
@@ -39,7 +75,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
 	sizep = of_get_property(np, "linux,sml-size", NULL);
 	basep = of_get_property(np, "linux,sml-base", NULL);
 	if (sizep == NULL && basep == NULL)
-		return -ENODEV;
+		return tpm_read_log_memory_region(chip);
 	if (sizep == NULL || basep == NULL)
 		return -EIO;
 
Signature · 1 line
2.31.1

I would CC this to linux-devicetree.

BR, Jarkko