Re: [PATCH v2 1/3] iommu/amd: Do not request ACS when IOMMU is not going to be initialized

Rong Zhang <[email protected]>
Newsgroups dev.linux.lists.iommu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi Sairaj,

On Fri, 2026-08-21 at 16:12 +0530, Sairaj Kodilkar wrote:
> On 8/20/2026 11:55 PM, Rong Zhang wrote:
> > The AMD IOMMU Initialization State Machine has the following state
> > transition diagram (only the very first states are showed, and the
> > `IOMMU_' prefix is omitted):
> > 
> >    START_STATE
> >         |
> >         v
> > [0] detect_ivrs() --> NOT_FOUND
> >         | ok
> >         v
> >   IVRS_DETECTED
> >         |
> >         v
> > [1] amd_iommu_disabled? (amd_iommu=off) --> IOMMU_CMDLINE_DISABLED
> >         | no
> >         v
> > [2] early_amd_iommu_init()
> >         |
> >         +-- [3] amd_iommu_detected? (!iommu=off && ...) -+
> >         | yes                                            |
> >         +-- ... --> IOMMU_INIT_ERROR <-------------------+
> >         | ok
> >         v
> > IOMMU_ACPI_FINISHED
> >         |
> >         v
> >        ...
> > 
> > [0] always calls pci_request_acs() as long as there's a valid IVRS table
> > and no Stoney Ridge graphics. This is not optimal as ACS is not required
> > in an [amd_]iommu=off boot.
> > 
> > In a normal boot, ACS is requested due to amd_iommu_detect() requesting
> > IVRS_DETECTED.
> > 
> >     pci_request_acs+0x9/0x18
> >     iommu_go_to_state+0x106/0x1a20
> >     amd_iommu_detect+0x1c/0x50
> >     pci_iommu_alloc+0x26/0x40
> >     mm_core_init+0xa/0x120
> >     start_kernel+0x527/0x7a0
> >     x86_64_start_reservations+0x24/0x30
> >     x86_64_start_kernel+0xd1/0xe0
> >     common_startup_64+0x13e/0x158
> > 
> > This is intended to ensure ACS is requested before the PCI core
> > initialization, or else a !CONFIG_IRQ_REMAP, nointremap or intremap=off
> > boot would be broken.
> > 
> > However, in an amd_iommu=off boot, the state machine still requests ACS
> > at the exact same time, as amd_iommu_detect() has nothing to do with
> > amd_iommu_disabled.
> > 
> > Even worse, in an iommu=off boot, though amd_iommu_detect() bails out
> > early, ACS is still requested due to amd_iommu_prepare() requesting
> > IOMMU_ACPI_FINISHED, which is called by irq_remapping_prepare() thanks
> > to CONFIG_X86_LOCAL_APIC (always set on X86_64) and CONFIG_IRQ_REMAP
> > (enabled by defconfig), unless nointremap or intremap=off is also passed
> > to cmdline.
> > 
> >     pci_request_acs+0x9/0x18
> >     iommu_go_to_state+0x106/0x1a20
> >     amd_iommu_prepare+0x15/0x40
> >     irq_remapping_prepare+0x43/0x60
> >     enable_IR_x2apic+0x22/0x190
> >     x86_64_probe_apic+0xa/0x50
> >     apic_intr_mode_init+0x70/0xd0
> >     x86_late_time_init+0x28/0x40
> >     start_kernel+0x6f9/0x7a0
> >     ...
> > 
> > In both cases, [2] is still gated due to the [1] or [3] check, so that
> > IOMMU can be disabled per cmdline.
> > 
> > Technically, it makes no sense to detect IVRS at all in an
> > [amd_]iommu=off boot or if IOMMU is not supported due to platform
> > settings. This is probably why amd_iommu_detect() bails out before
> > requesting IVRS_DETECTED. Apparently only bailing out there is not
> > sufficient, and the bailing-out paths should really have been parts of
> > the state machine.
> > 
> > Clean up the initialization routines by moving the bailing-out paths and
> > [1] to the right place in the state machine (i.e., before [0]), and
> > always requesting IVRS_DETECTED in amd_iommu_detect() to initialize the
> > state machine early and properly.
> > 
> > Signed-off-by: Rong Zhang <[email protected]>
> > ---
> >  drivers/iommu/amd/init.c | 25 +++++++++++--------------
> >  1 file changed, 11 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
> > index 40726dfef273..a720796cca3b 100644
> > --- a/drivers/iommu/amd/init.c
> > +++ b/drivers/iommu/amd/init.c
> > @@ -3470,6 +3470,8 @@ static void amd_iommu_apply_erratum_snp(void)
> >  #endif
> >  }
> >  
> > +static bool amd_iommu_sme_check(void);
> > +
> >  /****************************************************************************
> >   *
> >   * AMD IOMMU Initialization State Machine
> > @@ -3482,7 +3484,13 @@ static int __init state_next(void)
> >  
> >  	switch (init_state) {
> >  	case IOMMU_START_STATE:
> > -		if (!detect_ivrs()) {
> > +		if (no_iommu || amd_iommu_disabled) {
> > +			init_state	= IOMMU_CMDLINE_DISABLED;
> > +			ret		= -EINVAL;
> > +		} else if ((iommu_detected && !gart_iommu_aperture) || !amd_iommu_sme_check()) {
> 
> Looks like you can drop the condition
> (iommu_detected && !gart_iommu_aperture)
> 
> It was added by the commit 6631ee9d00, which set iommu_detected = 1 and
> gart_iommu_aperture = 0 in iommu driver. But it is later removed and no
> longer present in the lastest iommu code.
> 
> Latest code can have following two conditions
> 
> 1. When CONFIG_GART_IOMMU=y
> x86/kernel/aperture_64.c sets both iommu_detected and
> gart_iommu_aperture to 1
> 
> 2. When CONFIG_GART_IOMMU=n
> amd_iommu_detect is called only when both iommu_detected and
> gart_iommu_aperture are zero.

Makes sense. Will clean it up in v3.

Thanks,
Rong

> 
> Thanks
> Sairaj.
> 
> 
> 
> > +			init_state	= IOMMU_INIT_ERROR;
> > +			ret		= -EINVAL;
> > +		} else if (!detect_ivrs()) {
> >  			init_state	= IOMMU_NOT_FOUND;
> >  			ret		= -ENODEV;
> >  		} else {
> > @@ -3490,13 +3498,8 @@ static int __init state_next(void)
> >  		}
> >  		break;
> >  	case IOMMU_IVRS_DETECTED:
> > -		if (amd_iommu_disabled) {
> > -			init_state = IOMMU_CMDLINE_DISABLED;
> > -			ret = -EINVAL;
> > -		} else {
> > -			ret = early_amd_iommu_init();
> > -			init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED;
> > -		}
> > +		ret = early_amd_iommu_init();
> > +		init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED;
> >  		break;
> >  	case IOMMU_ACPI_FINISHED:
> >  		early_enable_iommus();
> > @@ -3695,12 +3698,6 @@ void __init amd_iommu_detect(void)
> >  {
> >  	int ret;
> >  
> > -	if (no_iommu || (iommu_detected && !gart_iommu_aperture))
> > -		goto disable_snp;
> > -
> > -	if (!amd_iommu_sme_check())
> > -		goto disable_snp;
> > -
> >  	ret = iommu_go_to_state(IOMMU_IVRS_DETECTED);
> >  	if (ret)
> >  		goto disable_snp;
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.