From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 1C4F0377ECC for ; Fri, 7 Aug 2026 18:17:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786126664; cv=none; b=cp2Q8rUOAvSFFQ+mrwPApQy+32CvXQzJiC2ICQGitsYWy5VHbzajFwZ6sv2rwv/Vb4/grRvCgXFUozGdcpaHKAxbs5T0mBinvF6qBQPQUf5s8FaoKM81JdHzOTYuaDAWLMhO7PZ87qlajnGgFx2M5q9OMzVpDno5aLSWpJcUv8Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786126664; c=relaxed/simple; bh=GUJfb1dZH5eozewGcXpc6Sxm8HbaN4pR4TBhU3/Gzy0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Fkc4JCjaO48VF6UMSwRmXopSPKk0OvPvfSvcaCQbkPWSTpPmsOg0+5AIbdk2WHVnNFWuz0BV9qtuA5898ERhQSL+MrrmIe9h+pjXCsn9WBMii9grq2Bt9OST3AleleIwGS1O9PllECLCasnQu563XgcgQ+iOzoRc0gUoQ+SB1SQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=A/YJamef; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=B7hjZdV4; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="A/YJamef"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="B7hjZdV4" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 677GO5kv1149639 for ; Fri, 7 Aug 2026 18:17:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=6/g900LeMuA 9H91SWWyZJUr2BtZA/MVuA2CBGYpOYUk=; b=A/YJamefyWCCP/VUAE5x5QtbwKu 5I72lFTZwcNVILZidWXJYo5m+T/UddpFyXBALhpFXo3WaLGYhLj2bRLcO4PCnZeN 5Jalna6M+RS8xV0n2RUkJtUzHgf+fqkRQVisGCcsGjy/Njx11/BzOcmAA9GVIe55 cUzwOnYseLMatAY9XgOwNM2AUyfMyaESaqYmAG5qTkh0w1LFfu3shPRv7KuHCmTC Jagfe2GIHFNNsW8igNru0Tc8eDNbPIlclYBwbE1Wce4qBOoZHsiqEs355lgnzRSl DX9ib2770l82OrLHKUkQ9oryr+ryJmK3to+5OtLqTcDfuGFaXontkBG0FLg== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fwhk3gwpu-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 07 Aug 2026 18:17:38 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-51c1d137a68so67167951cf.3 for ; Fri, 07 Aug 2026 11:17:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786126658; x=1786731458; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=6/g900LeMuA9H91SWWyZJUr2BtZA/MVuA2CBGYpOYUk=; b=B7hjZdV4CXVTrGpe0hrWFDu1e6n6jTyL8UNI21t62B8uof1PTtBv1lfUrPTXbpgCe2 8DlYH84E7+ZmFGLgVsigpbGY9GuTWGOlB8peSZCqy4uWwGAPhGajlzWpN1I/LkpUn8IM +oWBzKQNG0qyWyatbOvh0jIc7S5fO93pnBHDvtDtq57VxwKkMcHn/fge3a+5aADSq1AE LVxNSf8Z0hXdDDLKYBPDLQL/P/0JO2H/cP21dN4i74QTYvBlvJBhmeZk6bh9vvMyTKJ4 zIE/qJWMBljPAE3tLbaYC3/KZeR04EqkapEq5wmlF02DiBEn+SGbfQpPFgLSkiCtDpWy Eifw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786126658; x=1786731458; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=6/g900LeMuA9H91SWWyZJUr2BtZA/MVuA2CBGYpOYUk=; b=betXNiYqqoM7Uo0T6IWe98WClb6t6XJnkAdrFcA6xiLZWZiWwPokkdYYzK5XsGWV0s sGgek4cIlSZLxoy9TpPXr9n7If1RitSjW1CfDi0NQw+Zcf7wCm0dNun656J93KzZyH2I +IgVsB2cAsbhj6aYciFvJvUOEv/PrLiKKjO8mD7QmLPW2iaUSvsIrtz/ghXyPANRzY41 j4Hyg70hx5jAGwb+uRcPgSvRHVoazUVDQlkk/cMqMib83jY7TumsdZXRWioBwQLkXaWs 803JH/frMWoVfp2LP/k0iEJb6cIP1NhBqXBhWupCEaTV039jm6Fy2VnFvpWft4fMflBj 5CPw== X-Gm-Message-State: AOJu0YzSyEq7/pnbRYJKu9y+18aQ7DxuuFMpDzaXS2qNW9cj+doCLMuT RntCXRtccNkR3y8AIhx5eDTdFvTFLUaoSPWBiZUCb1T/Rb0KlwVIGmL+ed74kGaVmvLBhuIHG/m yhQOJopDRBqi/dHzW1AmOgzdToJB8G1a8MR8hPlZQ4IzdBHTCYVVG+FZf7QKn9uJzkAU= X-Gm-Gg: AR+sD12764UVwUw5J6cNmDvpSIcq3az45lowjFeKuEQUHC8hinE4k9wAJUyOj3wYqmS ozb1+zMMBFqJdWCG7D+9zKQARbPdZFbnRkaUsp9D1z6k6V4Qkh+9RarotIWh0ABt2PiZwUU83To VDr4QrlVl2NOlvUwN6MmjVc0It5ISDl8QO7Wz97S2zgVcnaN43U+3Z5anyHMTp9dwtt53QRh4YF 4BPLFRPaIVujajZz3gJMOokxgoTx8c02qEi2o7hs7BBZM7B60yIVpD+jckFbC0foaVkc0mV/LLT 9pnqCzTWOEaomOAml7kFk+YHCKrOutmBVQ28ZF6AQU60nST3sInrgvTShXO2PQi6yTATOGX7KLG n9coD04IzkwvXC2dstNXsMcYjnDuymriq1Ufomnc= X-Received: by 2002:a05:622a:400d:b0:527:8651:7f7a with SMTP id d75a77b69052e-52d20a10f25mr38177041cf.26.1786126657971; Fri, 07 Aug 2026 11:17:37 -0700 (PDT) X-Received: by 2002:a05:622a:400d:b0:527:8651:7f7a with SMTP id d75a77b69052e-52d20a10f25mr38176331cf.26.1786126657521; Fri, 07 Aug 2026 11:17:37 -0700 (PDT) Received: from localhost (ip-86-49-241-13.bb.vodafone.cz. [86.49.241.13]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2080c90494sm80217466b.36.2026.08.07.11.17.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 11:17:36 -0700 (PDT) From: Andrew Jones To: linux-riscv@lists.infradead.org, iommu@lists.linux.dev Cc: linux-kernel@vger.kernel.org, tomasz.jeznach@linux.dev, tjeznach@rivosinc.com, jgg@ziepe.ca, jgg@nvidia.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, pjw@kernel.org, palmer@dabbelt.com, anup@brainfault.org, tglx@kernel.org, kevin.tian@intel.com, fangyu.yu@linux.alibaba.com Subject: [PATCH v3 11/19] iommu/riscv: Copy MSI IOVA table when replacing an iommufd domain Date: Fri, 7 Aug 2026 20:17:05 +0200 Message-ID: <20260807181713.228535-12-andrew.jones@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260807181713.228535-1-andrew.jones@oss.qualcomm.com> References: <20260807181713.228535-1-andrew.jones@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Authority-Analysis: v=2.4 cv=RKaD2Yi+ c=1 sm=1 tr=0 ts=6a762143 cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=VPysOpcHbS0DNrM1Xqmyow==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=advkBHUnGrKv1w340x8A:9 a=dawVfQjAaf238kedN5IG:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODA3MDE0MyBTYWx0ZWRfX2fOS8EhKBUzg 3masvY6ZvyweAQOBgfwKomTBIQLv1erRXPjKmQkAJBdHGSRcWxq2L5ZL6srn26fz/XEfElZA0YG gvoVR3woUoexGn+9TLsniMgNQ2dBUpQ= X-Proofpoint-ORIG-GUID: Le0K7QUohjtNwzK2A02l99la4dUb-97y X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA3MDE0MyBTYWx0ZWRfX/wnLH05hDjWV Yhvr7nvJYmaVyNYYXL6xEgHnCZgWll3Xqx4/X7C/LoJJ6J6ALg2MBN/J2aIkaoBVK5xPDaFgd1o 1s+30LRobps+N0ru/Xma1uh2+iX/xuvnunY/kQxrwHK+0cAuUV3k/bY2wYub/S2ltkBTpFs5tOq dFEunWcWGYz3Uz+UJuZExct0q+A7SDYuQq/yK0F04wpe+qkAWwv9FmRbj5g5cEnx7D8BJYMHt7N zzwIiITNP2M1zNdL3l1ZdjU8mQZnFtWw7YwTp+sduzkAo1zmx0lahuH+NpjXOT/2AphcVXAvAu5 koR1kCCySEQLEV6F16sd2Eog4i7BoWMaMV4kN+a2yztydray3H62sd7uiDj6PEJP9jp0Ci74fio W+5UtkBXrYH3YAZVF787lG15KcnsbEO7nHDo9LPHRbmu1MxbSN/cRz98bKj1m7APkp81L+HCFA2 NfdyWVAqgM67nJsCrRw== X-Proofpoint-GUID: Le0K7QUohjtNwzK2A02l99la4dUb-97y X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-07_03,2026-08-07_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 suspectscore=0 phishscore=0 impostorscore=0 adultscore=0 spamscore=0 clxscore=1015 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608070143 iommufd may replace one paging domain with another on a device while leaving the device otherwise operational, e.g. when converting a device's HWPT. If the old domain already had a populated MSI IOVA table then the new domain must inherit that table rather than wait to build its own, since the MSI IOVAs are only built on the next irq_domain_alloc_irqs(), which does not happen on a domain replacement. Only copy from an old domain that is a genuine RISC-V paging domain; iommu.c already has riscv_iommu_paging_domain_ops in scope to check this, so do the check there and pass NULL down on a mismatch. This keeps riscv_iommu_ir_attach_paging_domain() simple: a non-NULL old is always safe to cast with iommu_domain_to_riscv(). Only iommufd cookie domains are copied from and to, since VFIO type1 and DMA API domains build their own tables from irq_domain_alloc_irqs() before any device is attached, and are never replaced while a device is live. Signed-off-by: Andrew Jones --- drivers/iommu/riscv/iommu-ir.c | 78 ++++++++++++++++++++++++++++++++-- drivers/iommu/riscv/iommu.h | 2 + 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/riscv/iommu-ir.c b/drivers/iommu/riscv/iommu-ir.c index 0dff74aa9b18..7d9a1eaca92e 100644 --- a/drivers/iommu/riscv/iommu-ir.c +++ b/drivers/iommu/riscv/iommu-ir.c @@ -118,18 +118,26 @@ static int riscv_iommu_ir_irq_domain_alloc_irqs(struct irq_domain *irqdomain, * quiesced, including MSI teardown, before switching away from or freeing * the domain. iommu_dma_map_msi() requires the group mutex to be held; * take it around the domain lookup too so info->domain can't change - * out from under the build. + * out from under the build. Bump info->nr_msis here too, before + * irq_domain_alloc_irqs_parent() runs unlocked below, so a concurrent + * riscv_iommu_ir_attach_paging_domain() can never observe a count that + * is lower than the number of MSIs actually in flight for this device. */ scoped_guard(iommu_group, info->dev) { domain = rcu_dereference_protected(info->domain, true); ret = domain ? riscv_iommu_ir_build_msi_iova(domain, info->dev) : 0; + if (!ret) + info->nr_msis += nr_irqs; } if (ret) return ret; ret = irq_domain_alloc_irqs_parent(irqdomain, irq_base, nr_irqs, arg); - if (ret) + if (ret) { + guard(iommu_group)(info->dev); + info->nr_msis -= nr_irqs; return ret; + } for (i = 0; i < nr_irqs; i++) { data = irq_domain_get_irq_data(irqdomain, irq_base + i); @@ -139,9 +147,25 @@ static int riscv_iommu_ir_irq_domain_alloc_irqs(struct irq_domain *irqdomain, return 0; } +static void riscv_iommu_ir_irq_domain_free_irqs(struct irq_domain *irqdomain, + unsigned int irq_base, unsigned int nr_irqs) +{ + struct riscv_iommu_info *info = irqdomain->host_data; + + irq_domain_free_irqs_parent(irqdomain, irq_base, nr_irqs); + + /* + * Decrement only after the parent free completes, so a concurrent + * riscv_iommu_ir_attach_paging_domain() never observes a count lower + * than the number of MSIs that are actually still live. + */ + scoped_guard(iommu_group, info->dev) + info->nr_msis -= nr_irqs; +} + static const struct irq_domain_ops riscv_iommu_ir_irq_domain_ops = { .alloc = riscv_iommu_ir_irq_domain_alloc_irqs, - .free = irq_domain_free_irqs_parent, + .free = riscv_iommu_ir_irq_domain_free_irqs, }; static const struct msi_parent_ops riscv_iommu_ir_msi_parent_ops = { @@ -213,6 +237,54 @@ void riscv_iommu_ir_irq_domain_remove(struct device *dev, struct riscv_iommu_inf int riscv_iommu_ir_attach_paging_domain(struct iommu_domain *iommu_domain, struct device *dev, struct iommu_domain *old) { + struct riscv_iommu_domain *domain = iommu_domain_to_riscv(iommu_domain); + struct riscv_iommu_info *info = dev_iommu_priv_get(dev); + struct riscv_iommu_domain *old_domain = NULL; + dma_addr_t *msi_iova = NULL; + + if (old && (old->type & __IOMMU_DOMAIN_PAGING)) + old_domain = iommu_domain_to_riscv(old); + + /* + * Copying is only correct between two IOMMUFD domains: their MSI IOVAs + * come from the fd-wide SW_MSI reservation, so they match across + * domain instances. Every other cookie type derives its MSI IOVAs from + * domain-local allocator state. + */ + if (old_domain && old_domain->domain.cookie_type == IOMMU_COOKIE_IOMMUFD && + iommu_domain->cookie_type == IOMMU_COOKIE_IOMMUFD) { + scoped_guard(mutex, &old_domain->mutex) { + if (old_domain->msi_iova) { + msi_iova = kmemdup(old_domain->msi_iova, + riscv_iommu_ir_msi_iova_count() * + sizeof(*msi_iova), + GFP_KERNEL); + if (!msi_iova) + return -ENOMEM; + } + } + + if (msi_iova) { + guard(mutex)(&domain->mutex); + + if (domain->msi_iova) + kfree(msi_iova); + else + domain->msi_iova = msi_iova; + + return 0; + } + } + + /* + * No table to copy: build one from scratch if this device has ever + * allocated MSIs, since those MSIs may already be live and expecting + * riscv_iommu_ir_compose_msi_msg() to find a populated table for + * whatever domain is now attached. + */ + if (info->nr_msis) + return riscv_iommu_ir_build_msi_iova(domain, dev); + return 0; } diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h index 8bd41dd63f0e..77328282a236 100644 --- a/drivers/iommu/riscv/iommu.h +++ b/drivers/iommu/riscv/iommu.h @@ -46,6 +46,8 @@ struct riscv_iommu_info { struct riscv_iommu_domain __rcu *domain; struct irq_domain *irqdomain; struct device *dev; + /* Number of currently allocated MSIs; protected by the group mutex */ + unsigned int nr_msis; }; struct riscv_iommu_device; -- 2.43.0