mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Re: [PATCH] tpm: crb: handle ACPI NVS memory region overlap
@ 2026-09-20  6:33 Delton Ding
  2026-09-25 14:24 ` Jarkko Sakkinen
  0 siblings, 1 reply; 9+ messages in thread
From: Delton Ding @ 2026-09-20  6:33 UTC (permalink / raw)
  To: jarkko, f13208471983; +Cc: linux-integrity, linux-kernel

Hi Jarkko and MicroFish,

I'm following up on this discussion:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2652132.html

I would like to add a Fujitsu/Intel platform with what appears to be a
related NVS resource reservation failure. I have not tested the proposed
patch; this is an additional hardware report.

Hardware and software:

  System: FUJITSU FMVU14003
  Board: FJNB2B5
  CPU: Intel Core i5-7300U (family 6, model 142, stepping 9)
  BIOS: Version 1.33, 11/25/2025
  OS: NixOS 26.05
  Running kernel: 7.2.5 (NixOS build)
  /proc/sys/kernel/tainted: 0

On this machine, the TPM2 table specifies StartMethod 2 (ACPI Start).
The control area, rather than the MMIO range reported by _CRS, lies
inside ACPI NVS:

  TPM2 table (length 52, revision 3, checksum valid):
    ControlAddress: 0x000000008ff6e000
    StartMethod:    2

  Relevant /proc/iomem entries:
    8d77f000-8ff7efff : ACPI Non-volatile Storage
    fed40000-fed44fff : MSFT0101:00

  The TPM SSDT declares _CRS with base 0xfed40000 and length 0x5000.
  It also contains:

    OperationRegion (TPMR, SystemMemory, 0xFED40000, 0x5000)
    OperationRegion (TNVS, SystemMemory, 0x8FF6F000, 0x27)
    OperationRegion (CONA, SystemMemory, 0x8FF6E000, 0x30)

The kernel reports:

  tpm_crb_acpi MSFT0101:00: error -EBUSY: can't request region for
resource [mem 0x8ff6e000-0x8ff6e02f]
  tpm_crb_acpi MSFT0101:00: probe with driver tpm_crb_acpi failed with error -16
  ima: No TPM chip found, activating TPM-bypass!

Neither /dev/tpm0 nor /dev/tpmrm0 exists, and both /sys/class/tpm and
/sys/class/tpmrm are empty. The ACPI device has status 15 and an existing
platform physical_node, so platform device creation itself succeeded.

Based on the ACPI tables and source inspection, this appears to reach the
iores == NULL path in crb_map_res() when crb_map_io() first maps the
48-byte control area. That area lies outside _CRS but within the NVS
reservation. This is an inference from the tables and error range;
I have not instrumented the driver to trace the call path.

Earlier boot logs show the same error and address on BIOS 1.10, 1.30
with kernel 7.2.6. I do not have a known-good Linux kernel on this machine,
so I am not reporting this as a confirmed regression. The TPM works in
Windows on the same machine; its TPM firmware has also been updated.
The vendor of the TPM is infineon, but the exact TPM firmware revision
has not been collected here.

The missing devices cause systemd 260.2 to wait 90 seconds in the initrd
and another 90 seconds after switching to the real root. We have prepared
systemd.tpm2_wait=0 as a local workaround for the boot delay; it does not
restore the TPM device.

Does this look like another instance of the NVS mapping issue, and is
there a preferred revised patch or targeted diagnostic for this ACPI
StartMethod 2 layout? I can provide the raw TPM2 table and TPM SSDT,
including its disassembly, if useful.

Best Regards,
Delton Ding

^ permalink raw reply	[flat|nested] 9+ messages in thread
* [PATCH] tpm: crb: handle ACPI NVS memory region overlap
@ 2026-08-27  3:55 microfish
  2026-08-28  2:04 ` Jarkko Sakkinen
  2026-09-25 14:42 ` Jarkko Sakkinen
  0 siblings, 2 replies; 9+ messages in thread
From: microfish @ 2026-08-27  3:55 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Peter Huewe, Jason Gunthorpe, linux-integrity, linux-kernel,
	stable, microfish, microfish

On certain Lenovo/AMD systems, the BIOS declares an ACPI NVS region
that covers a large memory range (e.g. 0xccc40000-0xccd3efff) which
includes the TPM CRB MMIO area (0xccd35000-0xccd38fff). The E820
subsystem registers this NVS region with IORESOURCE_BUSY in the
iomem_resource tree.

When tpm_crb probes, it calls devm_ioremap_resource() to map the CRB
registers, which internally calls devm_request_mem_region(). This fails
with -EBUSY because the NVS region already claims that address range.

Fix this by adding a crb_try_nvs_fallback() helper that detects the
ACPI NVS overlap using region_intersects() and falls back to
devm_memremap() when the resource falls inside ACPI NVS.
devm_memremap() does not require exclusive resource reservation,
making it safe to use on NVS-overlapping regions. This approach is
identical to the one used by the WDAT watchdog driver (wdat_wdt_map_mem).

The NVS fallback is applied in both code paths of crb_map_res():
1. When iores is NULL (no ACPI resource encompasses the target address)
2. When iores is non-NULL but devm_ioremap_resource() fails with EBUSY

Before this patch:
  tpm_crb MSFT0101:00: error -EBUSY: can't request region for resource
  [mem 0xccd35000-0xccd38fff]
  tpm_crb MSFT0101:00: probe with driver tpm_crb failed with error -16

After this patch:
  tpm_crb MSFT0101:00: [mem 0xccd35000-0xccd38fff] is inside ACPI NVS,
  mapping without reservation
  tpm_crb MSFT0101:00: of device registration complete, result 0: 0

Signed-off-by: microfish <microfish@kernel.org>
Signed-off-by: microfish <f13208471983@163.com>
---
 drivers/char/tpm/tpm_crb.c | 50 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index ceb4100ba..c4e8b925c 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -13,6 +13,7 @@
 
 #include <linux/acpi.h>
 #include <linux/highmem.h>
+#include <linux/mm.h>
 #include <linux/rculist.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -557,6 +558,39 @@ static int crb_check_resource(struct acpi_resource *ares, void *data)
 	return 1;
 }
 
+/*
+ * Try to map a resource region. If devm_ioremap_resource() fails with
+ * -EBUSY because the region falls inside an ACPI NVS area (common on
+ * certain Lenovo/AMD firmware), fall back to devm_memremap() which
+ * does not require exclusive resource reservation. This is analogous
+ * to the approach used by the WDAT watchdog driver (wdat_wdt_map_mem).
+ */
+static void __iomem *crb_try_nvs_fallback(struct device *dev, u64 start,
+					   u32 size)
+{
+	struct resource res = {
+		.start	= start,
+		.end	= start + size - 1,
+		.flags	= IORESOURCE_MEM,
+	};
+	void *addr;
+
+	if (region_intersects(res.start, resource_size(&res), IORESOURCE_MEM,
+			     IORES_DESC_ACPI_NV_STORAGE) !=
+			     REGION_INTERSECTS)
+		return NULL;
+
+	dev_warn(dev,
+		 "%pR is inside ACPI NVS, mapping without reservation\n",
+		 &res);
+
+	addr = devm_memremap(dev, res.start, resource_size(&res), MEMREMAP_WB);
+	if (IS_ERR(addr))
+		return IOMEM_ERR_PTR(PTR_ERR(addr));
+
+	return (void __iomem __force *)addr;
+}
+
 static void __iomem *crb_map_res(struct device *dev, struct resource *iores,
 				 void __iomem **iobase_ptr, u64 start, u32 size)
 {
@@ -565,18 +599,30 @@ static void __iomem *crb_map_res(struct device *dev, struct resource *iores,
 		.end	= start + size - 1,
 		.flags	= IORESOURCE_MEM,
 	};
+	void __iomem *p;
 
 	/* Detect a 64 bit address on a 32 bit system */
 	if (start != new_res.start)
 		return IOMEM_ERR_PTR(-EINVAL);
 
-	if (!iores)
+	if (!iores) {
+		p = crb_try_nvs_fallback(dev, start, size);
+		if (p)
+			return p;
 		return devm_ioremap_resource(dev, &new_res);
+	}
 
 	if (!*iobase_ptr) {
 		*iobase_ptr = devm_ioremap_resource(dev, iores);
-		if (IS_ERR(*iobase_ptr))
+		if (IS_ERR(*iobase_ptr)) {
+			p = crb_try_nvs_fallback(dev, iores->start,
+						 resource_size(iores));
+			if (p) {
+				*iobase_ptr = p;
+				return p + (new_res.start - iores->start);
+			}
 			return *iobase_ptr;
+		}
 	}
 
 	return *iobase_ptr + (new_res.start - iores->start);
-- 
2.47.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-09-25 14:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20  6:33 [PATCH] tpm: crb: handle ACPI NVS memory region overlap Delton Ding
2026-09-25 14:24 ` Jarkko Sakkinen
2026-09-25 14:42   ` Jarkko Sakkinen
  -- strict thread matches above, loose matches on Subject: below --
2026-08-27  3:55 microfish
2026-08-28  2:04 ` Jarkko Sakkinen
2026-08-28 11:11   ` MicroFish
2026-09-01 12:57     ` Jarkko Sakkinen
2026-09-01 14:35       ` Jarkko Sakkinen
2026-09-25 14:42 ` Jarkko Sakkinen

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®