* [PATCH v1 0/2] x86/tboot: Add Intel TXT Protection Regions (TPR) support
@ 2026-06-03 11:44 Michal Camacho Romero
2026-06-03 11:44 ` [PATCH v1 1/2] x86/tboot: Add support for parsing DTPR table and disabling TPRs Michal Camacho Romero
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
0 siblings, 2 replies; 7+ messages in thread
From: Michal Camacho Romero @ 2026-06-03 11:44 UTC (permalink / raw)
To: Lu Baolu, Ning Sun, Thomas Gleixner
Cc: x86, iommu, tboot-devel, linux-kernel, Mateusz Mowka,
Adam Pawlicki, Pawel Randzio, Michal Camacho Romero
Intel TXT Protection Regions (TPRs) are a new hardware mechanism for
DMA protection that replaces Protected Memory Regions
(PMRs). TPRs are configured by the SINIT ACM and managed through the
DTPR table in the TXT heap's extended data elements.
This series adds kernel support for detecting and disabling TPRs during
early boot, allowing the kernel to take over DMA protection management
via the IOMMU.
Patch No.1 adds the TXT heap parsing logic to locate the DTPR table and
disable each TPR instance by setting the enable bit (BIT14 in TPRn_BASE
register).
Patch No.2 integrates TPR detection into the IOMMU initialization path:
skipping force-IOMMU, when TPRs provide DMA protection and tearing down
redundant PMRs.
Tested on Intel platforms with SINIT ACM supporting ACPI DTPR tables.
Documentation:
- Intel TXT DMA Protection Ranges, rev 0.73
https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
- Intel TXT MLE Developer's Guide, rev 017
https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
Michal Camacho Romero (2):
x86/tboot: Add support for parsing DTPR table and disabling TPRs
iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
arch/x86/kernel/tboot.c | 146 ++++++++++++++++++++++++++++++++----
drivers/iommu/intel/dmar.c | 12 +++
drivers/iommu/intel/iommu.c | 8 +-
include/linux/tboot.h | 10 +++
4 files changed, 160 insertions(+), 16 deletions(-)
--
2.53.0
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v1 1/2] x86/tboot: Add support for parsing DTPR table and disabling TPRs
2026-06-03 11:44 [PATCH v1 0/2] x86/tboot: Add Intel TXT Protection Regions (TPR) support Michal Camacho Romero
@ 2026-06-03 11:44 ` Michal Camacho Romero
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
1 sibling, 0 replies; 7+ messages in thread
From: Michal Camacho Romero @ 2026-06-03 11:44 UTC (permalink / raw)
To: Lu Baolu, Ning Sun, Thomas Gleixner
Cc: x86, iommu, tboot-devel, linux-kernel, Mateusz Mowka,
Adam Pawlicki, Pawel Randzio, Michal Camacho Romero
Add functions to locate and parse the DMA TXT Protection Ranges (DTPR)
table from the TXT heap's SinitMleData extended data elements (requires
SINIT MLE version >= 9).
* tboot_get_dtpr_table() - function walks through the TXT heap to find
the DTPR extended data element
(type HEAP_EXTDATA_TYPE_DTPR) and returns
pointer to the DTPR table.
* tboot_parse_dtpr_table() - function iterates over TPR instances and
disables each TPR region by setting bit 4
in the TPRn_BASE register via MMIO.
Using these functions will allow the kernel to deactivate SINIT
ACM-established TPRs prior to the Linux OS launch.
Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
---
arch/x86/kernel/tboot.c | 146 +++++++++++++++++++++++++++++++++++-----
include/linux/tboot.h | 10 +++
2 files changed, 141 insertions(+), 15 deletions(-)
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 46b8f1f16676..8825e5ee916c 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/tboot.h>
#include <linux/debugfs.h>
+#include <acpi/actbl1.h>
#include <asm/realmode.h>
#include <asm/processor.h>
@@ -453,22 +454,30 @@ struct sha1_hash {
u8 hash[SHA1_SIZE];
};
+struct heap_ext_data_elt {
+ u32 type;
+ u32 size;
+ u8 data[];
+} __packed;
+
struct sinit_mle_data {
- u32 version; /* currently 6 */
- struct sha1_hash bios_acm_id;
- u32 edx_senter_flags;
- u64 mseg_valid;
- struct sha1_hash sinit_hash;
- struct sha1_hash mle_hash;
- struct sha1_hash stm_hash;
- struct sha1_hash lcp_policy_hash;
- u32 lcp_policy_control;
- u32 rlp_wakeup_addr;
- u32 reserved;
- u32 num_mdrs;
- u32 mdrs_off;
- u32 num_vtd_dmars;
- u32 vtd_dmars_off;
+ u32 version; /* currently 9 */
+ struct sha1_hash bios_acm_id;
+ u32 edx_senter_flags;
+ u64 mseg_valid;
+ struct sha1_hash sinit_hash;
+ struct sha1_hash mle_hash;
+ struct sha1_hash stm_hash;
+ struct sha1_hash lcp_policy_hash;
+ u32 lcp_policy_control;
+ u32 rlp_wakeup_addr;
+ u32 reserved;
+ u32 num_mdrs;
+ u32 mdrs_off;
+ u32 num_vtd_dmars;
+ u32 vtd_dmars_off;
+ u32 proc_scrtm_status; /* version 8 or later only*/
+ struct heap_ext_data_elt ext_data_elts[];
} __packed;
struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tbl)
@@ -514,3 +523,110 @@ struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tb
return dmar_tbl;
}
+
+struct acpi_table_dtpr *tboot_get_dtpr_table(void **heap_base)
+{
+ void *heap_ptr, *config;
+ struct sinit_mle_data *sinit_mle;
+ struct heap_ext_data_elt *elt;
+ u64 sinit_mle_size;
+
+ if (!heap_base)
+ return NULL;
+
+ if (!tboot_enabled())
+ return NULL;
+ /*
+ * ACPI tables may not be DMA protected by tboot, so use DMAR copy
+ * SINIT saved in SinitMleData in TXT heap (which is DMA protected)
+ */
+
+ /* map config space in order to get heap addr */
+ config = ioremap(TXT_PUB_CONFIG_REGS_BASE, NR_TXT_CONFIG_PAGES *
+ PAGE_SIZE);
+ if (!config)
+ return NULL;
+
+ /* now map TXT heap */
+ *heap_base = ioremap(*(u64 *)(config + TXTCR_HEAP_BASE),
+ *(u64 *)(config + TXTCR_HEAP_SIZE));
+ iounmap(config);
+
+ if (!(*heap_base))
+ return NULL;
+
+ /* walk heap to SinitMleData */
+ /* skip BiosData */
+ heap_ptr = *heap_base + *(u64 *) (*heap_base);
+ /* skip OsMleData */
+ heap_ptr += *(u64 *)heap_ptr;
+ /* skip OsSinitData */
+ heap_ptr += *(u64 *)heap_ptr;
+ /* now points to SinitMleDataSize; set to SinitMleData */
+ sinit_mle_size = *(u64 *)heap_ptr;
+ heap_ptr += sizeof(u64);
+
+ sinit_mle = (struct sinit_mle_data *)heap_ptr;
+ if (sinit_mle->version < 9) {
+ iounmap(*heap_base);
+ return NULL;
+ }
+
+ elt = sinit_mle->ext_data_elts;
+ while (elt->type != HEAP_EXTDATA_TYPE_DTPR &&
+ elt->type != HEAP_EXTDATA_TYPE_END) {
+ elt = (void *)elt + elt->size;
+ if ((u64)elt > (u64)sinit_mle + sinit_mle_size) {
+ iounmap(*heap_base);
+ return NULL;
+ }
+ }
+
+ return (struct acpi_table_dtpr *)elt->data;
+}
+
+static bool tboot_tpr_enabled = false;
+void tboot_parse_dtpr_table(struct acpi_table_dtpr *dtpr)
+{
+ struct acpi_tpr_instance *tpr_inst;
+ struct acpi_tpr_array *tpr_arr;
+ u32 *instance_cnt;
+ u64 *base;
+ u32 i, j;
+
+ if (!tboot_enabled())
+ return;
+
+ tboot_tpr_enabled = true;
+ instance_cnt = (u32*)(&dtpr->ins_cnt);
+ tpr_inst = (struct acpi_tpr_instance *)(instance_cnt + 1);
+ for (i = 0; i < *instance_cnt; ++i) {
+ for (j = 0; j < tpr_inst->tpr_cnt; ++j) {
+ tpr_arr = (struct acpi_tpr_array*)((u8*) tpr_inst +
+ sizeof(struct acpi_tpr_instance) +
+ j * sizeof(struct acpi_tpr_array));
+
+ base = ioremap(tpr_arr->base, 16);
+ if (!base) {
+ pr_warn("TPR Instance %d, TPR No.%d disabling failure.\n", i, j);
+ continue;
+ }
+
+ pr_info("TPR instance %d, TPR %d:base %llx limit %llx\n", i, j,
+ readq(base), readq(base + 1));
+ writeq(readq(base) | BIT(4), base);
+ iounmap(base);
+ }
+
+ tpr_inst = (struct acpi_tpr_instance *)((u8*)tpr_inst +
+ sizeof(*tpr_inst) + j * sizeof(struct acpi_tpr_array));
+ }
+
+ if (tboot_tpr_enabled)
+ pr_debug("TPR protection detected, PMR will be disabled\n");
+}
+
+bool tboot_is_tpr_enabled(void)
+{
+ return tboot_tpr_enabled;
+}
diff --git a/include/linux/tboot.h b/include/linux/tboot.h
index d2279160ef39..39fb2e3ba80b 100644
--- a/include/linux/tboot.h
+++ b/include/linux/tboot.h
@@ -24,6 +24,10 @@ enum {
#include <linux/acpi.h>
/* used to communicate between tboot and the launched kernel */
+/*TXT Extended Data Element Types*/
+#define HEAP_EXTDATA_TYPE_END 0
+#define HEAP_EXTDATA_TYPE_DTPR 14
+
#define TB_KEY_SIZE 64 /* 512 bits */
#define MAX_TB_MAC_REGIONS 32
@@ -126,6 +130,9 @@ extern void tboot_probe(void);
extern void tboot_shutdown(u32 shutdown_type);
extern struct acpi_table_header *tboot_get_dmar_table(
struct acpi_table_header *dmar_tbl);
+extern struct acpi_table_dtpr *tboot_get_dtpr_table(void **);
+extern void tboot_parse_dtpr_table(struct acpi_table_dtpr *);
+extern bool tboot_is_tpr_enabled(void);
#else
@@ -135,6 +142,9 @@ extern struct acpi_table_header *tboot_get_dmar_table(
#define tboot_sleep(sleep_state, pm1a_control, pm1b_control) \
do { } while (0)
#define tboot_get_dmar_table(dmar_tbl) (dmar_tbl)
+#define tboot_get_dtpr_table(txt_heap) NULL
+#define tboot_parse_dtpr_table(dtpr) do { } while (0)
+#define tboot_is_tpr_enabled() 0
#endif /* !CONFIG_INTEL_TXT */
--
2.53.0
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
2026-06-03 11:44 [PATCH v1 0/2] x86/tboot: Add Intel TXT Protection Regions (TPR) support Michal Camacho Romero
2026-06-03 11:44 ` [PATCH v1 1/2] x86/tboot: Add support for parsing DTPR table and disabling TPRs Michal Camacho Romero
@ 2026-06-03 11:45 ` Michal Camacho Romero
2026-06-11 8:49 ` Baolu Lu
` (2 more replies)
1 sibling, 3 replies; 7+ messages in thread
From: Michal Camacho Romero @ 2026-06-03 11:45 UTC (permalink / raw)
To: Lu Baolu, Ning Sun, Thomas Gleixner
Cc: x86, iommu, tboot-devel, linux-kernel, Mateusz Mowka,
Adam Pawlicki, Pawel Randzio, Michal Camacho Romero
When Intel TXT Protection Regions (TPRs) are present in the DTPR table,
hardware-level DMA protection is already enforced by the SINIT ACM.
In this case:
- Skip forcing IOMMU enablement in tboot_force_iommu(), since TPRs
already provide DMA protection.
- Tear down PMRs during intel_iommu_init() when TPRs are active,
while PMRs are redundant with TPR-based protection.
- Call tboot_parse_dtpr_table() from parse_dmar_table() to disable
TPR regions early, allowing the kernel to manage DMA protection
prior to the OS boot.
Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
---
drivers/iommu/intel/dmar.c | 12 ++++++++++++
drivers/iommu/intel/iommu.c | 8 +++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index d33c119a935e..3ab09117c79e 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -635,6 +635,8 @@ static int __init
parse_dmar_table(void)
{
struct acpi_table_dmar *dmar;
+ struct acpi_table_dtpr *dtpr;
+ void *txt_heap;
int drhd_count = 0;
int ret;
struct dmar_res_callback cb = {
@@ -670,6 +672,16 @@ parse_dmar_table(void)
return -EINVAL;
}
+ dtpr = tboot_get_dtpr_table(&txt_heap);
+ if (dtpr) {
+ /* TPR is enabled
+ * This will also tell not to establish IOMMU PMRs
+ */
+ tboot_parse_dtpr_table(dtpr);
+ iounmap(txt_heap);
+ }
+
+ txt_heap = NULL;
pr_info("Host address width %d\n", dmar->width + 1);
ret = dmar_walk_dmar_table(dmar, &cb);
if (ret == 0 && drhd_count == 0)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 4d0e65bc131d..486693a13dc6 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2540,6 +2540,12 @@ static __init int tboot_force_iommu(void)
if (!tboot_enabled())
return 0;
+ /* If TPR is enabled we don't need to force IOMMU,
+ * TPR set by SINIT ACM will take care of DMA protection
+ */
+ if (tboot_is_tpr_enabled())
+ return 0;
+
if (no_iommu || dmar_disabled)
pr_warn("Forcing Intel-IOMMU to enabled\n");
@@ -2597,7 +2603,7 @@ int __init intel_iommu_init(void)
* calling SENTER, but the kernel is expected to reset/tear
* down the PMRs.
*/
- if (intel_iommu_tboot_noforce) {
+ if (intel_iommu_tboot_noforce || tboot_is_tpr_enabled()) {
for_each_iommu(iommu, drhd)
iommu_disable_protect_mem_regions(iommu);
}
--
2.53.0
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
@ 2026-06-11 8:49 ` Baolu Lu
2026-08-07 9:16 ` [PATCH v2 " Michal Camacho Romero
2026-08-07 10:14 ` Michal Camacho Romero
2 siblings, 0 replies; 7+ messages in thread
From: Baolu Lu @ 2026-06-11 8:49 UTC (permalink / raw)
To: Michal Camacho Romero, Ning Sun, Thomas Gleixner
Cc: baolu.lu, x86, iommu, tboot-devel, linux-kernel, Mateusz Mowka,
Adam Pawlicki, Pawel Randzio
On 6/3/2026 7:45 PM, Michal Camacho Romero wrote:
> When Intel TXT Protection Regions (TPRs) are present in the DTPR table,
> hardware-level DMA protection is already enforced by the SINIT ACM.
> In this case:
>
> - Skip forcing IOMMU enablement in tboot_force_iommu(), since TPRs
> already provide DMA protection.
> - Tear down PMRs during intel_iommu_init() when TPRs are active,
> while PMRs are redundant with TPR-based protection.
> - Call tboot_parse_dtpr_table() from parse_dmar_table() to disable
> TPR regions early, allowing the kernel to manage DMA protection
> prior to the OS boot.
>
> Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
> Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
> Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
> ---
> drivers/iommu/intel/dmar.c | 12 ++++++++++++
> drivers/iommu/intel/iommu.c | 8 +++++++-
> 2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index d33c119a935e..3ab09117c79e 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -635,6 +635,8 @@ static int __init
> parse_dmar_table(void)
> {
> struct acpi_table_dmar *dmar;
> + struct acpi_table_dtpr *dtpr;
> + void *txt_heap;
Please avoid using extra whitespace before the variable name. Just use:
void *txt_heap;
> int drhd_count = 0;
> int ret;
> struct dmar_res_callback cb = {
> @@ -670,6 +672,16 @@ parse_dmar_table(void)
> return -EINVAL;
> }
>
> + dtpr = tboot_get_dtpr_table(&txt_heap);
> + if (dtpr) {
> + /* TPR is enabled
> + * This will also tell not to establish IOMMU PMRs
> + */
Please use the standard kernel multiple-line comment format:
/*
* TPR is enabled. This will also tell not to establish IOMMU
* PMRs.
*/
> + tboot_parse_dtpr_table(dtpr);
> + iounmap(txt_heap);
> + }
> +
> + txt_heap = NULL;
> pr_info("Host address width %d\n", dmar->width + 1);
> ret = dmar_walk_dmar_table(dmar, &cb);
> if (ret == 0 && drhd_count == 0)
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 4d0e65bc131d..486693a13dc6 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2540,6 +2540,12 @@ static __init int tboot_force_iommu(void)
> if (!tboot_enabled())
> return 0;
>
> + /* If TPR is enabled we don't need to force IOMMU,
> + * TPR set by SINIT ACM will take care of DMA protection
> + */
Ditto.
> + if (tboot_is_tpr_enabled())
> + return 0;
> +
> if (no_iommu || dmar_disabled)
> pr_warn("Forcing Intel-IOMMU to enabled\n");
>
> @@ -2597,7 +2603,7 @@ int __init intel_iommu_init(void)
> * calling SENTER, but the kernel is expected to reset/tear
> * down the PMRs.
> */
> - if (intel_iommu_tboot_noforce) {
> + if (intel_iommu_tboot_noforce || tboot_is_tpr_enabled()) {
> for_each_iommu(iommu, drhd)
> iommu_disable_protect_mem_regions(iommu);
> }
With these nits fixed:
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
2026-06-11 8:49 ` Baolu Lu
@ 2026-08-07 9:16 ` Michal Camacho Romero
2026-08-07 10:14 ` Michal Camacho Romero
2 siblings, 0 replies; 7+ messages in thread
From: Michal Camacho Romero @ 2026-08-07 9:16 UTC (permalink / raw)
To: Baolu Lu, Ning Sun, Thomas Gleixner
Cc: Michal Camacho Romero, x86, iommu, tboot-devel, linux-kernel,
Mateusz Mowka, Adam Pawlicki, Pawel Randzio
When Intel TXT Protection Regions (TPRs) are present in the DTPR table,
hardware-level DMA protection is already enforced by the SINIT ACM.
In this case:
- Skip forcing IOMMU enablement in tboot_force_iommu(), since TPRs
already provide DMA protection.
- Tear down PMRs during intel_iommu_init() when TPRs are active,
while PMRs are redundant with TPR-based protection.
- Call tboot_parse_dtpr_table() from parse_dmar_table() to disable
TPR regions early, allowing the kernel to manage DMA protection
prior to the OS boot.
Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
---
drivers/iommu/intel/dmar.c | 13 +++++++++++++
drivers/iommu/intel/iommu.c | 9 ++++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 767ec092accd..17c26d222253 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -635,6 +635,8 @@ static int __init
parse_dmar_table(void)
{
struct acpi_table_dmar *dmar;
+ struct acpi_table_dtpr *dtpr;
+ void *txt_heap;
int drhd_count = 0;
int ret;
struct dmar_res_callback cb = {
@@ -670,6 +672,17 @@ parse_dmar_table(void)
return -EINVAL;
}
+ dtpr = tboot_get_dtpr_table(&txt_heap);
+ if (dtpr) {
+ /*
+ * TPR is enabled. This will also tell not to establish IOMMU
+ * PMRs.
+ */
+ tboot_parse_dtpr_table(dtpr);
+ iounmap(txt_heap);
+ }
+
+ txt_heap = NULL;
pr_info("Host address width %d\n", dmar->width + 1);
ret = dmar_walk_dmar_table(dmar, &cb);
if (ret == 0 && drhd_count == 0)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 849d06dfe1ae..5bc6f2dd25c4 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2543,6 +2543,13 @@ static __init int tboot_force_iommu(void)
if (!tboot_enabled())
return 0;
+ /*
+ * If TPR is enabled we don't need to force IOMMU, TPR set by SINIT
+ * ACM will take care of DMA protection.
+ */
+ if (tboot_is_tpr_enabled())
+ return 0;
+
if (no_iommu || dmar_disabled)
pr_warn("Forcing Intel-IOMMU to enabled\n");
@@ -2600,7 +2607,7 @@ int __init intel_iommu_init(void)
* calling SENTER, but the kernel is expected to reset/tear
* down the PMRs.
*/
- if (intel_iommu_tboot_noforce) {
+ if (intel_iommu_tboot_noforce || tboot_is_tpr_enabled()) {
for_each_iommu(iommu, drhd)
iommu_disable_protect_mem_regions(iommu);
}
--
2.55.0
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
2026-06-11 8:49 ` Baolu Lu
2026-08-07 9:16 ` [PATCH v2 " Michal Camacho Romero
@ 2026-08-07 10:14 ` Michal Camacho Romero
2026-08-20 3:28 ` Baolu Lu
2 siblings, 1 reply; 7+ messages in thread
From: Michal Camacho Romero @ 2026-08-07 10:14 UTC (permalink / raw)
To: Baolu Lu, Ning Sun, Thomas Gleixner
Cc: Michal Camacho Romero, x86, iommu, tboot-devel, linux-kernel,
Mateusz Mowka, Adam Pawlicki, Pawel Randzio
From: Michal Camacho Romero <michal.camacho.romero@intel.com>
When Intel TXT Protection Regions (TPRs) are present in the DTPR table,
hardware-level DMA protection is already enforced by the SINIT ACM.
In this case:
- Skip forcing IOMMU enablement in tboot_force_iommu(), since TPRs
already provide DMA protection.
- Tear down PMRs during intel_iommu_init() when TPRs are active,
while PMRs are redundant with TPR-based protection.
- Call tboot_parse_dtpr_table() from parse_dmar_table() to disable
TPR regions early, allowing the kernel to manage DMA protection
prior to the OS boot.
Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
---
drivers/iommu/intel/dmar.c | 13 +++++++++++++
drivers/iommu/intel/iommu.c | 9 ++++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 767ec092accd..17c26d222253 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -635,6 +635,8 @@ static int __init
parse_dmar_table(void)
{
struct acpi_table_dmar *dmar;
+ struct acpi_table_dtpr *dtpr;
+ void *txt_heap;
int drhd_count = 0;
int ret;
struct dmar_res_callback cb = {
@@ -670,6 +672,17 @@ parse_dmar_table(void)
return -EINVAL;
}
+ dtpr = tboot_get_dtpr_table(&txt_heap);
+ if (dtpr) {
+ /*
+ * TPR is enabled. This will also tell not to establish IOMMU
+ * PMRs.
+ */
+ tboot_parse_dtpr_table(dtpr);
+ iounmap(txt_heap);
+ }
+
+ txt_heap = NULL;
pr_info("Host address width %d\n", dmar->width + 1);
ret = dmar_walk_dmar_table(dmar, &cb);
if (ret == 0 && drhd_count == 0)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 849d06dfe1ae..5bc6f2dd25c4 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2543,6 +2543,13 @@ static __init int tboot_force_iommu(void)
if (!tboot_enabled())
return 0;
+ /*
+ * If TPR is enabled we don't need to force IOMMU, TPR set by SINIT
+ * ACM will take care of DMA protection.
+ */
+ if (tboot_is_tpr_enabled())
+ return 0;
+
if (no_iommu || dmar_disabled)
pr_warn("Forcing Intel-IOMMU to enabled\n");
@@ -2600,7 +2607,7 @@ int __init intel_iommu_init(void)
* calling SENTER, but the kernel is expected to reset/tear
* down the PMRs.
*/
- if (intel_iommu_tboot_noforce) {
+ if (intel_iommu_tboot_noforce || tboot_is_tpr_enabled()) {
for_each_iommu(iommu, drhd)
iommu_disable_protect_mem_regions(iommu);
}
--
2.55.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active
2026-08-07 10:14 ` Michal Camacho Romero
@ 2026-08-20 3:28 ` Baolu Lu
0 siblings, 0 replies; 7+ messages in thread
From: Baolu Lu @ 2026-08-20 3:28 UTC (permalink / raw)
To: Michal Camacho Romero, Ning Sun, Thomas Gleixner
Cc: Michal Camacho Romero, x86, iommu, tboot-devel, linux-kernel,
Mateusz Mowka, Adam Pawlicki, Pawel Randzio
On 8/7/26 18:14, Michal Camacho Romero wrote:
> From: Michal Camacho Romero <michal.camacho.romero@intel.com>
>
> When Intel TXT Protection Regions (TPRs) are present in the DTPR table,
> hardware-level DMA protection is already enforced by the SINIT ACM.
> In this case:
>
> - Skip forcing IOMMU enablement in tboot_force_iommu(), since TPRs
> already provide DMA protection.
> - Tear down PMRs during intel_iommu_init() when TPRs are active,
> while PMRs are redundant with TPR-based protection.
> - Call tboot_parse_dtpr_table() from parse_dmar_table() to disable
> TPR regions early, allowing the kernel to manage DMA protection
> prior to the OS boot.
>
> Link: https://uefi.org/sites/default/files/resources/633933_Intel_TXT_DMA_Protection_Ranges_rev_0p73.pdf
> Link: https://cdrdv2-public.intel.com/315168/315168_TXT_MLE_DG_rev_017_7.pdf
> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
> Signed-off-by: Michal Camacho Romero <michal.camacho.romero@intel.com>
> ---
> drivers/iommu/intel/dmar.c | 13 +++++++++++++
> drivers/iommu/intel/iommu.c | 9 ++++++++-
> 2 files changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index 767ec092accd..17c26d222253 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -635,6 +635,8 @@ static int __init
> parse_dmar_table(void)
> {
> struct acpi_table_dmar *dmar;
> + struct acpi_table_dtpr *dtpr;
> + void *txt_heap;
> int drhd_count = 0;
> int ret;
> struct dmar_res_callback cb = {
> @@ -670,6 +672,17 @@ parse_dmar_table(void)
> return -EINVAL;
> }
>
> + dtpr = tboot_get_dtpr_table(&txt_heap);
> + if (dtpr) {
> + /*
> + * TPR is enabled. This will also tell not to establish IOMMU
> + * PMRs.
> + */
> + tboot_parse_dtpr_table(dtpr);
> + iounmap(txt_heap);
> + }
> +
> + txt_heap = NULL;
> pr_info("Host address width %d\n", dmar->width + 1);
> ret = dmar_walk_dmar_table(dmar, &cb);
> if (ret == 0 && drhd_count == 0)
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 849d06dfe1ae..5bc6f2dd25c4 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2543,6 +2543,13 @@ static __init int tboot_force_iommu(void)
This patch doesn't apply cleanly on top of the recent mainline tree —
tboot_force_iommu() has been refactored by a recent merge. Please rebase
and re-post it after 7.3-rc1.
> if (!tboot_enabled())
> return 0;
>
> + /*
> + * If TPR is enabled we don't need to force IOMMU, TPR set by SINIT
> + * ACM will take care of DMA protection.
> + */
> + if (tboot_is_tpr_enabled())
> + return 0;
> +
> if (no_iommu || dmar_disabled)
> pr_warn("Forcing Intel-IOMMU to enabled\n");
>
> @@ -2600,7 +2607,7 @@ int __init intel_iommu_init(void)
> * calling SENTER, but the kernel is expected to reset/tear
> * down the PMRs.
> */
> - if (intel_iommu_tboot_noforce) {
> + if (intel_iommu_tboot_noforce || tboot_is_tpr_enabled()) {
> for_each_iommu(iommu, drhd)
> iommu_disable_protect_mem_regions(iommu);
> }
Thanks,
baolu
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-20 3:28 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-03 11:44 [PATCH v1 0/2] x86/tboot: Add Intel TXT Protection Regions (TPR) support Michal Camacho Romero
2026-06-03 11:44 ` [PATCH v1 1/2] x86/tboot: Add support for parsing DTPR table and disabling TPRs Michal Camacho Romero
2026-06-03 11:45 ` [PATCH v1 2/2] iommu/vt-d: Disable PMRs and skip force-IOMMU when TXT TPRs are active Michal Camacho Romero
2026-06-11 8:49 ` Baolu Lu
2026-08-07 9:16 ` [PATCH v2 " Michal Camacho Romero
2026-08-07 10:14 ` Michal Camacho Romero
2026-08-20 3:28 ` Baolu Lu
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®