* [PATCH v3] iommu/amd: Make PerfOpt compulsory
@ 2026-09-30 16:24 Mario Limonciello (AMD)
2026-09-30 22:40 ` Jason Gunthorpe
0 siblings, 1 reply; 2+ messages in thread
From: Mario Limonciello (AMD) @ 2026-09-30 16:24 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Alex Deucher, Joerg Roedel, Suravee Suthikulpanit, Vasant Hegde,
open list:RADEON and AMDGPU DRM DRIVERS, open list,
open list:AMD IOMMU (AMD-VI), Mario Limonciello (AMD)
PerfOpt is only a feature usable by integrated GPUs and only in identity
mode. Instead of leaving a policy knob in amdgpu, just turn it on when
an integrated GPU is in identity.
This drops quite a bit of compatibility glue. There was a refcounting
system, exported symbols, and device attach/detach logic. By just setting
it immediately it's a lot more straightforward.
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
---
v3:
* Move amd_iommu_perfopt_set() to init.c and set static (Vasant)
* Clear bit if it fails to enable (Vasant)
* Use pr_err() instead of dev_err for early errors (Sashiko)
* Restore attach_device check for VFIO cases (Sashiko)
* Handle VFIO case (Sashiko)
* Handle multi-IOMMU case (Sashiko)
v2:
* Move WARN_ON to amd_iommu_perfopt_clear()
* Make amd_iommu_perfopt_clear() void
* Drop unnecessary cleanup/create paths that unset feature
* Enable the feature in IOMMU if supported (per guidance in IVRS spec)
* Use existing check_feature() helper instead
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 50 -----
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 --
drivers/iommu/amd/amd_iommu.h | 3 -
drivers/iommu/amd/amd_iommu_types.h | 3 -
drivers/iommu/amd/init.c | 81 ++++----
drivers/iommu/amd/iommu.c | 215 +--------------------
include/linux/amd-iommu.h | 11 --
8 files changed, 42 insertions(+), 334 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0e53a02ad1bab..a9c6f5d4a6397 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -156,7 +156,6 @@ struct amdgpu_watchdog_timer {
* Modules parameters.
*/
extern int amdgpu_modeset;
-extern int amdgpu_iommu_perfopt;
extern unsigned int amdgpu_vram_limit;
extern int amdgpu_vis_vram_limit;
extern int amdgpu_gart_size;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index bfe4d90343c4e..9269e780feb73 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -33,7 +33,6 @@
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/iommu.h>
-#include <linux/amd-iommu.h>
#include <linux/pci.h>
#include <linux/pci-p2pdma.h>
#include <linux/apple-gmux.h>
@@ -3753,28 +3752,6 @@ amdgpu_device_should_register_switcheroo(struct amdgpu_device *adev, bool px)
apple_gmux_detect(NULL, NULL)));
}
-static inline bool amdgpu_device_identity(struct amdgpu_device *adev)
-{
- struct pci_dev *pdev = adev->pdev;
- struct iommu_domain *domain = iommu_get_domain_for_dev(&pdev->dev);
-
- if (!domain)
- return false;
-
- return domain->type == IOMMU_DOMAIN_IDENTITY;
-}
-
-static bool amdgpu_device_use_perfopt(struct amdgpu_device *adev)
-{
- if (amdgpu_iommu_perfopt == 0)
- return false;
-
- if (!(adev->flags & AMD_IS_APU))
- return false;
-
- return amdgpu_device_identity(adev);
-}
-
/**
* amdgpu_device_init - initialize the driver
*
@@ -3982,16 +3959,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (r)
return r;
- if (amdgpu_device_use_perfopt(adev)) {
- int perfopt_ret = amd_iommu_enable_perfopt(pdev);
-
- /* Optional optimization; a failure to arm it must not abort probe. */
- if (perfopt_ret)
- dev_warn(adev->dev,
- "Failed to enable IOMMU PerfOpt (%d); continuing without it\n",
- perfopt_ret);
- }
-
/*
* No need to remove conflicting FBs for non-display class devices.
* This prevents the sysfb from being freed accidently.
@@ -4361,9 +4328,6 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
amdgpu_gart_dummy_page_fini(adev);
- if (amdgpu_device_use_perfopt(adev))
- amd_iommu_disable_perfopt(adev->pdev);
-
if (pci_dev_is_disconnected(adev->pdev))
amdgpu_device_unmap_mmio(adev);
@@ -4727,20 +4691,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
- if (amdgpu_device_use_perfopt(adev)) {
- int perfopt_ret = amd_iommu_enable_perfopt(adev->pdev);
-
- /*
- * Must not return on failure: a bare return would leak the
- * SR-IOV VF exclusive-mode acquisition taken above (released
- * via the exit: path).
- */
- if (perfopt_ret)
- dev_warn(adev->dev,
- "Failed to enable IOMMU PerfOpt (%d); continuing without it\n",
- perfopt_ret);
- }
-
if (adev->in_s0ix)
amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D0Entry);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 3ca98091ce487..5c33c19fd9bc5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -185,7 +185,6 @@ char *amdgpu_disable_cu;
char *amdgpu_virtual_display;
int amdgpu_enforce_isolation = -1;
int amdgpu_modeset = -1;
-int amdgpu_iommu_perfopt = -1;
/* Specifies the default granularity for SVM, used in buffer
* migration and restoration of backing memory when handling
@@ -393,17 +392,6 @@ module_param_named(fw_load_type, amdgpu_fw_load_type, int, 0444);
MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(aspm, amdgpu_aspm, int, 0444);
-/**
- * DOC: iommu_perfopt (int)
- * Control the AMD IOMMU PerfOpt DMA-latency optimization
- * (0 = disable; -1 = enable on supported devices).
- * This arms the IOMMU PerfOpt control (IOMMU spec, MMIO Offset 016Ch, EFR PerfOptSup / PerfOptEn)
- * Arming it disables ATS, PRI, PASID and SVA for the GPU and removes IOMMU DMA containment for it,
- * trading isolation for lower DMA latency.
- */
-MODULE_PARM_DESC(iommu_perfopt, "Control IOMMU PerfOpt DMA-latency optimization (-1 = enable on supported devices, 0 = disable)");
-module_param_named(iommu_perfopt, amdgpu_iommu_perfopt, int, 0444);
-
/**
* DOC: runpm (int)
* Override for runtime power management control for dGPUs. The amdgpu driver can dynamically power down
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index 93845b3c3fbf7..71113e8608594 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -48,9 +48,6 @@ extern u8 amd_iommu_hpt_vasize;
extern unsigned long amd_iommu_pgsize_bitmap;
extern bool amd_iommu_hatdis;
-int amd_iommu_perfopt_clear(struct amd_iommu *iommu);
-int amd_iommu_perfopt_restore(struct amd_iommu *iommu);
-
/* Protection domain ops */
void amd_iommu_init_identity_domain(void);
struct protection_domain *protection_domain_alloc(void);
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 1c1624b7c9a36..9d873819304fb 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -657,9 +657,6 @@ struct amd_iommu {
/* Extended features 2 */
u64 features2;
- /* Devices requesting PerfOpt; the shared PERF_OPT_EN bit is on while >0. Protected by @lock. */
- int perfopt_refcount;
-
/* PCI device id of the IOMMU device */
u16 devid;
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 8ec8a6fccaaf3..e510ac724eea1 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -426,6 +426,37 @@ static void iommu_enable(struct amd_iommu *iommu)
iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
}
+/*
+ * Program or clear the per-IOMMU PerfOpt enable bit.
+ * Gate on this IOMMU's own EFR, not the global AND-mask.
+ */
+static int amd_iommu_perfopt_set(struct amd_iommu *iommu, bool enable)
+{
+ u32 old, val, readback;
+
+ if (!(iommu->features & FEATURE_PERF_OPT))
+ return enable ? -ENODEV : 0;
+
+ old = readl(iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
+ if (old == U32_MAX)
+ goto fail;
+
+ val = enable ? old | PERF_OPT_EN : old & ~PERF_OPT_EN;
+ if (val != old)
+ writel(val, iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
+ readback = readl(iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
+ if (readback == U32_MAX ||
+ (readback & PERF_OPT_EN) != (val & PERF_OPT_EN)) {
+ goto fail;
+ }
+
+ return 0;
+fail:
+ iommu->features &= ~FEATURE_PERF_OPT;
+ pr_err("Failed to set PerfOpt to %d\n", enable);
+ return -EIO;
+}
+
static void iommu_disable(struct amd_iommu *iommu)
{
if (!iommu->mmio_base)
@@ -451,6 +482,9 @@ static void iommu_disable(struct amd_iommu *iommu)
/* Clear IRTE cache disabling bit */
iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS);
+
+ /* Clear PerfOpt feature */
+ amd_iommu_perfopt_set(iommu, FALSE);
}
/*
@@ -1943,9 +1977,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
if (!iommu->mmio_base)
return -ENOMEM;
- if (amd_iommu_perfopt_clear(iommu))
- pr_err("IOMMU%d: failed to clear PerfOpt\n", iommu->index);
-
return init_iommu_from_acpi(iommu, h);
}
@@ -2314,6 +2345,9 @@ static void print_iommu_info(void)
if (check_feature2(FEATURE_SEVSNPIO_SUP))
pr_cont(" SEV-TIO");
+ if (check_feature(FEATURE_PERF_OPT))
+ pr_cont(" PerfOpt");
+
pr_cont("\n");
}
@@ -2921,6 +2955,7 @@ static void early_enable_iommu(struct amd_iommu *iommu)
iommu_enable_xt(iommu);
iommu_enable_irtcachedis(iommu);
iommu_enable_2k_int(iommu);
+ amd_iommu_perfopt_set(iommu, TRUE);
iommu_enable(iommu);
amd_iommu_flush_all_caches(iommu);
}
@@ -3050,46 +3085,10 @@ static void enable_iommus_vapic(void)
#endif
}
-static int clear_perfopt_all(void)
-{
- struct amd_iommu *iommu;
- int err, ret = 0;
-
- for_each_iommu(iommu) {
- err = amd_iommu_perfopt_clear(iommu);
- if (err)
- ret = err;
- }
-
- return ret;
-}
-
-static int restore_perfopt_all(void)
-{
- struct amd_iommu *iommu;
- int err, ret = 0;
-
- for_each_iommu(iommu) {
- err = amd_iommu_perfopt_restore(iommu);
- if (err)
- ret = err;
- }
-
- return ret;
-}
-
static void disable_iommus(void)
{
struct amd_iommu *iommu;
- /*
- * PerfOpt is an optional performance bit, so a failure to clear it must
- * not skip the mandatory disable below. This also runs from the void
- * amd_iommu_disable() shutdown/kexec path, which cannot report an error.
- */
- if (clear_perfopt_all())
- pr_err("Failed to clear PerfOpt while disabling IOMMUs\n");
-
for_each_iommu(iommu)
iommu_disable(iommu);
@@ -3115,10 +3114,6 @@ static void amd_iommu_resume(void *data)
for_each_iommu(iommu)
early_enable_iommu(iommu);
- /* early_enable_iommu() cleared PERF_OPT_EN; re-assert it from the refcount. */
- if (restore_perfopt_all())
- pr_err("Failed to restore PerfOpt after IOMMU resume\n");
-
iommu_enable_event_buffer();
amd_iommu_enable_interrupts();
}
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index c9b28e5e582ea..3f9f02274e809 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2370,7 +2370,7 @@ static int attach_device(struct device *dev,
if (ret)
goto out;
- if (dev_data->perfopt)
+ if (dev_data->perfopt && pdom_is_in_pt_mode(domain))
goto skip_caps;
/* Setup GCR3 table */
@@ -2512,192 +2512,6 @@ static int iommu_init_device_caps(struct iommu_dev_data *dev_data,
return 0;
}
-/* Program the per-IOMMU PerfOpt enable bit. Caller must hold iommu->lock. */
-static int __perfopt_write(struct amd_iommu *iommu, bool enable)
-{
- u32 old, val, readback;
-
- if (!(readq(iommu->mmio_base + MMIO_EXT_FEATURES) & FEATURE_PERF_OPT))
- return enable ? -ENODEV : 0;
-
- old = readl(iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
- if (old == U32_MAX)
- return -EIO;
-
- val = enable ? old | PERF_OPT_EN : old & ~PERF_OPT_EN;
- if (val != old)
- writel(val, iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
- readback = readl(iommu->mmio_base + MMIO_PERF_OPT_OFFSET);
- if (readback == U32_MAX ||
- (readback & PERF_OPT_EN) != (val & PERF_OPT_EN))
- return -EIO;
- return 0;
-}
-
-/*
- * PERF_OPT_EN is a single bit shared by every device behind @iommu, so it is
- * reference counted: armed on the first requesting device, cleared on the last.
- */
-static int perfopt_get(struct amd_iommu *iommu)
-{
- unsigned long flags;
- int ret = 0;
-
- if (!iommu->mmio_base)
- return 0;
-
- raw_spin_lock_irqsave(&iommu->lock, flags);
- if (iommu->perfopt_refcount == 0) {
- ret = __perfopt_write(iommu, true);
- if (ret)
- goto out;
- }
- iommu->perfopt_refcount++;
-out:
- raw_spin_unlock_irqrestore(&iommu->lock, flags);
- return ret;
-}
-
-static int perfopt_put(struct amd_iommu *iommu)
-{
- unsigned long flags;
- int ret = 0;
-
- if (!iommu->mmio_base)
- return 0;
-
- raw_spin_lock_irqsave(&iommu->lock, flags);
- if (iommu->perfopt_refcount > 0 && --iommu->perfopt_refcount == 0)
- ret = __perfopt_write(iommu, false);
- raw_spin_unlock_irqrestore(&iommu->lock, flags);
- return ret;
-}
-
-/*
- * Force PERF_OPT_EN off without touching the refcount (used on init, shutdown,
- * and suspend). The count is preserved so amd_iommu_perfopt_restore() can
- * re-arm on resume.
- */
-int amd_iommu_perfopt_clear(struct amd_iommu *iommu)
-{
- unsigned long flags;
- int ret;
-
- if (!iommu->mmio_base)
- return 0;
-
- raw_spin_lock_irqsave(&iommu->lock, flags);
- ret = __perfopt_write(iommu, false);
- raw_spin_unlock_irqrestore(&iommu->lock, flags);
- return ret;
-}
-
-/*
- * Re-assert PERF_OPT_EN from the refcount after the hardware was reprogrammed on
- * resume, so devices armed before suspend keep the optimization without each
- * consumer driver re-arming.
- */
-int amd_iommu_perfopt_restore(struct amd_iommu *iommu)
-{
- unsigned long flags;
- int ret;
-
- if (!iommu->mmio_base)
- return 0;
-
- raw_spin_lock_irqsave(&iommu->lock, flags);
- ret = __perfopt_write(iommu, iommu->perfopt_refcount > 0);
- raw_spin_unlock_irqrestore(&iommu->lock, flags);
- return ret;
-}
-
-int amd_iommu_enable_perfopt(struct pci_dev *pdev)
-{
- struct iommu_dev_data *dev_data = dev_iommu_priv_get(&pdev->dev);
- struct amd_iommu *iommu = rlookup_amd_iommu(&pdev->dev);
- struct protection_domain *domain;
- int ret;
-
- if (!iommu || !dev_data)
- return -ENODEV;
-
- if (!(iommu->features & FEATURE_PERF_OPT))
- return -ENODEV;
-
- domain = dev_data->domain;
- if (!domain)
- return -ENODEV;
-
- /* Already armed for this device (e.g. re-entry on resume). */
- if (dev_data->perfopt)
- return 0;
-
- /*
- * The bit is only architecturally valid while the device is untranslated:
- * identity domain with ATS/PRI/PASID off. The identity domain is
- * SVA-capable so attach_device() enabled ATS/PRI/PASID and built a GCR3
- * table. Re-home the device onto the same identity domain with
- * perfopt set, so the attach_device() skip_caps path leaves
- * ATS/PRI/PASID off and no GCR3 table. This follows the detach/attach
- * pattern used by amd_iommu_attach_device().
- *
- * Locking: this and amd_iommu_disable_perfopt() run only from the
- * consumer driver's bind/unbind path. group->mutex is not exposed to
- * drivers, but a device bound to its native driver cannot have its domain
- * changed concurrently by the core (VFIO ownership is mutually exclusive;
- * sysfs domain changes require an unused group), so the detach/attach pair
- * is serialized without it.
- */
- dev_data->perfopt = true;
- detach_device(&pdev->dev);
- ret = attach_device(&pdev->dev, domain);
- if (ret)
- goto err_restore;
-
- ret = perfopt_get(iommu);
- if (ret)
- goto err_rearm;
-
- dev_info_once(&pdev->dev, "PerfOpt armed on IOMMU%d\n", iommu->index);
- return 0;
-
-err_rearm:
- detach_device(&pdev->dev);
-err_restore:
- dev_data->perfopt = false;
- if (attach_device(&pdev->dev, domain))
- pci_err(pdev, "failed to restore state after PerfOpt setup; device left detached\n");
- dev_err_once(&pdev->dev, "PerfOpt failed to arm on IOMMU%d (%d)\n",
- iommu->index, ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(amd_iommu_enable_perfopt);
-
-void amd_iommu_disable_perfopt(struct pci_dev *pdev)
-{
- struct iommu_dev_data *dev_data = dev_iommu_priv_get(&pdev->dev);
- struct amd_iommu *iommu = rlookup_amd_iommu(&pdev->dev);
- struct protection_domain *domain;
-
- if (!iommu || !dev_data || !dev_data->perfopt || !dev_data->domain)
- return;
-
- if (WARN_ON(perfopt_put(iommu)))
- pci_err(pdev, "failed to clear PerfOpt\n");
-
- /*
- * Restore ATS/PRI/PASID (and thus SVA) by re-homing the device onto its
- * identity domain with the flag cleared, so a later bind without PerfOpt
- * sees a normally-capable device. See the locking note in
- * amd_iommu_enable_perfopt().
- */
- domain = dev_data->domain;
- dev_data->perfopt = false;
- detach_device(&pdev->dev);
- if (attach_device(&pdev->dev, domain))
- pci_err(pdev, "failed to restore caps after PerfOpt disable\n");
-}
-EXPORT_SYMBOL_GPL(amd_iommu_disable_perfopt);
static struct iommu_device *amd_iommu_probe_device(struct device *dev)
{
struct iommu_device *iommu_dev;
@@ -2741,14 +2555,6 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
static void amd_iommu_release_device(struct device *dev)
{
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
- struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
-
- if (dev_data->perfopt) {
- if (WARN_ON(perfopt_put(iommu)))
- dev_err(dev, "IOMMU%d: failed to clear PerfOpt on release\n",
- iommu->index);
- dev_data->perfopt = false;
- }
WARN_ON(dev_data->domain);
@@ -3123,19 +2929,6 @@ static int blocked_domain_attach_device(struct iommu_domain *domain,
struct iommu_domain *old)
{
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
- struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
-
- /*
- * blocked_domain is also the .release_domain, so this is the normal
- * teardown path: drop the reference and clear the flag here too, and
- * don't fail teardown if the WARN-guarded write doesn't stick.
- */
- if (dev_data->perfopt) {
- if (WARN_ON(perfopt_put(iommu)))
- dev_err(dev, "IOMMU%d: failed to clear PerfOpt for blocked domain\n",
- iommu->index);
- dev_data->perfopt = false;
- }
if (dev_data->domain)
detach_device(dev);
@@ -3204,9 +2997,6 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, struct device *dev,
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev);
int ret;
- if (dev_data->perfopt && !pdom_is_in_pt_mode(domain))
- return -EBUSY;
-
/*
* Skip attach device to domain if new domain is same as
* devices current domain
@@ -3421,6 +3211,9 @@ static int amd_iommu_def_domain_type(struct device *dev)
if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
return 0;
+ dev_data->perfopt = get_amd_iommu_from_dev_data(dev_data)->features &
+ FEATURE_PERF_OPT;
+
return IOMMU_DOMAIN_IDENTITY;
}
diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h
index 104817e8d8977..5c9dcf720f846 100644
--- a/include/linux/amd-iommu.h
+++ b/include/linux/amd-iommu.h
@@ -76,15 +76,4 @@ static inline int amd_iommu_snp_disable(void) { return 0; }
static inline bool amd_iommu_sev_tio_supported(void) { return false; }
#endif
-#ifdef CONFIG_AMD_IOMMU
-int amd_iommu_enable_perfopt(struct pci_dev *pdev);
-void amd_iommu_disable_perfopt(struct pci_dev *pdev);
-#else
-static inline int amd_iommu_enable_perfopt(struct pci_dev *pdev)
-{
- return 0;
-}
-static inline void amd_iommu_disable_perfopt(struct pci_dev *pdev) { }
-#endif
-
#endif /* _ASM_X86_AMD_IOMMU_H */
--
2.53.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v3] iommu/amd: Make PerfOpt compulsory
2026-09-30 16:24 [PATCH v3] iommu/amd: Make PerfOpt compulsory Mario Limonciello (AMD)
@ 2026-09-30 22:40 ` Jason Gunthorpe
0 siblings, 0 replies; 2+ messages in thread
From: Jason Gunthorpe @ 2026-09-30 22:40 UTC (permalink / raw)
To: Mario Limonciello (AMD)
Cc: Jason Gunthorpe, Alex Deucher, Joerg Roedel,
Suravee Suthikulpanit, Vasant Hegde, amd-gfx, linux-kernel,
iommu
> [ ... 336 lines skipped ... ]
> @@ -2370,7 +2370,7 @@ static int attach_device(struct device *dev,
> if (ret)
> goto out;
>
> - if (dev_data->perfopt)
> + if (dev_data->perfopt && pdom_is_in_pt_mode(domain))
> goto skip_caps;
This should also disable PASID support since without a gcr3 table
that's broken. Set the max_pasid to zero during probe device.
The flow is weird like this because the driver still hasn't cleaned up
the identity/blocking domain flows. There is no need to track them in
lists and things because they never need invalidation..
This is much nicer if the above could be written in side
amd_iommu_identity_attach().
Also, I'm a little confused, I thought this had to be toggled on and
off so it is only set while in identity, how does the DTE influence
what happens when in this special mode? I was sort of expecting it was
ignored entirely in HW. This version seems to lock it to always on,
but still permits a blocking domain to attach.
--
Jason
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-30 22:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 16:24 [PATCH v3] iommu/amd: Make PerfOpt compulsory Mario Limonciello (AMD)
2026-09-30 22:40 ` Jason Gunthorpe
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®