From nobody Mon Apr 6 16:23:50 2026 Received: from out30-99.freemail.mail.aliyun.com (out30-99.freemail.mail.aliyun.com [115.124.30.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5673534E743 for ; Thu, 19 Mar 2026 07:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905902; cv=none; b=dUHy1e7C/UvQyiYDQGOyCX4QYSs7x7Lpz/1I+brP5xAFV0wb02kyTLBZPqh2yPwce0cRzwQ3LzJlLUxFUtG9JfXRnNmZhzGVOf3uRNy2IUX8kgCf/kgpl9Q1NuH6b5eFGIeWiH13GcnF5DcOpI26nxSbYTaCNL0PbakBhpWe2wI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905902; c=relaxed/simple; bh=A+0Ub8LK2Sro9xETxnNcenTrLDH/r/59z4r1kDVVZBY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qW/j6pBO5gWqhb4L/M/2xgW/6VjImyYtmHxpGgMMv24qBtobSbQLcN3UeAdFHgPNJm8UCisMclj7XHZri+m3sqrxR/qvStGSdAbvfYAoohKtgbM4SVLrJX+Q0cJK/OMag5gfwgPBQjoyvY3eufbsGzZSU0893Ac+s4ANSsIZL1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=jESFlCKt; arc=none smtp.client-ip=115.124.30.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="jESFlCKt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1773905893; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=QKEW3Jbfg2XYZKXRGBvGg0e5m1rDToi+MBji5wzT9iY=; b=jESFlCKtdbDFZUoE4T/xlFXozxNyd5DpBrDOBz3vhpT4XVJUSyzr8OZEAc76dlJvYE+6s/DLn0maPWK5oajvkOezhMVdNSP5eX7PRd3v7N1BtN8Cu7GdX0L63/sJHbnN6EjC1mKDPT1D4NOT4yRlWPpJg4uxx4gskD/BxljXYEg= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=7;SR=0;TI=SMTPD_---0X.HbDIW_1773905892; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X.HbDIW_1773905892 cluster:ay36) by smtp.aliyun-inc.com; Thu, 19 Mar 2026 15:38:12 +0800 From: Guanghui Feng To: joro@8bytes.org, suravee.suthikulpanit@amd.com, will@kernel.org, robin.murphy@arm.com Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org, ming.shu@amd.com Subject: [PATCH 1/2] iommu/amd: Fix illegal device-id access in IOMMU debugfs Date: Thu, 19 Mar 2026 15:37:53 +0800 Message-ID: <20260319073754.651998-2-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260319073754.651998-1-guanghuifeng@linux.alibaba.com> References: <20260319073754.651998-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the current AMD IOMMU debugFS, when multiple processes use the IOMMU debugFS process simultaneously, illegal access issues can occur in the following execution flow: 1. CPU1: Sets a valid sbdf via devid_write, then checks the sbdf's validity in execution flows such as devid_show, iommu_devtbl_show, and iommu_irqtbl_show. 2. CPU2: Sets an invalid sbdf via devid_write, at which point the sbdf value is -1. 3. CPU1: accesses the IOMMU device table, IRQ table, based on the invalid SBDF value of -1, resulting in illegal access. This is especially problematic in monitoring scripts, where multiple scripts may access debugFS simultaneously, and some scripts may unexpectedly set invalid values, which triggers illegal access in debugfs. This patch modifies the execution flow of devid_show, iommu_devtbl_show, and iommu_irqtbl_show to ensure that these processes determine the validity and access based on the same device-id, thus guaranteeing correctness and robustness. Signed-off-by: Guanghui Feng Reviewed-by: Vasant Hegde --- drivers/iommu/amd/debugfs.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c index 20b04996441d..0b03e0622f67 100644 --- a/drivers/iommu/amd/debugfs.c +++ b/drivers/iommu/amd/debugfs.c @@ -197,10 +197,11 @@ static ssize_t devid_write(struct file *filp, const c= har __user *ubuf, static int devid_show(struct seq_file *m, void *unused) { u16 devid; + int sbdf_shadow =3D sbdf; =20 - if (sbdf >=3D 0) { - devid =3D PCI_SBDF_TO_DEVID(sbdf); - seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf), + if (sbdf_shadow >=3D 0) { + devid =3D PCI_SBDF_TO_DEVID(sbdf_shadow); + seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow), PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid)); } else seq_puts(m, "No or Invalid input provided\n"); @@ -237,13 +238,14 @@ static int iommu_devtbl_show(struct seq_file *m, void= *unused) { struct amd_iommu_pci_seg *pci_seg; u16 seg, devid; + int sbdf_shadow =3D sbdf; =20 - if (sbdf < 0) { + if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } - seg =3D PCI_SBDF_TO_SEGID(sbdf); - devid =3D PCI_SBDF_TO_DEVID(sbdf); + seg =3D PCI_SBDF_TO_SEGID(sbdf_shadow); + devid =3D PCI_SBDF_TO_DEVID(sbdf_shadow); =20 for_each_pci_segment(pci_seg) { if (pci_seg->id !=3D seg) @@ -336,19 +338,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void= *unused) { struct amd_iommu_pci_seg *pci_seg; u16 devid, seg; + int sbdf_shadow =3D sbdf; =20 if (!irq_remapping_enabled) { seq_puts(m, "Interrupt remapping is disabled\n"); return 0; } =20 - if (sbdf < 0) { + if (sbdf_shadow < 0) { seq_puts(m, "Enter a valid device ID to 'devid' file\n"); return 0; } =20 - seg =3D PCI_SBDF_TO_SEGID(sbdf); - devid =3D PCI_SBDF_TO_DEVID(sbdf); + seg =3D PCI_SBDF_TO_SEGID(sbdf_shadow); + devid =3D PCI_SBDF_TO_DEVID(sbdf_shadow); =20 for_each_pci_segment(pci_seg) { if (pci_seg->id !=3D seg) --=20 2.43.7 From nobody Mon Apr 6 16:23:50 2026 Received: from out30-118.freemail.mail.aliyun.com (out30-118.freemail.mail.aliyun.com [115.124.30.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99A8623EAB3 for ; Thu, 19 Mar 2026 07:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905903; cv=none; b=ZUh3DPW9/kd6WR9WzoqHMQQ1Ia2WQf39zYREuKPobGxU9FB6HZMIFZaxZMGKJI3/xziNYR5f1zkc+h8GvkuXmeVJwscbsHzoYDarDAU59nxCr689y0AS+ruPLGgOB2VganNoC+7fVn35UYz4NWrsEj8b48wjydZda3UDO1ORP8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905903; c=relaxed/simple; bh=UNeVSmO8Mgab/v1dEV/ATI5VmMcAW917v7NN5lqKJKU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aouZhll0z9gtBoqzotVGHjQrngXoOYz+KwFF1AE6myyO11X+vOarCwwz0MlB8ASLJrps5iyJabAo04uJ+ncivteYT42tSdifuN/koV7pxaMCCDUB3AmRnBs07v4qAiZfkyEJdh9PJzVeOL9XA5jKZLEF4XhFP8+bFC5S5t0RP1A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=symQzY16; arc=none smtp.client-ip=115.124.30.118 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="symQzY16" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1773905893; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=oPDiGtoIzm3InSMa1allZTsHpr47UCJD5YwtL801kIo=; b=symQzY16lzOEK4OXJrkEirGsaF2ef6Pt1MPNDWA9d9XNadPGT/MNYp8KoX25QsWRO+sAslKRT3f1BeXsEZ9K74MgUhyHD+J1WV+HCuxdlfbHc8vZskNBPEcseoJeQ8SNo8N3QqoQ6s2rhYriyVAlhbdH+Ha3M5yFp2HH5rFsFaE= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033037026112;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=7;SR=0;TI=SMTPD_---0X.HbDIc_1773905893; Received: from VM20241011-104.tbsite.net(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0X.HbDIc_1773905893 cluster:ay36) by smtp.aliyun-inc.com; Thu, 19 Mar 2026 15:38:13 +0800 From: Guanghui Feng To: joro@8bytes.org, suravee.suthikulpanit@amd.com, will@kernel.org, robin.murphy@arm.com Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org, ming.shu@amd.com Subject: [PATCH 2/2] iommu/amd: Fix illegal cap/mmio access in IOMMU debugfs Date: Thu, 19 Mar 2026 15:37:54 +0800 Message-ID: <20260319073754.651998-3-guanghuifeng@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260319073754.651998-1-guanghuifeng@linux.alibaba.com> References: <20260319073754.651998-1-guanghuifeng@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the current AMD IOMMU debugfs, when multiple processes simultaneously access the IOMMU mmio/cap registers using the IOMMU debugfs, illegal access issues can occur in the following execution flow: 1. CPU1: Sets a valid access address using iommu_mmio/capability_write, and verifies the access address's validity in iommu_mmio/capability_show 2. CPU2: Sets an invalid address using iommu_mmio/capability_write 3. CPU1: accesses the IOMMU mmio/cap registers based on the invalid address, resulting in an illegal access. This patch modifies the execution process to first verify the address's validity and then access it based on the same address, ensuring correctness and robustness. Signed-off-by: Guanghui Feng Reviewed-by: Vasant Hegde --- drivers/iommu/amd/debugfs.c | 42 +++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c index 0b03e0622f67..4e66473d7cea 100644 --- a/drivers/iommu/amd/debugfs.c +++ b/drivers/iommu/amd/debugfs.c @@ -26,22 +26,19 @@ static ssize_t iommu_mmio_write(struct file *filp, cons= t char __user *ubuf, { struct seq_file *m =3D filp->private_data; struct amd_iommu *iommu =3D m->private; - int ret; - - iommu->dbg_mmio_offset =3D -1; + int ret, dbg_mmio_offset =3D iommu->dbg_mmio_offset =3D -1; =20 if (cnt > OFS_IN_SZ) return -EINVAL; =20 - ret =3D kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_mmio_offset); + ret =3D kstrtou32_from_user(ubuf, cnt, 0, &dbg_mmio_offset); if (ret) return ret; =20 - if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { - iommu->dbg_mmio_offset =3D -1; - return -EINVAL; - } + if (dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) + return -EINVAL; =20 + iommu->dbg_mmio_offset =3D dbg_mmio_offset; return cnt; } =20 @@ -49,14 +46,16 @@ static int iommu_mmio_show(struct seq_file *m, void *un= used) { struct amd_iommu *iommu =3D m->private; u64 value; + int dbg_mmio_offset =3D iommu->dbg_mmio_offset; =20 - if (iommu->dbg_mmio_offset < 0) { + if (dbg_mmio_offset < 0 || dbg_mmio_offset > + iommu->mmio_phys_end - sizeof(u64)) { seq_puts(m, "Please provide mmio register's offset\n"); return 0; } =20 - value =3D readq(iommu->mmio_base + iommu->dbg_mmio_offset); - seq_printf(m, "Offset:0x%x Value:0x%016llx\n", iommu->dbg_mmio_offset, va= lue); + value =3D readq(iommu->mmio_base + dbg_mmio_offset); + seq_printf(m, "Offset:0x%x Value:0x%016llx\n", dbg_mmio_offset, value); =20 return 0; } @@ -67,23 +66,20 @@ static ssize_t iommu_capability_write(struct file *filp= , const char __user *ubuf { struct seq_file *m =3D filp->private_data; struct amd_iommu *iommu =3D m->private; - int ret; - - iommu->dbg_cap_offset =3D -1; + int ret, dbg_cap_offset =3D iommu->dbg_cap_offset =3D -1; =20 if (cnt > OFS_IN_SZ) return -EINVAL; =20 - ret =3D kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_cap_offset); + ret =3D kstrtou32_from_user(ubuf, cnt, 0, &dbg_cap_offset); if (ret) return ret; =20 /* Capability register at offset 0x14 is the last IOMMU capability regist= er. */ - if (iommu->dbg_cap_offset > 0x14) { - iommu->dbg_cap_offset =3D -1; + if (dbg_cap_offset > 0x14) return -EINVAL; - } =20 + iommu->dbg_cap_offset =3D dbg_cap_offset; return cnt; } =20 @@ -91,21 +87,21 @@ static int iommu_capability_show(struct seq_file *m, vo= id *unused) { struct amd_iommu *iommu =3D m->private; u32 value; - int err; + int err, dbg_cap_offset =3D iommu->dbg_cap_offset; =20 - if (iommu->dbg_cap_offset < 0) { + if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) { seq_puts(m, "Please provide capability register's offset in the range [0= x00 - 0x14]\n"); return 0; } =20 - err =3D pci_read_config_dword(iommu->dev, iommu->cap_ptr + iommu->dbg_cap= _offset, &value); + err =3D pci_read_config_dword(iommu->dev, iommu->cap_ptr + dbg_cap_offset= , &value); if (err) { seq_printf(m, "Not able to read capability register at 0x%x\n", - iommu->dbg_cap_offset); + dbg_cap_offset); return 0; } =20 - seq_printf(m, "Offset:0x%x Value:0x%08x\n", iommu->dbg_cap_offset, value); + seq_printf(m, "Offset:0x%x Value:0x%08x\n", dbg_cap_offset, value); =20 return 0; } --=20 2.43.7