* [PATCH 0/9] iommu/vt-d: Support a new DMAR flag
@ 2026-06-04 5:15 Kevin Tian
2026-06-04 5:15 ` [PATCH 1/9] iommu/vt-d: Fix no_iommu to disable platform optin Kevin Tian
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
VT-d spec v5.2 introduces a new DMA_REMAP_OPT_OUT flag in the DMAR
table, adding another knob to affect whether the DMA remapping
capability should be turned on or off.
While at it, first clean up the existing on/off policy messed with
user opts and various force_on conditions in the first 8 patches.
On top of the improved framework, the last patch introduces the
support of the new bit.
Kevin Tian (9):
iommu/vt-d: Fix no_iommu to disable platform optin
iommu/vt-d: Force requesting ACS when tboot is enabled
iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set
iommu/vt-d: Consolidate dmar state management and force_on logic
iommu/vt-d: Use dmar_can_force_on() for platform optin
iommu/vt-d: Call dmar_can_force_on() for tboot optin
iommu/vt-d: Remove the 'force_on' variable
iommu/vt-d: Remove dmar_disabled
iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit
drivers/iommu/intel/dmar.c | 92 +++++++++++++++++++++++++++++++++----
drivers/iommu/intel/iommu.c | 73 ++++++++++++++---------------
drivers/iommu/intel/iommu.h | 64 +++++++++++++++++++++-----
drivers/iommu/intel/svm.c | 2 +-
include/linux/dmar.h | 1 +
5 files changed, 173 insertions(+), 59 deletions(-)
base-commit: 6f3ed7fec72fc8979b2a8c7219c0a9fcfc8d07b5
--
2.43.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/9] iommu/vt-d: Fix no_iommu to disable platform optin
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-04 5:15 ` [PATCH 2/9] iommu/vt-d: Force requesting ACS when tboot is enabled Kevin Tian
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel,
stable
If user explicitly requests to disable iommu (via "iommu=off" or
"intel_iommu=off"), there is no reason to force enabling it due
to platform optin (for external-facing devices). User should be
aware of any security implication of doing so.
"intel_iommu=off" implements this policy by setting no_platform_optin
to skip platform optin in platform_optin_force_iommu().
However, "iommu=off" (no_iommu=1) doesn't set no_platform_optin
hence is broken in this aspect:
- detect_intel_iommu() doesn't request ACS if no_iommu=1
- platform_optin_force_iommu() forces iommu on if external-facing
devices exist and no_platform_optin is not set
This leads to a bad configuration with ACS disabled while DMA
remapping is enabled.
Instead of setting no_platform_optin (will soon be removed) for
no_iommu=1, directly check no_iommu in platform_optin_force_iommu().
Fixes: 89a6079df791 ("iommu/vt-d: Force IOMMU on for platform opt in hint")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 4d0e65bc131d..9584ac0ed02f 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2479,10 +2479,11 @@ static bool has_external_pci(void)
static int __init platform_optin_force_iommu(void)
{
- if (!dmar_platform_optin() || no_platform_optin || !has_external_pci())
+ if (no_iommu || !dmar_platform_optin() || no_platform_optin ||
+ !has_external_pci())
return 0;
- if (no_iommu || dmar_disabled)
+ if (dmar_disabled)
pr_info("Intel-IOMMU force enabled due to platform opt in\n");
/*
@@ -2493,7 +2494,6 @@ static int __init platform_optin_force_iommu(void)
iommu_set_default_passthrough(false);
dmar_disabled = 0;
- no_iommu = 0;
return 1;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/9] iommu/vt-d: Force requesting ACS when tboot is enabled
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
2026-06-04 5:15 ` [PATCH 1/9] iommu/vt-d: Fix no_iommu to disable platform optin Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-04 5:15 ` [PATCH 3/9] iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set Kevin Tian
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel,
stable
Currently the conditions of requesting ACS in detect_intel_iommu()
don't include tboot, leading to a possible misconfiguration with ACS
disabled (e.g. due to user opts) while iommu is later forced on by
tboot_force_iommu().
Fix it by checking tboot in detect_intel_iommu().
Fixes: 5d990b627537 ("PCI: add pci_request_acs")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/dmar.c | 15 +++++++++++++--
drivers/iommu/intel/iommu.c | 2 +-
drivers/iommu/intel/iommu.h | 2 ++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index d33c119a935e..e8f01e56cf46 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -915,6 +915,18 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
return 0;
}
+static bool dmar_required(void)
+{
+ /* tboot supersedes any user/platform opt */
+ if (!intel_iommu_tboot_noforce && tboot_enabled())
+ return true;
+
+ if (!no_iommu && (!dmar_disabled || dmar_platform_optin()))
+ return true;
+
+ return false;
+}
+
void __init detect_intel_iommu(void)
{
int ret;
@@ -928,8 +940,7 @@ void __init detect_intel_iommu(void)
if (!ret)
ret = dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl,
&validate_drhd_cb);
- if (!ret && !no_iommu && !iommu_detected &&
- (!dmar_disabled || dmar_platform_optin())) {
+ if (!ret && !iommu_detected && dmar_required()) {
iommu_detected = 1;
/* Make sure ACS will be enabled */
pci_request_acs();
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 9584ac0ed02f..0365ff4e5092 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -57,7 +57,7 @@ static int rwbf_quirk;
* (used when kernel is launched w/ TXT)
*/
static int force_on = 0;
-static int intel_iommu_tboot_noforce;
+int intel_iommu_tboot_noforce;
static int no_platform_optin;
#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index ef145560aa98..e0ac9efa1aa9 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1343,6 +1343,7 @@ static inline bool ecmd_has_pmu_essential(struct intel_iommu *iommu)
extern int dmar_disabled;
extern int intel_iommu_enabled;
+extern int intel_iommu_tboot_noforce;
#else
static inline int iommu_calculate_agaw(struct intel_iommu *iommu)
{
@@ -1355,6 +1356,7 @@ static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
#define dmar_disabled (1)
#define intel_iommu_enabled (0)
#define intel_iommu_sm (0)
+#define intel_iommu_tboot_noforce (0)
#endif
static inline const char *decode_prq_descriptor(char *str, size_t size,
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/9] iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
2026-06-04 5:15 ` [PATCH 1/9] iommu/vt-d: Fix no_iommu to disable platform optin Kevin Tian
2026-06-04 5:15 ` [PATCH 2/9] iommu/vt-d: Force requesting ACS when tboot is enabled Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-04 5:15 ` [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic Kevin Tian
` (5 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
Those are leftovers and unreachable now: the entire intel directory
is built only when CONFIG_INTEL_IOMMU is set.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.h | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index e0ac9efa1aa9..bb8b973476f6 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1329,7 +1329,6 @@ static inline bool intel_domain_is_ss_paging(struct dmar_domain *domain)
return domain->domain.ops == &intel_ss_paging_domain_ops;
}
-#ifdef CONFIG_INTEL_IOMMU
extern int intel_iommu_sm;
int iommu_calculate_agaw(struct intel_iommu *iommu);
int iommu_calculate_max_sagaw(struct intel_iommu *iommu);
@@ -1344,20 +1343,6 @@ static inline bool ecmd_has_pmu_essential(struct intel_iommu *iommu)
extern int dmar_disabled;
extern int intel_iommu_enabled;
extern int intel_iommu_tboot_noforce;
-#else
-static inline int iommu_calculate_agaw(struct intel_iommu *iommu)
-{
- return 0;
-}
-static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
-{
- return 0;
-}
-#define dmar_disabled (1)
-#define intel_iommu_enabled (0)
-#define intel_iommu_sm (0)
-#define intel_iommu_tboot_noforce (0)
-#endif
static inline const char *decode_prq_descriptor(char *str, size_t size,
u64 dw0, u64 dw1, u64 dw2, u64 dw3)
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (2 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 3/9] iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-12 11:08 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin Kevin Tian
` (4 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
Currently the dmar state is carried by multiple variables (no_iommu,
dmar_disabled, no_platform_optin, etc.) with error-prone force_on logic
scattered in multiple places.
Unify the state management and centralize the policy/priority for
various force_on scenarios.
No functional impact except one case - "intel_iommu=off" sets
no_platform_optin which is checked in platform_optin_force_iommu()
but not in detect_intel_iommu(), leading to ACS unnecessarily requested
when iommu could not be forced on later. Now with the unified logic
this becomes more consistent.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/dmar.c | 57 ++++++++++++++++++++++++++++++++++---
drivers/iommu/intel/iommu.c | 7 +++++
drivers/iommu/intel/iommu.h | 45 +++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index e8f01e56cf46..791b91a7be29 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -915,14 +915,60 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
return 0;
}
+/*
+ * Centralized helper for deciding the force_on policy
+ *
+ * dmar disabled states (for DMA Remapping) are defined from stronger
+ * disables (more negative values) to weaker disables (less negative
+ * values).
+ *
+ * When a force_on type is passed in, it is associated to a reference
+ * level for comparison. force_on is permitted when dmar is in a
+ * disabled state less negative than the reference level (if dmar is
+ * enabled then the check is always true).
+ *
+ * For supported force_on types:
+ *
+ * - DMAR_FORCEON_TBOOT: tboot strictly requires DMA remapping for secure
+ * boot hence supersedes any user opts ("iommu=off" or "intel_iommu=off")
+ * and weaker disables.
+ *
+ * - DMAR_FORCEON_PLATFORM: external-facing devices requires DMA
+ * remapping to prevent malicious downstream external devices from
+ * composing DMA attacks. force_on is permitted only if dmar is disabled
+ * by build configurations (CONFIG_INTEL_IOMMU_DEFAULT_ON=off).
+ */
+bool dmar_can_force_on(enum dmar_force_on force_on)
+{
+ int level;
+
+ switch (force_on) {
+ case DMAR_FORCEON_TBOOT:
+ level = DMAR_DISABLED_USER;
+ break;
+ case DMAR_FORCEON_PLATFORM:
+ level = DMAR_DISABLED_AUTO;
+ break;
+ default:
+ pr_warn("Unsupported force_on type (%d)\n", force_on);
+ /* '0' means returning true only when dmar is enabled */
+ level = 0;
+ break;
+ }
+
+ return dmar_state >= level;
+}
+
static bool dmar_required(void)
{
- /* tboot supersedes any user/platform opt */
- if (!intel_iommu_tboot_noforce && tboot_enabled())
+ if (dmar_is_enabled())
return true;
- if (!no_iommu && (!dmar_disabled || dmar_platform_optin()))
- return true;
+ if (!intel_iommu_tboot_noforce && tboot_enabled())
+ return dmar_can_force_on(DMAR_FORCEON_TBOOT);
+
+ if (dmar_platform_optin())
+ return dmar_can_force_on(DMAR_FORCEON_PLATFORM);
return false;
}
@@ -936,6 +982,9 @@ void __init detect_intel_iommu(void)
};
down_write(&dmar_global_lock);
+ if (no_iommu)
+ dmar_state = DMAR_DISABLED_USER;
+
ret = dmar_table_detect();
if (!ret)
ret = dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0365ff4e5092..0fc131a34963 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -196,6 +196,11 @@ static LIST_HEAD(dmar_satc_units);
static void intel_iommu_domain_free(struct iommu_domain *domain);
+#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
+int dmar_state = DMAR_ENABLED;
+#else
+int dmar_state = DMAR_DISABLED_AUTO;
+#endif
int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
@@ -237,9 +242,11 @@ static int __init intel_iommu_setup(char *str)
while (*str) {
if (!strncmp(str, "on", 2)) {
+ dmar_state = DMAR_ENABLED;
dmar_disabled = 0;
pr_info("IOMMU enabled\n");
} else if (!strncmp(str, "off", 3)) {
+ dmar_state = DMAR_DISABLED_USER;
dmar_disabled = 1;
no_platform_optin = 1;
pr_info("IOMMU disabled\n");
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index bb8b973476f6..1acc393dafce 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1340,6 +1340,51 @@ static inline bool ecmd_has_pmu_essential(struct intel_iommu *iommu)
DMA_ECMD_ECCAP3_ESSENTIAL;
}
+enum dmar_force_on {
+ DMAR_FORCEON_PLATFORM,
+ DMAR_FORCEON_TBOOT
+};
+
+/*
+ * Enabled states are positive, with more positive value being stronger.
+ * Disabled states are negative, with more negative value being stronger.
+ *
+ * 'dmar' here refers to DMA remapping instead of the dmar/iommu unit.
+ *
+ * - DMAR_ENABLED_FORCE:
+ * force enabled (e.g. by tboot or platform optin).
+ *
+ * - DMAR_ENABLED:
+ * enabled by build configuration (CONFIG_INTEL_IOMMU_DEFAULT_ON=on)
+ * or user opts ("intel_iommu=on").
+ *
+ * - DMAR_DISABLED_AUTO
+ * disabled by build configuration (CONFIG_INTEL_IOMMU_DEFAULT_ON=off).
+ *
+ * - DMAR_DISABLED_USER
+ * disabled by user opts ("intel_iommu=off" or "iommu=off").
+ *
+ * - '0' is invalid, compared to decide dmar enabled vs. disabled
+ *
+ */
+#define DMAR_ENABLED_FORCE 2
+#define DMAR_ENABLED 1
+#define DMAR_DISABLED_AUTO -1
+#define DMAR_DISABLED_USER -2
+extern int dmar_state;
+
+static inline bool dmar_is_enabled(void)
+{
+ return dmar_state > 0;
+}
+
+static inline bool dmar_is_disabled(void)
+{
+ return dmar_state < 0;
+}
+
+bool dmar_can_force_on(enum dmar_force_on force_on);
+
extern int dmar_disabled;
extern int intel_iommu_enabled;
extern int intel_iommu_tboot_noforce;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (3 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-12 13:16 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin Kevin Tian
` (3 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
So the policy of requesting ACS in detect_intel_iommu() is consistent
with that in platform_optin_force_iommu().
While at it, remove no_platform_optin which is unnecessary now.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0fc131a34963..edf01261a41d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -58,7 +58,6 @@ static int rwbf_quirk;
*/
static int force_on = 0;
int intel_iommu_tboot_noforce;
-static int no_platform_optin;
#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
@@ -248,7 +247,6 @@ static int __init intel_iommu_setup(char *str)
} else if (!strncmp(str, "off", 3)) {
dmar_state = DMAR_DISABLED_USER;
dmar_disabled = 1;
- no_platform_optin = 1;
pr_info("IOMMU disabled\n");
} else if (!strncmp(str, "igfx_off", 8)) {
disable_igfx_iommu = 1;
@@ -2486,20 +2484,22 @@ static bool has_external_pci(void)
static int __init platform_optin_force_iommu(void)
{
- if (no_iommu || !dmar_platform_optin() || no_platform_optin ||
- !has_external_pci())
+ if (!dmar_platform_optin() || !dmar_can_force_on(DMAR_FORCEON_PLATFORM))
return 0;
- if (dmar_disabled)
- pr_info("Intel-IOMMU force enabled due to platform opt in\n");
+ if (!has_external_pci())
+ return 0;
/*
* If Intel-IOMMU is disabled by default, we will apply identity
* map for all devices except those marked as being untrusted.
*/
- if (dmar_disabled)
+ if (dmar_is_disabled()) {
+ pr_info("Intel-IOMMU force enabled due to platform opt in\n");
iommu_set_default_passthrough(false);
+ }
+ dmar_state = DMAR_ENABLED_FORCE;
dmar_disabled = 0;
return 1;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (4 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-12 13:57 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable Kevin Tian
` (2 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
So the policy of requesting ACS in detect_intel_iommu() is consistent
with that in tboot_force_iommu().
Though tboot is the strongest override so far, add a panic() in case
dmar_can_force_on() may return false due to future extensions.
No functional impact at this point.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index edf01261a41d..ed227de6d0ba 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2544,12 +2544,16 @@ static int __init probe_acpi_namespace_devices(void)
static __init int tboot_force_iommu(void)
{
- if (!tboot_enabled())
+ if (!tboot_enabled() || intel_iommu_tboot_noforce)
return 0;
- if (no_iommu || dmar_disabled)
+ if (!dmar_can_force_on(DMAR_FORCEON_TBOOT))
+ panic("tboot: Failed to force IOMMU on\n");
+
+ if (dmar_is_disabled())
pr_warn("Forcing Intel-IOMMU to enabled\n");
+ dmar_state = DMAR_ENABLED_FORCE;
dmar_disabled = 0;
no_iommu = 0;
@@ -2566,8 +2570,7 @@ int __init intel_iommu_init(void)
* Intel IOMMU is required for a TXT/tboot launch or platform
* opt in, so enforce that.
*/
- force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) ||
- platform_optin_force_iommu();
+ force_on = tboot_force_iommu() || platform_optin_force_iommu();
down_write(&dmar_global_lock);
if (dmar_table_init()) {
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (5 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-12 14:16 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 8/9] iommu/vt-d: Remove dmar_disabled Kevin Tian
2026-06-04 5:15 ` [PATCH 9/9] iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit Kevin Tian
8 siblings, 1 reply; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
The force_on variable is now redundant - same information captured
by "dmar_state == DMAR_ENABLED_FORCE". Replace all force_on checks
with dmar_is_force_on().
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.c | 34 +++++++++++++++-------------------
drivers/iommu/intel/iommu.h | 5 +++++
2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ed227de6d0ba..d05ae36eda70 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -53,10 +53,9 @@ static int rwbf_quirk;
#define rwbf_required(iommu) (rwbf_quirk || cap_rwbf((iommu)->cap))
/*
- * set to 1 to panic kernel if can't successfully enable VT-d
+ * set to 1 to avoid kernel panic if can't successfully enable VT-d
* (used when kernel is launched w/ TXT)
*/
-static int force_on = 0;
int intel_iommu_tboot_noforce;
#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
@@ -1708,7 +1707,7 @@ static int __init init_dmars(void)
* we always have to disable PMRs or DMA may fail on
* this device
*/
- if (force_on)
+ if (dmar_is_force_on())
iommu_disable_protect_mem_regions(iommu);
continue;
}
@@ -1800,7 +1799,7 @@ static int init_iommu_hw(void)
* we always have to disable PMRs or DMA may fail on
* this device
*/
- if (force_on)
+ if (dmar_is_force_on())
iommu_disable_protect_mem_regions(iommu);
continue;
}
@@ -1861,7 +1860,7 @@ static void iommu_resume(void *data)
unsigned long flag;
if (init_iommu_hw()) {
- if (force_on)
+ if (dmar_is_force_on())
panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
else
WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
@@ -2129,7 +2128,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
/*
* we always have to disable PMRs or DMA may fail on this device
*/
- if (force_on)
+ if (dmar_is_force_on())
iommu_disable_protect_mem_regions(iommu);
return 0;
}
@@ -2482,13 +2481,13 @@ static bool has_external_pci(void)
return false;
}
-static int __init platform_optin_force_iommu(void)
+static void __init platform_optin_force_iommu(void)
{
if (!dmar_platform_optin() || !dmar_can_force_on(DMAR_FORCEON_PLATFORM))
- return 0;
+ return;
if (!has_external_pci())
- return 0;
+ return;
/*
* If Intel-IOMMU is disabled by default, we will apply identity
@@ -2501,8 +2500,6 @@ static int __init platform_optin_force_iommu(void)
dmar_state = DMAR_ENABLED_FORCE;
dmar_disabled = 0;
-
- return 1;
}
static int __init probe_acpi_namespace_devices(void)
@@ -2542,10 +2539,10 @@ static int __init probe_acpi_namespace_devices(void)
return 0;
}
-static __init int tboot_force_iommu(void)
+static __init void tboot_force_iommu(void)
{
if (!tboot_enabled() || intel_iommu_tboot_noforce)
- return 0;
+ return;
if (!dmar_can_force_on(DMAR_FORCEON_TBOOT))
panic("tboot: Failed to force IOMMU on\n");
@@ -2556,8 +2553,6 @@ static __init int tboot_force_iommu(void)
dmar_state = DMAR_ENABLED_FORCE;
dmar_disabled = 0;
no_iommu = 0;
-
- return 1;
}
int __init intel_iommu_init(void)
@@ -2570,17 +2565,18 @@ int __init intel_iommu_init(void)
* Intel IOMMU is required for a TXT/tboot launch or platform
* opt in, so enforce that.
*/
- force_on = tboot_force_iommu() || platform_optin_force_iommu();
+ tboot_force_iommu();
+ platform_optin_force_iommu();
down_write(&dmar_global_lock);
if (dmar_table_init()) {
- if (force_on)
+ if (dmar_is_force_on())
panic("tboot: Failed to initialize DMAR table\n");
goto out_free_dmar;
}
if (dmar_dev_scope_init() < 0) {
- if (force_on)
+ if (dmar_is_force_on())
panic("tboot: Failed to initialize DMAR device scope\n");
goto out_free_dmar;
}
@@ -2634,7 +2630,7 @@ int __init intel_iommu_init(void)
ret = init_dmars();
if (ret) {
- if (force_on)
+ if (dmar_is_force_on())
panic("tboot: Failed to initialize DMARs\n");
pr_err("Initialization failed\n");
goto out_free_dmar;
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 1acc393dafce..6b4e47f2f245 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1383,6 +1383,11 @@ static inline bool dmar_is_disabled(void)
return dmar_state < 0;
}
+static inline bool dmar_is_force_on(void)
+{
+ return dmar_state == DMAR_ENABLED_FORCE;
+}
+
bool dmar_can_force_on(enum dmar_force_on force_on);
extern int dmar_disabled;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 8/9] iommu/vt-d: Remove dmar_disabled
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (6 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
2026-06-12 14:26 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 9/9] iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit Kevin Tian
8 siblings, 1 reply; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
It's replaced by dmar_is_disabled() now, covering both "iommu=off"
and "intel_iommu=off". Also remove unnecessary checks on no_iommu,
leaving only one exception in intel_iommu_init() which skips debugfs
init for "iommu=off" but not "intel_iommu=off". Keep it to avoid
surprise for now.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/iommu.c | 9 ++-------
drivers/iommu/intel/iommu.h | 1 -
drivers/iommu/intel/svm.c | 2 +-
3 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d05ae36eda70..78498dafa60a 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -199,7 +199,6 @@ int dmar_state = DMAR_ENABLED;
#else
int dmar_state = DMAR_DISABLED_AUTO;
#endif
-int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
int intel_iommu_enabled = 0;
@@ -241,11 +240,9 @@ static int __init intel_iommu_setup(char *str)
while (*str) {
if (!strncmp(str, "on", 2)) {
dmar_state = DMAR_ENABLED;
- dmar_disabled = 0;
pr_info("IOMMU enabled\n");
} else if (!strncmp(str, "off", 3)) {
dmar_state = DMAR_DISABLED_USER;
- dmar_disabled = 1;
pr_info("IOMMU disabled\n");
} else if (!strncmp(str, "igfx_off", 8)) {
disable_igfx_iommu = 1;
@@ -2366,7 +2363,7 @@ void intel_iommu_shutdown(void)
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu = NULL;
- if (no_iommu || dmar_disabled)
+ if (dmar_is_disabled())
return;
/*
@@ -2499,7 +2496,6 @@ static void __init platform_optin_force_iommu(void)
}
dmar_state = DMAR_ENABLED_FORCE;
- dmar_disabled = 0;
}
static int __init probe_acpi_namespace_devices(void)
@@ -2551,7 +2547,6 @@ static __init void tboot_force_iommu(void)
pr_warn("Forcing Intel-IOMMU to enabled\n");
dmar_state = DMAR_ENABLED_FORCE;
- dmar_disabled = 0;
no_iommu = 0;
}
@@ -2594,7 +2589,7 @@ int __init intel_iommu_init(void)
if (!no_iommu)
intel_iommu_debugfs_init();
- if (no_iommu || dmar_disabled) {
+ if (dmar_is_disabled()) {
/*
* We exit the function here to ensure IOMMU's remapping and
* mempool aren't setup, which means that the IOMMU's PMRs
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 6b4e47f2f245..1832debf4982 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1390,7 +1390,6 @@ static inline bool dmar_is_force_on(void)
bool dmar_can_force_on(enum dmar_force_on force_on);
-extern int dmar_disabled;
extern int intel_iommu_enabled;
extern int intel_iommu_tboot_noforce;
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index 57cd1db7207a..971dddaba48e 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -115,7 +115,7 @@ static int intel_iommu_sva_supported(struct device *dev)
struct device_domain_info *info = dev_iommu_priv_get(dev);
struct intel_iommu *iommu;
- if (!info || dmar_disabled)
+ if (!info || dmar_is_disabled())
return -EINVAL;
iommu = info->iommu;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 9/9] iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
` (7 preceding siblings ...)
2026-06-04 5:15 ` [PATCH 8/9] iommu/vt-d: Remove dmar_disabled Kevin Tian
@ 2026-06-04 5:15 ` Kevin Tian
8 siblings, 0 replies; 15+ messages in thread
From: Kevin Tian @ 2026-06-04 5:15 UTC (permalink / raw)
To: Lu Baolu, Joerg Roedel, Will Deacon, Robin Murphy
Cc: Kevin Tian, Joerg Roedel, Mika Westerberg, Ashok Raj,
Chris Wright, Jesse Barnes, Asit Mallick, iommu, linux-kernel
Some BIOS already provides config options to expose/hide VT-d units
as a whole to/from system software. A new demand is to allow exposing
VT-d units but requesting system software to disable DMA remapping
while sustaining interrupt remapping. This can be communicated now by
setting the new DMA_REMAP_OPT_OUT flag bit in the DMAR table, as
introduced in VT-d spec v5.2 (section 8.1, DMA Remapping Reporting
Structure).
Introduce a new disabled state (DMAR_DISABLED_FW) for DMA_REMAP_OPT_OUT.
As the strongest disabled state, it cannot be overridden by user opts
or any force_on types. If tboot is enabled in the meantime, kernel will
panic. It is user responsibility to configure BIOS properly.
One cleanup is left for future - the DMAR flag is parsed multiple
times, in detect_intel_iommu(), dmar_platform_optin() (which can be
called at run-time), etc. Caching it is a cleaner way.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/iommu/intel/dmar.c | 32 ++++++++++++++++++++++----------
drivers/iommu/intel/iommu.h | 4 ++++
include/linux/dmar.h | 1 +
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 791b91a7be29..24b173d33afd 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -931,7 +931,9 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
*
* - DMAR_FORCEON_TBOOT: tboot strictly requires DMA remapping for secure
* boot hence supersedes any user opts ("iommu=off" or "intel_iommu=off")
- * and weaker disables.
+ * and weaker disables. But if firmware forces DMA remapping off (by
+ * setting DMAR_REMAP_OPT_OUT in the DMAR table), no force_on is allowed.
+ * Firmware settings must be changed to unblock tboot.
*
* - DMAR_FORCEON_PLATFORM: external-facing devices requires DMA
* remapping to prevent malicious downstream external devices from
@@ -975,31 +977,41 @@ static bool dmar_required(void)
void __init detect_intel_iommu(void)
{
- int ret;
struct dmar_res_callback validate_drhd_cb = {
.cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &dmar_validate_one_drhd,
.ignore_unhandled = true,
};
+ struct acpi_table_dmar *dmar;
+ int ret;
down_write(&dmar_global_lock);
if (no_iommu)
dmar_state = DMAR_DISABLED_USER;
ret = dmar_table_detect();
- if (!ret)
- ret = dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl,
- &validate_drhd_cb);
- if (!ret && !iommu_detected && dmar_required()) {
+ if (!ret) {
+ dmar = (struct acpi_table_dmar *)dmar_tbl;
+ ret = dmar_walk_dmar_table(dmar, &validate_drhd_cb);
+ }
+
+ if (ret)
+ goto out;
+
+ if (dmar->flags & DMAR_REMAP_OPT_OUT) {
+ dmar_state = DMAR_DISABLED_FW;
+ pr_info("Firmware forces DMA remapping off\n");
+ }
+
+ if (!iommu_detected && dmar_required()) {
iommu_detected = 1;
/* Make sure ACS will be enabled */
pci_request_acs();
}
- if (!ret) {
- x86_init.iommu.iommu_init = intel_iommu_init;
- x86_platform.iommu_shutdown = intel_iommu_shutdown;
- }
+ x86_init.iommu.iommu_init = intel_iommu_init;
+ x86_platform.iommu_shutdown = intel_iommu_shutdown;
+out:
if (dmar_tbl) {
acpi_put_table(dmar_tbl);
dmar_tbl = NULL;
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 1832debf4982..67ecf3521fd4 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1364,6 +1364,9 @@ enum dmar_force_on {
* - DMAR_DISABLED_USER
* disabled by user opts ("intel_iommu=off" or "iommu=off").
*
+ * - DMAR_DISABLED_FW
+ * disabled due to firmware opt-out (DMAR_REMAP_OPT_OUT)
+ *
* - '0' is invalid, compared to decide dmar enabled vs. disabled
*
*/
@@ -1371,6 +1374,7 @@ enum dmar_force_on {
#define DMAR_ENABLED 1
#define DMAR_DISABLED_AUTO -1
#define DMAR_DISABLED_USER -2
+#define DMAR_DISABLED_FW -3
extern int dmar_state;
static inline bool dmar_is_enabled(void)
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 692b2b445761..63e35df2cef4 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -24,6 +24,7 @@ struct acpi_dmar_header;
#define DMAR_INTR_REMAP 0x1
#define DMAR_X2APIC_OPT_OUT 0x2
#define DMAR_PLATFORM_OPT_IN 0x4
+#define DMAR_REMAP_OPT_OUT 0x8
struct intel_iommu;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic
2026-06-04 5:15 ` [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic Kevin Tian
@ 2026-06-12 11:08 ` Baolu Lu
0 siblings, 0 replies; 15+ messages in thread
From: Baolu Lu @ 2026-06-12 11:08 UTC (permalink / raw)
To: Kevin Tian, Joerg Roedel, Will Deacon, Robin Murphy
Cc: baolu.lu, Joerg Roedel, Mika Westerberg, Ashok Raj, Chris Wright,
Jesse Barnes, Asit Mallick, iommu, linux-kernel
On 6/4/2026 1:15 PM, Kevin Tian wrote:
> Currently the dmar state is carried by multiple variables (no_iommu,
> dmar_disabled, no_platform_optin, etc.) with error-prone force_on logic
> scattered in multiple places.
>
> Unify the state management and centralize the policy/priority for
> various force_on scenarios.
>
> No functional impact except one case - "intel_iommu=off" sets
> no_platform_optin which is checked in platform_optin_force_iommu()
> but not in detect_intel_iommu(), leading to ACS unnecessarily requested
> when iommu could not be forced on later. Now with the unified logic
> this becomes more consistent.
>
> Signed-off-by: Kevin Tian<kevin.tian@intel.com>
> ---
> drivers/iommu/intel/dmar.c | 57 ++++++++++++++++++++++++++++++++++---
> drivers/iommu/intel/iommu.c | 7 +++++
> drivers/iommu/intel/iommu.h | 45 +++++++++++++++++++++++++++++
> 3 files changed, 105 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index e8f01e56cf46..791b91a7be29 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -915,14 +915,60 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
> return 0;
> }
>
> +/*
> + * Centralized helper for deciding the force_on policy
> + *
> + * dmar disabled states (for DMA Remapping) are defined from stronger
> + * disables (more negative values) to weaker disables (less negative
> + * values).
> + *
> + * When a force_on type is passed in, it is associated to a reference
> + * level for comparison. force_on is permitted when dmar is in a
> + * disabled state less negative than the reference level (if dmar is
> + * enabled then the check is always true).
> + *
> + * For supported force_on types:
> + *
> + * - DMAR_FORCEON_TBOOT: tboot strictly requires DMA remapping for secure
> + * boot hence supersedes any user opts ("iommu=off" or "intel_iommu=off")
> + * and weaker disables.
> + *
> + * - DMAR_FORCEON_PLATFORM: external-facing devices requires DMA
> + * remapping to prevent malicious downstream external devices from
> + * composing DMA attacks. force_on is permitted only if dmar is disabled
> + * by build configurations (CONFIG_INTEL_IOMMU_DEFAULT_ON=off).
> + */
It reads like tboot successfully overrides the user's choices, whereas
the platform opt-in cannot. Could you shed more light on this? My
understanding is that "trusted boot environment" is considered stronger
than "user choices", which in turn is stronger than a "platform opt-in
hint".
If this is indeed the core design philosophy, would you mind spelling it
out explicitly in this comment? Making the exact precedence clear
will help future development follow the same philosophy.
> +bool dmar_can_force_on(enum dmar_force_on force_on)
> +{
> + int level;
> +
> + switch (force_on) {
> + case DMAR_FORCEON_TBOOT:
> + level = DMAR_DISABLED_USER;
> + break;
> + case DMAR_FORCEON_PLATFORM:
> + level = DMAR_DISABLED_AUTO;
> + break;
> + default:
> + pr_warn("Unsupported force_on type (%d)\n", force_on);
> + /* '0' means returning true only when dmar is enabled */
> + level = 0;
> + break;
> + }
> +
> + return dmar_state >= level;
> +}
If this helper returns false (meaning a requested force_on type cannot
be enforced), would it be better to notify the user via a clear pr_info/
pr_warn in the kernel log?
Normally, a failure to enforce a requested "force_on" condition might
mean security or trust implications that the administrator should be
aware of.
The rest of the patch looks good to me. Thanks!
Thanks,
baolu
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin
2026-06-04 5:15 ` [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin Kevin Tian
@ 2026-06-12 13:16 ` Baolu Lu
0 siblings, 0 replies; 15+ messages in thread
From: Baolu Lu @ 2026-06-12 13:16 UTC (permalink / raw)
To: Kevin Tian, Joerg Roedel, Will Deacon, Robin Murphy
Cc: baolu.lu, Joerg Roedel, Mika Westerberg, Ashok Raj, Chris Wright,
Jesse Barnes, Asit Mallick, iommu, linux-kernel
On 6/4/2026 1:15 PM, Kevin Tian wrote:
> So the policy of requesting ACS in detect_intel_iommu() is consistent
> with that in platform_optin_force_iommu().
>
> While at it, remove no_platform_optin which is unnecessary now.
>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> ---
> drivers/iommu/intel/iommu.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 0fc131a34963..edf01261a41d 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -58,7 +58,6 @@ static int rwbf_quirk;
> */
> static int force_on = 0;
> int intel_iommu_tboot_noforce;
> -static int no_platform_optin;
>
> #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
>
> @@ -248,7 +247,6 @@ static int __init intel_iommu_setup(char *str)
> } else if (!strncmp(str, "off", 3)) {
> dmar_state = DMAR_DISABLED_USER;
> dmar_disabled = 1;
> - no_platform_optin = 1;
> pr_info("IOMMU disabled\n");
> } else if (!strncmp(str, "igfx_off", 8)) {
> disable_igfx_iommu = 1;
> @@ -2486,20 +2484,22 @@ static bool has_external_pci(void)
>
> static int __init platform_optin_force_iommu(void)
> {
> - if (no_iommu || !dmar_platform_optin() || no_platform_optin ||
> - !has_external_pci())
> + if (!dmar_platform_optin() || !dmar_can_force_on(DMAR_FORCEON_PLATFORM))
> return 0;
>
> - if (dmar_disabled)
> - pr_info("Intel-IOMMU force enabled due to platform opt in\n");
> + if (!has_external_pci())
> + return 0;
Moving has_external_pci() down here seems to be an optimization. :-)
Scanning the PCI fabric for external-facing ports can be costly, and now
we could skip it entirely if platform force-on is unnecessary.
>
> /*
> * If Intel-IOMMU is disabled by default, we will apply identity
> * map for all devices except those marked as being untrusted.
> */
> - if (dmar_disabled)
> + if (dmar_is_disabled()) {
> + pr_info("Intel-IOMMU force enabled due to platform opt in\n");
> iommu_set_default_passthrough(false);
> + }
>
> + dmar_state = DMAR_ENABLED_FORCE;
I was initially wondering if we needed a lock to protect dmar_state
here, but since this runs during early boot in a single-threaded
environment (indicated by the __init prefix), concurrent access isn't a
concern.
However, changing dmar_state here does mean that any logic calling
dmar_is_enabled() before this point will see a "disabled" state, while
subsequent calls will see an "enabled" state.
While I don't see a real problem right now, this state volatility is
something we should document. Could we add a brief comment here to
clarify this intentional state upgrade?
> dmar_disabled = 0;
>
> return 1;
The rest looks good to me.
Thanks,
baolu
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin
2026-06-04 5:15 ` [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin Kevin Tian
@ 2026-06-12 13:57 ` Baolu Lu
0 siblings, 0 replies; 15+ messages in thread
From: Baolu Lu @ 2026-06-12 13:57 UTC (permalink / raw)
To: Kevin Tian, Joerg Roedel, Will Deacon, Robin Murphy
Cc: baolu.lu, Joerg Roedel, Mika Westerberg, Ashok Raj, Chris Wright,
Jesse Barnes, Asit Mallick, iommu, linux-kernel
On 6/4/2026 1:15 PM, Kevin Tian wrote:
> So the policy of requesting ACS in detect_intel_iommu() is consistent
> with that in tboot_force_iommu().
>
> Though tboot is the strongest override so far, add a panic() in case
> dmar_can_force_on() may return false due to future extensions.
>
> No functional impact at this point.
>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> ---
> drivers/iommu/intel/iommu.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index edf01261a41d..ed227de6d0ba 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2544,12 +2544,16 @@ static int __init probe_acpi_namespace_devices(void)
>
> static __init int tboot_force_iommu(void)
> {
> - if (!tboot_enabled())
> + if (!tboot_enabled() || intel_iommu_tboot_noforce)
Hmm, it looks a bit strange here. The core design philosophy is that the
trusted boot environment takes priority over user options. However,
checking intel_iommu_tboot_noforce at the very top means a user
option (intel_iommu=tboot_noforce) is successfully overriding tboot.
Is this an exception? If so, it might be worth adding a brief comment
clarifying why `tboot_noforce` is allowed to bypass the priority?
> return 0;
>
> - if (no_iommu || dmar_disabled)
> + if (!dmar_can_force_on(DMAR_FORCEON_TBOOT))
> + panic("tboot: Failed to force IOMMU on\n");
> +
> + if (dmar_is_disabled())
> pr_warn("Forcing Intel-IOMMU to enabled\n");
>
> + dmar_state = DMAR_ENABLED_FORCE;
> dmar_disabled = 0;
> no_iommu = 0;
>
> @@ -2566,8 +2570,7 @@ int __init intel_iommu_init(void)
> * Intel IOMMU is required for a TXT/tboot launch or platform
> * opt in, so enforce that.
> */
> - force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) ||
> - platform_optin_force_iommu();
> + force_on = tboot_force_iommu() || platform_optin_force_iommu();
>
> down_write(&dmar_global_lock);
> if (dmar_table_init()) {
Thanks,
baolu
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable
2026-06-04 5:15 ` [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable Kevin Tian
@ 2026-06-12 14:16 ` Baolu Lu
0 siblings, 0 replies; 15+ messages in thread
From: Baolu Lu @ 2026-06-12 14:16 UTC (permalink / raw)
To: Kevin Tian, Joerg Roedel, Will Deacon, Robin Murphy
Cc: baolu.lu, Joerg Roedel, Mika Westerberg, Ashok Raj, Chris Wright,
Jesse Barnes, Asit Mallick, iommu, linux-kernel
On 6/4/2026 1:15 PM, Kevin Tian wrote:
> The force_on variable is now redundant - same information captured
> by "dmar_state == DMAR_ENABLED_FORCE". Replace all force_on checks
> with dmar_is_force_on().
>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> ---
> drivers/iommu/intel/iommu.c | 34 +++++++++++++++-------------------
> drivers/iommu/intel/iommu.h | 5 +++++
> 2 files changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index ed227de6d0ba..d05ae36eda70 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -53,10 +53,9 @@ static int rwbf_quirk;
> #define rwbf_required(iommu) (rwbf_quirk || cap_rwbf((iommu)->cap))
>
> /*
> - * set to 1 to panic kernel if can't successfully enable VT-d
> + * set to 1 to avoid kernel panic if can't successfully enable VT-d
> * (used when kernel is launched w/ TXT)
> */
It might be cleaner to replace it entirely with a new comment. For
example:
/*
* Skip forcing iommu enablement and avoid tboot-related kernel panics
* during initialization when set to 1 (via intel_iommu=tboot_noforce).
*/
int intel_iommu_tboot_noforce;
> -static int force_on = 0;
> int intel_iommu_tboot_noforce;
>
> #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
> @@ -1708,7 +1707,7 @@ static int __init init_dmars(void)
> * we always have to disable PMRs or DMA may fail on
> * this device
> */
> - if (force_on)
> + if (dmar_is_force_on())
> iommu_disable_protect_mem_regions(iommu);
> continue;
> }
> @@ -1800,7 +1799,7 @@ static int init_iommu_hw(void)
> * we always have to disable PMRs or DMA may fail on
> * this device
> */
> - if (force_on)
> + if (dmar_is_force_on())
> iommu_disable_protect_mem_regions(iommu);
> continue;
> }
> @@ -1861,7 +1860,7 @@ static void iommu_resume(void *data)
> unsigned long flag;
>
> if (init_iommu_hw()) {
> - if (force_on)
> + if (dmar_is_force_on())
> panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
> else
> WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
> @@ -2129,7 +2128,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
> /*
> * we always have to disable PMRs or DMA may fail on this device
> */
> - if (force_on)
> + if (dmar_is_force_on())
> iommu_disable_protect_mem_regions(iommu);
> return 0;
> }
> @@ -2482,13 +2481,13 @@ static bool has_external_pci(void)
> return false;
> }
>
> -static int __init platform_optin_force_iommu(void)
> +static void __init platform_optin_force_iommu(void)
> {
> if (!dmar_platform_optin() || !dmar_can_force_on(DMAR_FORCEON_PLATFORM))
> - return 0;
> + return;
>
> if (!has_external_pci())
> - return 0;
> + return;
>
> /*
> * If Intel-IOMMU is disabled by default, we will apply identity
> @@ -2501,8 +2500,6 @@ static int __init platform_optin_force_iommu(void)
>
> dmar_state = DMAR_ENABLED_FORCE;
> dmar_disabled = 0;
> -
> - return 1;
> }
>
> static int __init probe_acpi_namespace_devices(void)
> @@ -2542,10 +2539,10 @@ static int __init probe_acpi_namespace_devices(void)
> return 0;
> }
>
> -static __init int tboot_force_iommu(void)
> +static __init void tboot_force_iommu(void)
> {
> if (!tboot_enabled() || intel_iommu_tboot_noforce)
> - return 0;
> + return;
>
> if (!dmar_can_force_on(DMAR_FORCEON_TBOOT))
> panic("tboot: Failed to force IOMMU on\n");
> @@ -2556,8 +2553,6 @@ static __init int tboot_force_iommu(void)
> dmar_state = DMAR_ENABLED_FORCE;
> dmar_disabled = 0;
> no_iommu = 0;
> -
> - return 1;
> }
>
> int __init intel_iommu_init(void)
> @@ -2570,17 +2565,18 @@ int __init intel_iommu_init(void)
> * Intel IOMMU is required for a TXT/tboot launch or platform
> * opt in, so enforce that.
> */
> - force_on = tboot_force_iommu() || platform_optin_force_iommu();
> + tboot_force_iommu();
> + platform_optin_force_iommu();
>
> down_write(&dmar_global_lock);
> if (dmar_table_init()) {
> - if (force_on)
> + if (dmar_is_force_on())
> panic("tboot: Failed to initialize DMAR table\n");
> goto out_free_dmar;
> }
>
> if (dmar_dev_scope_init() < 0) {
> - if (force_on)
> + if (dmar_is_force_on())
> panic("tboot: Failed to initialize DMAR device scope\n");
> goto out_free_dmar;
> }
> @@ -2634,7 +2630,7 @@ int __init intel_iommu_init(void)
>
> ret = init_dmars();
> if (ret) {
> - if (force_on)
> + if (dmar_is_force_on())
> panic("tboot: Failed to initialize DMARs\n");
> pr_err("Initialization failed\n");
> goto out_free_dmar;
> diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
> index 1acc393dafce..6b4e47f2f245 100644
> --- a/drivers/iommu/intel/iommu.h
> +++ b/drivers/iommu/intel/iommu.h
> @@ -1383,6 +1383,11 @@ static inline bool dmar_is_disabled(void)
> return dmar_state < 0;
> }
>
> +static inline bool dmar_is_force_on(void)
> +{
> + return dmar_state == DMAR_ENABLED_FORCE;
> +}
This helper is only meaningful after
tboot_force_iommu();
platform_optin_force_iommu();
have been called. It would be better to add a brief comment about this?
> +
> bool dmar_can_force_on(enum dmar_force_on force_on);
>
> extern int dmar_disabled;
Thanks,
baolu
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 8/9] iommu/vt-d: Remove dmar_disabled
2026-06-04 5:15 ` [PATCH 8/9] iommu/vt-d: Remove dmar_disabled Kevin Tian
@ 2026-06-12 14:26 ` Baolu Lu
0 siblings, 0 replies; 15+ messages in thread
From: Baolu Lu @ 2026-06-12 14:26 UTC (permalink / raw)
To: Kevin Tian, Joerg Roedel, Will Deacon, Robin Murphy
Cc: baolu.lu, Joerg Roedel, Mika Westerberg, Ashok Raj, Chris Wright,
Jesse Barnes, Asit Mallick, iommu, linux-kernel
On 6/4/2026 1:15 PM, Kevin Tian wrote:
> It's replaced by dmar_is_disabled() now, covering both "iommu=off"
> and "intel_iommu=off". Also remove unnecessary checks on no_iommu,
> leaving only one exception in intel_iommu_init() which skips debugfs
> init for "iommu=off" but not "intel_iommu=off". Keep it to avoid
> surprise for now.
As mentioned in the previous patch, dmar_is_disabled() only becomes
meaningful for wider usage after the force_on logic has been executed,
right? Would it be better to add a check to make it safe?
>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> ---
> drivers/iommu/intel/iommu.c | 9 ++-------
> drivers/iommu/intel/iommu.h | 1 -
> drivers/iommu/intel/svm.c | 2 +-
> 3 files changed, 3 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index d05ae36eda70..78498dafa60a 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -199,7 +199,6 @@ int dmar_state = DMAR_ENABLED;
> #else
> int dmar_state = DMAR_DISABLED_AUTO;
> #endif
> -int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
> int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
>
> int intel_iommu_enabled = 0;
> @@ -241,11 +240,9 @@ static int __init intel_iommu_setup(char *str)
> while (*str) {
> if (!strncmp(str, "on", 2)) {
> dmar_state = DMAR_ENABLED;
> - dmar_disabled = 0;
> pr_info("IOMMU enabled\n");
> } else if (!strncmp(str, "off", 3)) {
> dmar_state = DMAR_DISABLED_USER;
> - dmar_disabled = 1;
> pr_info("IOMMU disabled\n");
> } else if (!strncmp(str, "igfx_off", 8)) {
> disable_igfx_iommu = 1;
> @@ -2366,7 +2363,7 @@ void intel_iommu_shutdown(void)
> struct dmar_drhd_unit *drhd;
> struct intel_iommu *iommu = NULL;
>
> - if (no_iommu || dmar_disabled)
> + if (dmar_is_disabled())
> return;
>
> /*
> @@ -2499,7 +2496,6 @@ static void __init platform_optin_force_iommu(void)
> }
>
> dmar_state = DMAR_ENABLED_FORCE;
> - dmar_disabled = 0;
> }
>
> static int __init probe_acpi_namespace_devices(void)
> @@ -2551,7 +2547,6 @@ static __init void tboot_force_iommu(void)
> pr_warn("Forcing Intel-IOMMU to enabled\n");
>
> dmar_state = DMAR_ENABLED_FORCE;
> - dmar_disabled = 0;
> no_iommu = 0;
> }
>
> @@ -2594,7 +2589,7 @@ int __init intel_iommu_init(void)
> if (!no_iommu)
> intel_iommu_debugfs_init();
>
> - if (no_iommu || dmar_disabled) {
> + if (dmar_is_disabled()) {
> /*
> * We exit the function here to ensure IOMMU's remapping and
> * mempool aren't setup, which means that the IOMMU's PMRs
> diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
> index 6b4e47f2f245..1832debf4982 100644
> --- a/drivers/iommu/intel/iommu.h
> +++ b/drivers/iommu/intel/iommu.h
> @@ -1390,7 +1390,6 @@ static inline bool dmar_is_force_on(void)
>
> bool dmar_can_force_on(enum dmar_force_on force_on);
>
> -extern int dmar_disabled;
> extern int intel_iommu_enabled;
> extern int intel_iommu_tboot_noforce;
>
> diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
> index 57cd1db7207a..971dddaba48e 100644
> --- a/drivers/iommu/intel/svm.c
> +++ b/drivers/iommu/intel/svm.c
> @@ -115,7 +115,7 @@ static int intel_iommu_sva_supported(struct device *dev)
> struct device_domain_info *info = dev_iommu_priv_get(dev);
> struct intel_iommu *iommu;
>
> - if (!info || dmar_disabled)
> + if (!info || dmar_is_disabled())
> return -EINVAL;
>
> iommu = info->iommu;
Thanks,
baolu
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-06-12 14:26 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04 5:15 [PATCH 0/9] iommu/vt-d: Support a new DMAR flag Kevin Tian
2026-06-04 5:15 ` [PATCH 1/9] iommu/vt-d: Fix no_iommu to disable platform optin Kevin Tian
2026-06-04 5:15 ` [PATCH 2/9] iommu/vt-d: Force requesting ACS when tboot is enabled Kevin Tian
2026-06-04 5:15 ` [PATCH 3/9] iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set Kevin Tian
2026-06-04 5:15 ` [PATCH 4/9] iommu/vt-d: Consolidate dmar state management and force_on logic Kevin Tian
2026-06-12 11:08 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 5/9] iommu/vt-d: Use dmar_can_force_on() for platform optin Kevin Tian
2026-06-12 13:16 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 6/9] iommu/vt-d: Call dmar_can_force_on() for tboot optin Kevin Tian
2026-06-12 13:57 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 7/9] iommu/vt-d: Remove the 'force_on' variable Kevin Tian
2026-06-12 14:16 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 8/9] iommu/vt-d: Remove dmar_disabled Kevin Tian
2026-06-12 14:26 ` Baolu Lu
2026-06-04 5:15 ` [PATCH 9/9] iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit Kevin Tian
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox