From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 C3EF24562AB for ; Tue, 4 Aug 2026 23:55:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785887706; cv=none; b=HKniraUbA7QSNgq+JoLKY7u4tQrN8d/eiFCGeoLMhQ25kaQgXtUdu0PnmciRrc7li1vZZKJdP/ttc+FawAATPWz1hb6rNV48QAFYXUJXwuZH3JbTA4vP5L/tTmHuy9bOygo/enGBOlKwzyjT9h/lVGFl/RmNEYaMXDPUaJvloWY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785887706; c=relaxed/simple; bh=0hEoNuRKl+qs3eW7LpOd8AxqJYyeaodBDnjTITybW1k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aT1QLByfs+Ks9qg3DfackjN4j8c+irX39Jp9mjtynN2tyyksZj/O6SCVDu9AYWFvMnHjBBtLnllTJUiizhM0j9DUJiwTUVav5AFKSi2mkspq7tHUQ94aIaE6nufNQRxnhDBXE+BCSx6bA2Ds0211asPrtjJ7sE4QkCaI713NGKA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Ezcpb6Cw; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Ezcpb6Cw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785887704; x=1817423704; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0hEoNuRKl+qs3eW7LpOd8AxqJYyeaodBDnjTITybW1k=; b=Ezcpb6CwR9EvTyqh7/lh0zpQKc63R3maKpWq987czXvzjTyRa0OBnvwA 4bKFjACcpvT3ka3uLE8Qi1OwlGi+LZV8ywXIJ8XLb9+BizzOBkS6TNAuf EyKx8HNqeA9y+VKC7oz3LEnV2k2Z8AyLF27RxrK4/yBEj8crsZppZB7CT Vy1wIgF6Pn3rk0GawkVQc2zPOoip3qOl6oAfm/SFpIGHdEKDx+0WQW80z aMFyvwn5DZtpwE/CJHMkDhfMmluGcDvz83EFHqUoqCgysMugDZ7hsf3cH aZyDTvRdrpya8IX+BNZYstJzOsxMRY08hcdTqmDw6LlE2ENaarTsuNsgX g==; X-CSE-ConnectionGUID: JecWWVvkQr6RYZe4aCExvw== X-CSE-MsgGUID: V+s4y185QMq4OzE9DiFlTQ== X-IronPort-AV: E=McAfee;i="6800,10657,11865"; a="90263369" X-IronPort-AV: E=Sophos;i="6.25,205,1779174000"; d="scan'208";a="90263369" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2026 16:55:03 -0700 X-CSE-ConnectionGUID: mOtJUMH2TdCDR1uSecgebQ== X-CSE-MsgGUID: dMkpvY2LRRKoNqIKQP/Bqg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,205,1779174000"; d="scan'208";a="257324409" Received: from allen-box.sh.intel.com ([10.239.159.52]) by fmviesa006.fm.intel.com with ESMTP; 04 Aug 2026 16:55:01 -0700 From: Lu Baolu To: Joerg Roedel Cc: ZhaoJinming , Kevin Tian , Dmitry Antipov , Guanghui Feng , Li RongQing , Desnes Nunes , iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 17/19] iommu/vt-d: Fix iopf_refcount leak on RID domain replacement Date: Wed, 5 Aug 2026 07:43:11 +0800 Message-ID: <20260804234314.3087110-18-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260804234314.3087110-1-baolu.lu@linux.intel.com> References: <20260804234314.3087110-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: iommu@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit intel_iommu_attach_device() enables IOPF for the new domain but never disables it for the old one. device_block_translation(), called at the start of the function, tears down translation but does not touch any IOPF state; blocking_domain_attach_dev() has to call iopf_for_domain_remove() explicitly before invoking it for exactly this reason. identity_domain_attach_dev() has the same problem. Its comment claims that no PRI handling is needed because the device has been put in the blocking state, but the blocking state and the IOPF reference count are independent of each other. As a result, replacing a domain that has an iopf_handler with another domain at RID level leaks a reference in info->iopf_refcount. The count never drops back to zero, so iopf_queue_remove_device() is never called and iommu_disable_pci_pri() triggers its WARN_ON(info->iopf_refcount) when the device is released. The PASID paths already handle this correctly by way of iopf_for_domain_replace(); convert the two RID paths to do the same. Using the replace helper rather than a bare remove keeps the enable before the disable, so the reference count does not transiently reach zero and evict the device from the IOPF queue. Fixes: 17fce9d2336d ("iommu/vt-d: Put iopf enablement in domain attach path") Reported-by: Sashiko Closes: https://sashiko.dev/#/patchset/20260602233426.357499-1-baolu.lu%40linux.intel.com Assisted-by: Claude:claude-opus-5 Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 000b81cf4a7a..9003783d02bc 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -3152,13 +3152,13 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, if (ret) return ret; - ret = iopf_for_domain_set(domain, dev); + ret = iopf_for_domain_replace(domain, old, dev); if (ret) return ret; ret = dmar_domain_attach_device(to_dmar_domain(domain), dev); if (ret) - iopf_for_domain_remove(domain, dev); + iopf_for_domain_replace(old, domain, dev); return ret; } @@ -3861,10 +3861,13 @@ static int identity_domain_attach_dev(struct iommu_domain *domain, return 0; /* - * No PRI support with the global identity domain. No need to enable or - * disable PRI in this path as the iommu has been put in the blocking - * state. + * The identity domain has no iopf_handler, so no IOPF reference is + * taken for it. The reference held by the old domain must still be + * released here; putting the device in the blocking state above does + * not affect the IOPF reference count. */ + iopf_for_domain_remove(old, dev); + if (sm_supported(iommu)) ret = intel_pasid_setup_pass_through(iommu, dev, IOMMU_NO_PASID); else -- 2.43.0