From: Andrew Jones <andrew.jones@oss.qualcomm.com>
To: iommu@lists.linux.dev, kvm-riscv@lists.infradead.org,
kvm@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: tomasz.jeznach@linux.dev, jgg@ziepe.ca, jgg@nvidia.com,
joro@8bytes.org, will@kernel.org, robin.murphy@arm.com,
pjw@kernel.org, palmer@dabbelt.com, tglx@kernel.org,
anup@brainfault.org, atish.patra@linux.dev,
fangyu.yu@linux.alibaba.com, zhangzhanpeng.jasper@bytedance.com,
zong.li@sifive.com
Subject: [RFC PATCH v3 02/14] iommu/riscv: Prepare domain bonds for outer locking
Date: Mon, 28 Sep 2026 16:31:01 +0200 [thread overview]
Message-ID: <20260928143113.49838-3-andrew.jones@oss.qualcomm.com> (raw)
In-Reply-To: <20260928143113.49838-1-andrew.jones@oss.qualcomm.com>
IRQ bypass will serialize attachment under a raw spinlock. Bond updates
retain their own lock, so make it raw for safe PREEMPT_RT nesting.
MSI forwarding will acquire the MSI table lock under the hardirq-safe
IRQ descriptor lock. Nesting the bond lock below the MSI table lock
therefore requires IRQ protection even for domains without an MSI
table, where attachment takes only the bond lock. Use irqsave/irqrestore
in both bond helpers to avoid a HARDIRQ-safe to HARDIRQ-unsafe lock
dependency.
Also split allocation from list insertion so a future outer lock can be
taken after the sleeping allocation.
No functional change intended.
Signed-off-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
---
drivers/iommu/riscv/iommu.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 3bbb4d0d0a85..09ec8c3e4a72 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -858,7 +858,7 @@ struct riscv_iommu_domain {
struct pt_iommu_riscv_64 riscvpt;
};
struct list_head bonds;
- spinlock_t lock; /* protect bonds list updates. */
+ raw_spinlock_t lock; /* protect bonds list updates. */
struct mutex mutex; /* serialize domain state updates */
int pscid;
int gscid;
@@ -896,34 +896,27 @@ struct riscv_iommu_bond {
struct device *dev;
};
-static int riscv_iommu_bond_link(struct riscv_iommu_domain *domain,
- struct device *dev)
+static void riscv_iommu_bond_link(struct riscv_iommu_domain *domain,
+ struct riscv_iommu_bond *bond)
{
- struct riscv_iommu_device *iommu = dev_to_iommu(dev);
- struct riscv_iommu_bond *bond;
+ struct riscv_iommu_device *iommu = dev_to_iommu(bond->dev);
struct list_head *bonds;
-
- bond = kzalloc_obj(*bond);
- if (!bond)
- return -ENOMEM;
- bond->dev = dev;
+ unsigned long flags;
/*
* List of devices attached to the domain is arranged based on
* managed IOMMU device.
*/
- spin_lock(&domain->lock);
+ raw_spin_lock_irqsave(&domain->lock, flags);
list_for_each(bonds, &domain->bonds)
if (dev_to_iommu(list_entry(bonds, struct riscv_iommu_bond, list)->dev) == iommu)
break;
list_add_rcu(&bond->list, bonds);
- spin_unlock(&domain->lock);
+ raw_spin_unlock_irqrestore(&domain->lock, flags);
/* Synchronize with riscv_iommu_iotlb_inval() sequence. See comment below. */
smp_mb();
-
- return 0;
}
static void riscv_iommu_bond_unlink(struct riscv_iommu_domain *domain,
@@ -932,12 +925,13 @@ static void riscv_iommu_bond_unlink(struct riscv_iommu_domain *domain,
struct riscv_iommu_device *iommu = dev_to_iommu(dev);
struct riscv_iommu_bond *bond, *found = NULL;
struct riscv_iommu_command cmd;
+ unsigned long flags;
int count = 0;
if (!domain)
return;
- spin_lock(&domain->lock);
+ raw_spin_lock_irqsave(&domain->lock, flags);
list_for_each_entry(bond, &domain->bonds, list) {
if (found && count)
break;
@@ -948,7 +942,7 @@ static void riscv_iommu_bond_unlink(struct riscv_iommu_domain *domain,
}
if (found)
list_del_rcu(&found->list);
- spin_unlock(&domain->lock);
+ raw_spin_unlock_irqrestore(&domain->lock, flags);
kfree_rcu(found, rcu);
/*
@@ -1391,6 +1385,7 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
struct riscv_iommu_domain *domain = iommu_domain_to_riscv(iommu_domain);
struct riscv_iommu_device *iommu = dev_to_iommu(dev);
struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
+ struct riscv_iommu_bond *bond;
struct pt_iommu_riscv_64_hw_info pt_info;
struct riscv_iommu_dc dc = {0};
int ret;
@@ -1421,9 +1416,12 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
dc.ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) |
RISCV_IOMMU_PC_TA_V;
- if (riscv_iommu_bond_link(domain, dev))
+ bond = kzalloc_obj(*bond);
+ if (!bond)
return -ENOMEM;
+ bond->dev = dev;
+ riscv_iommu_bond_link(domain, bond);
riscv_iommu_iodir_update(iommu, dev, &dc);
riscv_iommu_bond_unlink(info->domain, dev);
info->domain = domain;
@@ -1475,7 +1473,7 @@ riscv_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags,
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD_RCU(&domain->bonds);
- spin_lock_init(&domain->lock);
+ raw_spin_lock_init(&domain->lock);
mutex_init(&domain->mutex);
iommu = dev_to_iommu(dev);
cfg.common.hw_max_oasz_lg2 = 56;
--
2.43.0
next prev parent reply other threads:[~2026-09-28 14:31 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 14:30 [RFC PATCH v3 00/14] iommu/riscv: Add irqbypass support Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 01/14] iommu/riscv: Allocate MSI tables for second-stage domains Andrew Jones
2026-10-05 13:25 ` Andrew Jones
2026-09-28 14:31 ` Andrew Jones [this message]
2026-09-28 14:31 ` [RFC PATCH v3 03/14] iommu/riscv: Serialize MSI table publication with domain attachment Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 04/14] iommu/riscv: Reject live S2 replacement with forwarded IRQs Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 05/14] iommu/riscv: Derive the IOMMU from the device in IODIR updates Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 06/14] iommu/riscv: Cache the programmed device context Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 07/14] iommu/riscv: Prepare MSI table updates for interrupt remapping Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 08/14] irqchip/riscv-imsic: Define IOMMU IRQ bypass protocol Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 09/14] genirq/msi: Provide DOMAIN_BUS_MSI_REMAP Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 10/14] iommu/riscv: Add IRQ domain for interrupt remapping Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 11/14] iommu/riscv: Prepare info->domain for concurrent RCU access Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 12/14] iommu/riscv: Prepare interrupt remapping for IRQ bypass Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 13/14] iommu/riscv: Validate IRQ forwarding requests Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 14/14] iommu/riscv: Implement IRQ forwarding Andrew Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260928143113.49838-3-andrew.jones@oss.qualcomm.com \
--to=andrew.jones@oss.qualcomm.com \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=fangyu.yu@linux.alibaba.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=kvm-riscv@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=robin.murphy@arm.com \
--cc=tglx@kernel.org \
--cc=tomasz.jeznach@linux.dev \
--cc=will@kernel.org \
--cc=zhangzhanpeng.jasper@bytedance.com \
--cc=zong.li@sifive.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox