From patchwork Fri Apr 12 08:15:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627129 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 9B7614F20C for ; Fri, 12 Apr 2024 08:15:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909723; cv=none; b=KYtE9K5vmFcl08xJK0U/P4L8dxf6uFeXr+aDzliqZyr+C4Yj74Wm75SxOKGSeBf5pGRVY5DzVcGSzaEjl3rAqQOvUyoA2ViQTzhLAMd3wmfJCwHW8nDWG7XqvUXsAJTZTEhhT3iPT80fjba+jvs1pXN9RUMhtmC9H7ygbCI8xDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909723; c=relaxed/simple; bh=qoyJpcJ2+w+2yEzQ/z6sOf/WYiiOnrEms+md8VARlN8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=b6kQl4E6xzHqLMbYCsCAvUBkzngPlCk/BaoUyS52++20JfmKcN9GfaXW2fayQDz+SUl9R8IjhcA2q91qlZFH8S1nsW2cPryzYl4+QfMTkOS1/4Ej4hlro/Yc18GISTK88X11eJpFqlg7Dgui/k+EpoRyoXhNaCKv+QANPAYHhT4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=JNc+ZQbn; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="JNc+ZQbn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909722; x=1744445722; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qoyJpcJ2+w+2yEzQ/z6sOf/WYiiOnrEms+md8VARlN8=; b=JNc+ZQbnC2YgVZup0PaTrZ0Cvbuv3DLS/1jRtEd1PzeRbgWObAT97I1l 70Ng7DTfJOds5ekvLPLj/UI5lGzaLDLoiUbL7SCpCK9yQcJoNMsi/IBq6 YtQ4pfIi1klna1WlUPtvmxsvLKkxRl0b9E4xLmg/evMCawkEOLn0gwK6r 5PuFLrx2xNxlRfto6hB4puVvAAKNrQQM1xJA1vPVLBFKojE93j7M+1xID UpnVoohje21qSFI2fYZ8Pla5eCuTt5jxC15ENswznxKka7X173jgHxLxQ moK+5jWNgogWU2ui41rOYhAK06vaKjKhsNt5xFUxWrq24tzFt49yTglZi w==; X-CSE-ConnectionGUID: vZrel8jdQKC/jRHGw1L2fw== X-CSE-MsgGUID: 8yKNJ3/ZTiCt/qhTGcx2+g== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465033" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465033" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:19 -0700 X-CSE-ConnectionGUID: 6JbL2KX/QNCZ8hE7I5tECg== X-CSE-MsgGUID: VbfGTSwmT2aRO1XYXZUWkQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137757" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:18 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 01/12] iommu: Pass old domain to set_dev_pasid op Date: Fri, 12 Apr 2024 01:15:05 -0700 Message-Id: <20240412081516.31168-2-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To support domain replacement for pasid, the underlying iommu driver needs to know the old domain hence be able to clean up the existing attachment. It would be much convenient for iommu layer to pass down the old domain. Otherwise, iommu drivers would need to track domain for pasids by themselves, this would duplicate code among the iommu drivers. Or iommu drivers would rely group->pasid_array to get domain, which may not always the correct one. Suggested-by: Jason Gunthorpe Signed-off-by: Yi Liu --- drivers/iommu/intel/iommu.c | 3 ++- drivers/iommu/intel/svm.c | 3 ++- drivers/iommu/iommu.c | 3 ++- include/linux/iommu.h | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 45c75a8a0ef5..df49aed3df5e 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4626,7 +4626,8 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, } static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid) + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) { struct device_domain_info *info = dev_iommu_priv_get(dev); struct dmar_domain *dmar_domain = to_dmar_domain(domain); diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index c1bed89b1026..ac8733b61470 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -315,7 +315,8 @@ static int pasid_to_svm_sdev(struct device *dev, unsigned int pasid, } static int intel_svm_set_dev_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid) + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) { struct device_domain_info *info = dev_iommu_priv_get(dev); struct intel_iommu *iommu = info->iommu; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 3183b0ed4cdb..701b02a118db 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3321,7 +3321,8 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain, int ret; for_each_group_device(group, device) { - ret = domain->ops->set_dev_pasid(domain, device->dev, pasid); + ret = domain->ops->set_dev_pasid(domain, device->dev, + pasid, NULL); if (ret) goto err_revert; } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 40dd439307e8..1e5e9249c93f 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -631,7 +631,7 @@ struct iommu_ops { struct iommu_domain_ops { int (*attach_dev)(struct iommu_domain *domain, struct device *dev); int (*set_dev_pasid)(struct iommu_domain *domain, struct device *dev, - ioasid_t pasid); + ioasid_t pasid, struct iommu_domain *old); int (*map_pages)(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, From patchwork Fri Apr 12 08:15:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627130 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 A6DFC4F5E6 for ; Fri, 12 Apr 2024 08:15:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909723; cv=none; b=aBoz4kEOtGyfNXg0BE8O61Pg1noEil+xgHCin18WVOOnxM9ZvPKiL35/sVWMhd9o5kKP9WkEZg4vtcHIDdpQT01XaxfEnYzC6xE1Lwyo/OTGWe9eg3lZW1huSkjqEVNw9rh2PZGJ0MP4i8RxQx1Mhpni+k9bhkGj4BZoRBEYRT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909723; c=relaxed/simple; bh=xpJTU4SSgasIaJhc5aDJUwZTh4v5WWDaG0wBjeN9SjE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=U34uI/9epdCzh582gFPVN/qLLtkBiloR32QDTaoIepnDLDGySqbwlZJw6PG/DKJGvyquXtbevGQbohj0FE+0NqBS5IdGe4uNTCt0EfAPgGqcsDSGAihnPDZcQKMxXrqUKzSYzmXlHTiXs/2jsM5kDREJ5wjlJeVCIlUFgnjGLdA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=lMsoQirQ; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lMsoQirQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909722; x=1744445722; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xpJTU4SSgasIaJhc5aDJUwZTh4v5WWDaG0wBjeN9SjE=; b=lMsoQirQs894hWVNVqz6x1vwlD/QcwOVQnuuA0SXnigQp7re65Uwb9oJ qmSBL7ALWjqaB2tDjkZcKvxSVgdGxhdDgYYitIdWW2hBWmvlHnDFQ5U9o Utq3GSJEQLBqt3SGCUrLW3CLTEOwh4OPIQoI8L49wrd27f9XQb0JVb/s7 vVt06BANnOKX81UQWd63U6O/1KLb0zEP+GRUMmuXmVASFK7Q82A0/SNff QTnfxhddNOUn1nqw1fzweOKwLAgQTxGPdy5d2SerDuzx9fpy1aFODS88T XaZEwohRKJ610us0f6jIRWrYrv0LccY6UT6w2oTCPvld4XDgGg+/rFC0F g==; X-CSE-ConnectionGUID: oRgKmCGWTw25kF75qtggTA== X-CSE-MsgGUID: lelaDpE+Sy2T/JSIP7Gleg== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465041" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465041" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:22 -0700 X-CSE-ConnectionGUID: iQPzKXeCT4KHx9SBoPNXGg== X-CSE-MsgGUID: bsPC0mo8THmJW0OswyvKQg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137780" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:21 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 02/12] iommu: Introduce a replace API for device pasid Date: Fri, 12 Apr 2024 01:15:06 -0700 Message-Id: <20240412081516.31168-3-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Provide a high-level API to allow replacements of one domain with another for specific pasid of a device. This is similar to iommu_group_replace_domain() and it is expected to be used only by IOMMUFD. Signed-off-by: Lu Baolu Signed-off-by: Yi Liu --- drivers/iommu/iommu-priv.h | 3 ++ drivers/iommu/iommu.c | 92 +++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/iommu-priv.h b/drivers/iommu/iommu-priv.h index 5f731d994803..0949c02cee93 100644 --- a/drivers/iommu/iommu-priv.h +++ b/drivers/iommu/iommu-priv.h @@ -20,6 +20,9 @@ static inline const struct iommu_ops *dev_iommu_ops(struct device *dev) int iommu_group_replace_domain(struct iommu_group *group, struct iommu_domain *new_domain); +int iommu_replace_device_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid); + int iommu_device_register_bus(struct iommu_device *iommu, const struct iommu_ops *ops, const struct bus_type *bus, diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 701b02a118db..343683e646e0 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3315,14 +3315,15 @@ bool iommu_group_dma_owner_claimed(struct iommu_group *group) EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed); static int __iommu_set_group_pasid(struct iommu_domain *domain, - struct iommu_group *group, ioasid_t pasid) + struct iommu_group *group, ioasid_t pasid, + struct iommu_domain *old) { struct group_device *device, *last_gdev; int ret; for_each_group_device(group, device) { ret = domain->ops->set_dev_pasid(domain, device->dev, - pasid, NULL); + pasid, old); if (ret) goto err_revert; } @@ -3332,11 +3333,34 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain, err_revert: last_gdev = device; for_each_group_device(group, device) { - const struct iommu_ops *ops = dev_iommu_ops(device->dev); + /* + * If no old domain, just undo all the devices/pasid that + * have attached to the new domain. + */ + if (!old) { + const struct iommu_ops *ops = + dev_iommu_ops(device->dev); + + if (device == last_gdev) + break; + ops = dev_iommu_ops(device->dev); + ops->remove_dev_pasid(device->dev, pasid, domain); + continue; + } - if (device == last_gdev) + /* + * Rollback the devices/pasid that have attached to the new + * domain. And it is a driver bug to fail attaching with a + * previously good domain. + */ + if (device == last_gdev) { + WARN_ON(old->ops->set_dev_pasid(old, device->dev, + pasid, NULL)); break; - ops->remove_dev_pasid(device->dev, pasid, domain); + } + + WARN_ON(old->ops->set_dev_pasid(old, device->dev, + pasid, domain)); } return ret; } @@ -3395,7 +3419,7 @@ int iommu_attach_device_pasid(struct iommu_domain *domain, goto out_unlock; } - ret = __iommu_set_group_pasid(domain, group, pasid); + ret = __iommu_set_group_pasid(domain, group, pasid, NULL); if (ret) xa_erase(&group->pasid_array, pasid); out_unlock: @@ -3404,6 +3428,62 @@ int iommu_attach_device_pasid(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_attach_device_pasid); +/** + * iommu_replace_device_pasid - replace the domain that a pasid is attached to + * @domain: new IOMMU domain to replace with + * @dev: the physical device + * @pasid: pasid that will be attached to the new domain + * + * This API allows the pasid to switch domains. Return 0 on success, or an + * error. The pasid will roll back to use the old domain if failure. The + * caller could call iommu_detach_device_pasid() before free the old domain + * in order to avoid use-after-free case. + */ +int iommu_replace_device_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid) +{ + /* Caller must be a probed driver on dev */ + struct iommu_group *group = dev->iommu_group; + void *curr; + int ret; + + if (!domain) + return -EINVAL; + + if (!domain->ops->set_dev_pasid) + return -EOPNOTSUPP; + + if (!group) + return -ENODEV; + + if (!dev_has_iommu(dev) || dev_iommu_ops(dev) != domain->owner) + return -EINVAL; + + mutex_lock(&group->mutex); + curr = xa_store(&group->pasid_array, pasid, domain, GFP_KERNEL); + if (!curr) { + xa_erase(&group->pasid_array, pasid); + ret = -EINVAL; + goto out_unlock; + } + + ret = xa_err(curr); + if (ret) + goto out_unlock; + + if (curr == domain) + goto out_unlock; + + ret = __iommu_set_group_pasid(domain, group, pasid, curr); + if (ret) + WARN_ON(xa_err(xa_store(&group->pasid_array, pasid, + curr, GFP_KERNEL))); +out_unlock: + mutex_unlock(&group->mutex); + return ret; +} +EXPORT_SYMBOL_NS_GPL(iommu_replace_device_pasid, IOMMUFD_INTERNAL); + /* * iommu_detach_device_pasid() - Detach the domain from pasid of device * @domain: the iommu domain. From patchwork Fri Apr 12 08:15:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627131 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 5014B50279 for ; Fri, 12 Apr 2024 08:15:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909724; cv=none; b=eM/fZZyL+oxKEmke03vWzIt5qf8m6mHn1tM0bh0qX2GmJsgByiaa2N/BUFWUg1j/7oCZX9hUOWdKOLKOS6OeQmOIZ2aaRFrhfndxfea7sAYQKkymOwYbcVAlxwxKVMTczxZwrht6K+2sh0oqdIvawacyZlk+j0ecva+qXnAISpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909724; c=relaxed/simple; bh=aYYQQq2hSnK4fvPIGonGJcOfD68/B6uLV2j4kUlorE4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hGGaYdF8RLge7XT0TLSMwAA9ke0+KMxsbmhKF2EkjYuq8o8brhplpC0++GE0NFVR3YC98v+wynKAT7z789y0Qc3+xn7cqAQbU6EhZvixIcNnEzvssg7iO3DM3dx+G1VHPIFjpHxgz7ZwHdVp+3fB4HrO1TUvL0mCiNeQrWQ9EOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=b8KiedL/; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="b8KiedL/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909724; x=1744445724; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aYYQQq2hSnK4fvPIGonGJcOfD68/B6uLV2j4kUlorE4=; b=b8KiedL/rvpEmykNE/rwDC0d0Gu+zYOk+ZHG8E4V9blHtNfSSbQ1BPF0 9UPaVkDqG/9sD5jAXN83EkwhICcuHT/iT5YU6IDEaaNW7oOun8T0PO58y baNhmPWqzDhTqH3o4V5xCGctKcE3wM3L6qoxIuue2nmg31G7QIF0oRMey TSUeUrQh3d7N4KWd/3zMuHtvKKm/hNv35PNUurU/enZSSxA7SI+eh/SPP 9Zc+VX7zDUka5x1hJogPM+LimzP31kUdXm2xGhE2MBfCwncaTMCAdQ135 503vAeAhhsSA8Q8DDURPU7raxW80UiajeL8l/P46Wn18BbEHlEvflH0HQ w==; X-CSE-ConnectionGUID: cWCBnykXRIGwp8QOz5/CaA== X-CSE-MsgGUID: e7+RKpz7Rbucc8Du9BO89Q== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465048" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465048" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:24 -0700 X-CSE-ConnectionGUID: pLHnWCAXSSOIZ6loBWFsqg== X-CSE-MsgGUID: 8YqasCllQ5Cr3kJrPulyGg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137795" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:23 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 03/12] iommufd: replace attach_fn with a structure Date: Fri, 12 Apr 2024 01:15:07 -0700 Message-Id: <20240412081516.31168-4-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Most of the core logic before conducting the actual device attach/ replace operation can be shared with pasid attach/replace. Create a new structure so more information (e.g. pasid) can be later added along with the attach_fn. Signed-off-by: Kevin Tian Signed-off-by: Yi Liu --- drivers/iommu/iommufd/device.c | 33 ++++++++++++++++--------- drivers/iommu/iommufd/iommufd_private.h | 8 ++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 873630c111c1..56e4b8e776c9 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -531,8 +531,11 @@ iommufd_device_do_replace(struct iommufd_device *idev, return ERR_PTR(rc); } -typedef struct iommufd_hw_pagetable *(*attach_fn)( - struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt); +static struct iommufd_hw_pagetable *do_attach(struct iommufd_device *idev, + struct iommufd_hw_pagetable *hwpt, struct attach_data *data) +{ + return data->attach_fn(idev, hwpt); +} /* * When automatically managing the domains we search for a compatible domain in @@ -542,7 +545,7 @@ typedef struct iommufd_hw_pagetable *(*attach_fn)( static struct iommufd_hw_pagetable * iommufd_device_auto_get_domain(struct iommufd_device *idev, struct iommufd_ioas *ioas, u32 *pt_id, - attach_fn do_attach) + struct attach_data *data) { /* * iommufd_hw_pagetable_attach() is called by @@ -551,7 +554,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, * to use the immediate_attach path as it supports drivers that can't * directly allocate a domain. */ - bool immediate_attach = do_attach == iommufd_device_do_attach; + bool immediate_attach = data->attach_fn == iommufd_device_do_attach; struct iommufd_hw_pagetable *destroy_hwpt; struct iommufd_hwpt_paging *hwpt_paging; struct iommufd_hw_pagetable *hwpt; @@ -569,7 +572,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, hwpt = &hwpt_paging->common; if (!iommufd_lock_obj(&hwpt->obj)) continue; - destroy_hwpt = (*do_attach)(idev, hwpt); + destroy_hwpt = do_attach(idev, hwpt, data); if (IS_ERR(destroy_hwpt)) { iommufd_put_object(idev->ictx, &hwpt->obj); /* @@ -596,7 +599,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, hwpt = &hwpt_paging->common; if (!immediate_attach) { - destroy_hwpt = (*do_attach)(idev, hwpt); + destroy_hwpt = do_attach(idev, hwpt, data); if (IS_ERR(destroy_hwpt)) goto out_abort; } else { @@ -618,7 +621,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, } static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, - attach_fn do_attach) + struct attach_data *data) { struct iommufd_hw_pagetable *destroy_hwpt; struct iommufd_object *pt_obj; @@ -633,7 +636,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, struct iommufd_hw_pagetable *hwpt = container_of(pt_obj, struct iommufd_hw_pagetable, obj); - destroy_hwpt = (*do_attach)(idev, hwpt); + destroy_hwpt = do_attach(idev, hwpt, data); if (IS_ERR(destroy_hwpt)) goto out_put_pt_obj; break; @@ -643,7 +646,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, container_of(pt_obj, struct iommufd_ioas, obj); destroy_hwpt = iommufd_device_auto_get_domain(idev, ioas, pt_id, - do_attach); + data); if (IS_ERR(destroy_hwpt)) goto out_put_pt_obj; break; @@ -679,8 +682,11 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id) { int rc; + struct attach_data data = { + .attach_fn = &iommufd_device_do_attach, + }; - rc = iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_attach); + rc = iommufd_device_change_pt(idev, pt_id, &data); if (rc) return rc; @@ -710,8 +716,11 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, IOMMUFD); */ int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id) { - return iommufd_device_change_pt(idev, pt_id, - &iommufd_device_do_replace); + struct attach_data data = { + .attach_fn = &iommufd_device_do_replace, + }; + + return iommufd_device_change_pt(idev, pt_id, &data); } EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, IOMMUFD); diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index 991f864d1f9b..22f0b9a3df36 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -408,6 +408,14 @@ iommufd_get_device(struct iommufd_ucmd *ucmd, u32 id) void iommufd_device_destroy(struct iommufd_object *obj); int iommufd_get_hw_info(struct iommufd_ucmd *ucmd); +struct attach_data { + union { + struct iommufd_hw_pagetable *(*attach_fn)( + struct iommufd_device *idev, + struct iommufd_hw_pagetable *hwpt); + }; +}; + struct iommufd_access { struct iommufd_object obj; struct iommufd_ctx *ictx; From patchwork Fri Apr 12 08:15:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627132 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 DCA0D4F20A for ; Fri, 12 Apr 2024 08:15:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909734; cv=none; b=QlMJfl1yxxH2aurVjiJn8AWks2vbxIszysLVqetFEzZT0pT+VIkxfkeiOgch2VBTiXzFX4g7StlhJllPAdjQX/WmHytdtVqN5NYicLQoYqtXK2CYHTdWy/yd2E/VJUl1gioxP+BMlSObpMqGPrTaNe6h1ZE8wPjLJKQtaRs0tk4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909734; c=relaxed/simple; bh=ACEk34/RP5dvOflDxOyZ6INdZQHZeKilkYWroT75ukw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=vFoiCOcSxmiSkKYJ7lXyx7o9Dfm4Zg97KhZODVcperQIC7mL/Hj6qYUS6BRLfghlQx1K8HZCcmQ7OKQ2+3akO2AjMGp1IktfS9BvVZTVgwbV/o2dKXQF+6QSeIVx76gnK7cYJuAyn29rlCIHaDLGl+obf/Ospv+Ab8qrwxCg5b0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=khTRl2gf; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="khTRl2gf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909733; x=1744445733; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ACEk34/RP5dvOflDxOyZ6INdZQHZeKilkYWroT75ukw=; b=khTRl2gf5GP65rR/5AMCIKnXAsp9mQaUVlzNxjInLoHSr7lohZ0Xg8RR YH/f7ssk1QCNguLy27El2KdnCce2/iDRserljTBV4ok1ALMlO/ScrKfJW YTT6UTl/OlGT96IW3ZNRJaq7c0+SEeKd9HFpe6Hfl+aAtWZCNWSoVDvPS +k0IfoVCb2HKiHkH1HNZqZz20gy07f/2SKsl1NMNPVfOfc/djcnXtkXSS lj/4AuL+H6R3fND58YDcDe06FfW3kk/kxTlVxKNw5/nATUBdDKTeb8HQI Ruc3a/Xffk6EBxfcbkwv+I8Lbk+QOo92LgRsdy5yFmPvl/MNJVMgD+QDM g==; X-CSE-ConnectionGUID: Ah6HUl7LR5OwgoUuceHyng== X-CSE-MsgGUID: 2LIdvGAtT62StThtBZDIxQ== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465064" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465064" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:33 -0700 X-CSE-ConnectionGUID: F1nz8HZCQ+Oyehwr9tC+5g== X-CSE-MsgGUID: q0lc6C13RYefPyGchsuvSg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137836" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:32 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 04/12] iommufd: Support attach/replace hwpt per pasid Date: Fri, 12 Apr 2024 01:15:08 -0700 Message-Id: <20240412081516.31168-5-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This introduces three APIs for device drivers to manage pasid attach/ replace/detach. int iommufd_device_pasid_attach(struct iommufd_device *idev, u32 pasid, u32 *pt_id); int iommufd_device_pasid_replace(struct iommufd_device *idev, u32 pasid, u32 *pt_id); void iommufd_device_pasid_detach(struct iommufd_device *idev, u32 pasid); pasid operations have different implications when comparing to device operations: - No connection to iommufd_group since pasid is a device capability and can be enabled only in singleton group; - no reserved region per pasid otherwise SVA architecture is already broken (CPU address space doesn't count device reserved regions); - accordingly no sw_msi trick; - immediated_attach is not supported, expecting that arm-smmu driver will already remove that requirement before supporting this pasid operation. This avoids unnecessary change in iommufd_hw_pagetable_alloc() to carry the pasid from device.c. With above differences, this puts all pasid related logics into a new pasid.c file. Cache coherency enforcement is still applied to pasid operations since it is about memory accesses post page table walking (no matter the walk is per RID or per PASID). Since the attach is per PASID, this introduces a pasid_hwpts xarray to track the per-pasid attach data. Signed-off-by: Kevin Tian Signed-off-by: Yi Liu --- drivers/iommu/iommufd/Makefile | 1 + drivers/iommu/iommufd/device.c | 14 ++- drivers/iommu/iommufd/iommufd_private.h | 15 +++ drivers/iommu/iommufd/pasid.c | 161 ++++++++++++++++++++++++ include/linux/iommufd.h | 6 + 5 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/iommufd/pasid.c diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile index 34b446146961..4b4d516b025c 100644 --- a/drivers/iommu/iommufd/Makefile +++ b/drivers/iommu/iommufd/Makefile @@ -6,6 +6,7 @@ iommufd-y := \ ioas.o \ main.o \ pages.o \ + pasid.o \ vfio_compat.o iommufd-$(CONFIG_IOMMUFD_TEST) += selftest.o diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 56e4b8e776c9..442169f8b460 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -136,6 +136,7 @@ void iommufd_device_destroy(struct iommufd_object *obj) struct iommufd_device *idev = container_of(obj, struct iommufd_device, obj); + WARN_ON(!xa_empty(&idev->pasid_hwpts)); iommu_device_release_dma_owner(idev->dev); iommufd_put_group(idev->igroup); if (!iommufd_selftest_is_mock_dev(idev->dev)) @@ -216,6 +217,8 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx, /* igroup refcount moves into iommufd_device */ idev->igroup = igroup; + xa_init(&idev->pasid_hwpts); + /* * If the caller fails after this success it must call * iommufd_unbind_device() which is safe since we hold this refcount. @@ -534,7 +537,10 @@ iommufd_device_do_replace(struct iommufd_device *idev, static struct iommufd_hw_pagetable *do_attach(struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt, struct attach_data *data) { - return data->attach_fn(idev, hwpt); + if (data->pasid == IOMMU_PASID_INVALID) + return data->attach_fn(idev, hwpt); + else + return data->pasid_attach_fn(idev, data->pasid, hwpt); } /* @@ -620,8 +626,8 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, return destroy_hwpt; } -static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, - struct attach_data *data) +int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, + struct attach_data *data) { struct iommufd_hw_pagetable *destroy_hwpt; struct iommufd_object *pt_obj; @@ -684,6 +690,7 @@ int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id) int rc; struct attach_data data = { .attach_fn = &iommufd_device_do_attach, + .pasid = IOMMU_PASID_INVALID, }; rc = iommufd_device_change_pt(idev, pt_id, &data); @@ -718,6 +725,7 @@ int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id) { struct attach_data data = { .attach_fn = &iommufd_device_do_replace, + .pasid = IOMMU_PASID_INVALID, }; return iommufd_device_change_pt(idev, pt_id, &data); diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index 22f0b9a3df36..bf42775fa1c1 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -394,6 +394,7 @@ struct iommufd_device { struct list_head group_item; /* always the physical device */ struct device *dev; + struct xarray pasid_hwpts; bool enforce_cache_coherency; }; @@ -413,9 +414,23 @@ struct attach_data { struct iommufd_hw_pagetable *(*attach_fn)( struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt); + struct iommufd_hw_pagetable *(*pasid_attach_fn)( + struct iommufd_device *idev, u32 pasid, + struct iommufd_hw_pagetable *hwpt); }; + u32 pasid; }; +int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, + struct attach_data *data); + +struct iommufd_hw_pagetable * +iommufd_device_pasid_do_attach(struct iommufd_device *idev, u32 pasid, + struct iommufd_hw_pagetable *hwpt); +struct iommufd_hw_pagetable * +iommufd_device_pasid_do_replace(struct iommufd_device *idev, u32 pasid, + struct iommufd_hw_pagetable *hwpt); + struct iommufd_access { struct iommufd_object obj; struct iommufd_ctx *ictx; diff --git a/drivers/iommu/iommufd/pasid.c b/drivers/iommu/iommufd/pasid.c new file mode 100644 index 000000000000..ee063fdb75c3 --- /dev/null +++ b/drivers/iommu/iommufd/pasid.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2024, Intel Corporation + */ +#include +#include +#include "../iommu-priv.h" + +#include "iommufd_private.h" + +struct iommufd_hw_pagetable * +iommufd_device_pasid_do_attach(struct iommufd_device *idev, u32 pasid, + struct iommufd_hw_pagetable *hwpt) +{ + void *curr; + int rc; + + refcount_inc(&hwpt->obj.users); + curr = xa_cmpxchg(&idev->pasid_hwpts, pasid, NULL, hwpt, GFP_KERNEL); + if (curr) { + if (curr == hwpt) + rc = 0; + else + rc = xa_err(curr) ? : -EBUSY; + goto err_put_hwpt; + } + + rc = iommu_attach_device_pasid(hwpt->domain, idev->dev, pasid); + if (rc) { + xa_erase(&idev->pasid_hwpts, pasid); + goto err_put_hwpt; + } + + return NULL; + +err_put_hwpt: + refcount_dec(&hwpt->obj.users); + return ERR_PTR(rc); +} + +struct iommufd_hw_pagetable * +iommufd_device_pasid_do_replace(struct iommufd_device *idev, u32 pasid, + struct iommufd_hw_pagetable *hwpt) +{ + void *curr; + int rc; + + refcount_inc(&hwpt->obj.users); + curr = xa_store(&idev->pasid_hwpts, pasid, hwpt, GFP_KERNEL); + rc = xa_err(curr); + if (rc) + goto out_put_hwpt; + + if (!curr) { + xa_erase(&idev->pasid_hwpts, pasid); + rc = -EINVAL; + goto out_put_hwpt; + } + + if (curr == hwpt) + goto out_put_hwpt; + + rc = iommu_replace_device_pasid(hwpt->domain, idev->dev, pasid); + if (rc) { + WARN_ON(xa_err(xa_store(&idev->pasid_hwpts, pasid, + curr, GFP_KERNEL))); + goto out_put_hwpt; + } + + /* Caller must destroy old_hwpt */ + return curr; + +out_put_hwpt: + refcount_dec(&hwpt->obj.users); + return ERR_PTR(rc); +} + +/** + * iommufd_device_pasid_attach - Connect a {device, pasid} to an iommu_domain + * @idev: device to attach + * @pasid: pasid to attach + * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HW_PAGETABLE + * Output the IOMMUFD_OBJ_HW_PAGETABLE ID + * + * This connects a pasid of the device to an iommu_domain. Once this + * completes the device could do DMA with the pasid. + * + * This function is undone by calling iommufd_device_detach_pasid(). + * + * iommufd does not handle race between iommufd_device_pasid_attach(), + * iommufd_device_pasid_replace() and iommufd_device_pasid_detach(). + * So caller of them should guarantee no concurrent call on the same + * device and pasid. + */ +int iommufd_device_pasid_attach(struct iommufd_device *idev, + u32 pasid, u32 *pt_id) +{ + struct attach_data data = { + .pasid_attach_fn = &iommufd_device_pasid_do_attach, + .pasid = pasid, + }; + + return iommufd_device_change_pt(idev, pt_id, &data); +} +EXPORT_SYMBOL_NS_GPL(iommufd_device_pasid_attach, IOMMUFD); + +/** + * iommufd_device_pasid_replace - Change the {device, pasid}'s iommu_domain + * @idev: device to change + * @pasid: pasid to change + * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HW_PAGETABLE + * Output the IOMMUFD_OBJ_HW_PAGETABLE ID + * + * This is the same as + * iommufd_device_pasid_detach(); + * iommufd_device_pasid_attach(); + * + * If it fails then no change is made to the attachment. The iommu driver may + * implement this so there is no disruption in translation. This can only be + * called if iommufd_device_pasid_attach() has already succeeded. + * + * iommufd does not handle race between iommufd_device_pasid_replace(), + * iommufd_device_pasid_attach() and iommufd_device_pasid_detach(). + * So caller of them should guarantee no concurrent call on the same + * device and pasid. + */ +int iommufd_device_pasid_replace(struct iommufd_device *idev, + u32 pasid, u32 *pt_id) +{ + struct attach_data data = { + .pasid_attach_fn = &iommufd_device_pasid_do_replace, + .pasid = pasid, + }; + + return iommufd_device_change_pt(idev, pt_id, &data); +} +EXPORT_SYMBOL_NS_GPL(iommufd_device_pasid_replace, IOMMUFD); + +/** + * iommufd_device_pasid_detach - Disconnect a {device, pasid} to an iommu_domain + * @idev: device to detach + * @pasid: pasid to detach + * + * Undo iommufd_device_pasid_attach(). This disconnects the idev/pasid from + * the previously attached pt_id. + * + * iommufd does not handle race between iommufd_device_pasid_detach(), + * iommufd_device_pasid_attach() and iommufd_device_pasid_replace(). + * So caller of them should guarantee no concurrent call on the same + * device and pasid. + */ +void iommufd_device_pasid_detach(struct iommufd_device *idev, u32 pasid) +{ + struct iommufd_hw_pagetable *hwpt; + + hwpt = xa_erase(&idev->pasid_hwpts, pasid); + if (WARN_ON(!hwpt)) + return; + iommu_detach_device_pasid(hwpt->domain, idev->dev, pasid); + iommufd_hw_pagetable_put(idev->ictx, hwpt); +} +EXPORT_SYMBOL_NS_GPL(iommufd_device_pasid_detach, IOMMUFD); diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h index ffc3a949f837..0b007c376306 100644 --- a/include/linux/iommufd.h +++ b/include/linux/iommufd.h @@ -26,6 +26,12 @@ int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id); int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id); void iommufd_device_detach(struct iommufd_device *idev); +int iommufd_device_pasid_attach(struct iommufd_device *idev, + u32 pasid, u32 *pt_id); +int iommufd_device_pasid_replace(struct iommufd_device *idev, + u32 pasid, u32 *pt_id); +void iommufd_device_pasid_detach(struct iommufd_device *idev, u32 pasid); + struct iommufd_ctx *iommufd_device_to_ictx(struct iommufd_device *idev); u32 iommufd_device_to_id(struct iommufd_device *idev); From patchwork Fri Apr 12 08:15:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627133 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 97B605025A for ; Fri, 12 Apr 2024 08:15:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909736; cv=none; b=N3ebKvGQROuuc6S7mfIGkPxlIyaCsoJC2dtHtTpqU849CR6jDe1eU1td/olVI9IpGKO/f+XbFsJR1VUWdGOQm8PeSO9fNKczDIQhQiGiHr1kfwTcvLtROH1eQWJfUWZQJQCM0B6y0azt5Nv3hiURyQXGySF/KuUOrPjNaQnXsNA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909736; c=relaxed/simple; bh=9+733uWB7Bw+JboyGYQ9tafFmKQKqArPjT3L3IX1sZg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uXECApRQHXFKGMXmSYjuCok22yHjkUFRrX7ThRIcTI97kV3FycHlHaQp7LGEzFG6Uip9Vf90VeFcDCFW/H0VXhnP/2omjCGOWf2TiZoOChGmIqqvNUYI0bt9dLy2ToV7JOH1ND8c8VxkEAmPixh/fSrK+tPQINn8T6LgCPll2tY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=dc+MmoFh; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="dc+MmoFh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909735; x=1744445735; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9+733uWB7Bw+JboyGYQ9tafFmKQKqArPjT3L3IX1sZg=; b=dc+MmoFhyME3mH1s3TJ4UkBEX6ZT2mfXf92bTpWI2aQImfMYQZCdF7ZV 1pH3xJykhhJQRXoj5mXwS9cuh7LHOUzUOhkK/t/VXWEmUX0N+knDPlrqf 7z4QMFl1hhWjxgcnQuVQKUuo3UNiyHX97fo+XydiFrCPaU3WpoMGAaZq6 aicaUH3OBrTCZLiCtXnX2VuGaoVhfQrrD+2uFmOHuvBqRf5+HR+W2c4cg co6nvDZKHn96GfEyA192BvIVpmGBCLnDpv6HmwI5dmrW1l0/W/VeyTQzA n+yvDr2I8OGPdUEbVIt1ECwq59JWJiu3cJT8kHiF6hHC7NEhi340zIB34 w==; X-CSE-ConnectionGUID: p/UMrbpNSpOVUDtp6in/vQ== X-CSE-MsgGUID: XY1wH+dVS/qwbuN9zOaxIg== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465069" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465069" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:34 -0700 X-CSE-ConnectionGUID: lPIpN6rGRa6tNjYsWckn9Q== X-CSE-MsgGUID: fuZgDp5GTAm95lAS8kpTPg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137843" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:33 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 05/12] iommu: Allow iommu driver to populate the max_pasids Date: Fri, 12 Apr 2024 01:15:09 -0700 Message-Id: <20240412081516.31168-6-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Today, the iommu layer gets the max_pasids by pci_max_pasids() or reading the "pasid-num-bits" property. This requires the non-PCI devices to have a "pasid-num-bits" property. Like the mock device used in iommufd selftest, otherwise the max_pasids check would fail in iommu layer. While there is an alternative, the iommu layer can allow the iommu driver to set the max_pasids in its probe_device() callback and populate it. This is simpler and has no impact on the existing cases. Suggested-by: Jason Gunthorpe Signed-off-by: Yi Liu --- drivers/iommu/iommu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 343683e646e0..dc85c251237f 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -368,9 +368,9 @@ static bool dev_has_iommu(struct device *dev) return dev->iommu && dev->iommu->iommu_dev; } -static u32 dev_iommu_get_max_pasids(struct device *dev) +static void dev_iommu_set_max_pasids(struct device *dev) { - u32 max_pasids = 0, bits = 0; + u32 max_pasids = dev->iommu->max_pasids, bits = 0; int ret; if (dev_is_pci(dev)) { @@ -383,7 +383,8 @@ static u32 dev_iommu_get_max_pasids(struct device *dev) max_pasids = 1UL << bits; } - return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids); + dev->iommu->max_pasids = min_t(u32, max_pasids, + dev->iommu->iommu_dev->max_pasids); } void dev_iommu_priv_set(struct device *dev, void *priv) @@ -433,7 +434,7 @@ static int iommu_init_device(struct device *dev, const struct iommu_ops *ops) } dev->iommu_group = group; - dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev); + dev_iommu_set_max_pasids(dev); if (ops->is_attach_deferred) dev->iommu->attach_deferred = ops->is_attach_deferred(dev); return 0; From patchwork Fri Apr 12 08:15:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627134 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 D4D2A1CAA1 for ; Fri, 12 Apr 2024 08:15:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909736; cv=none; b=VXc/MzbhRTuPoegMKHqoidt7nvvEg1i4mymkUbRH5XT6sx7WP22ofmkpEEMrk6Unj46f9436/W2qJwHSRyAGbO7lA1XyODQbTCjXbcmWtPgzjetUcbwPuY/Oe/tkuabLQsaPetKG0y0G3qm93Sp4g2VSbz+BisoEbG9M5xsM/G0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909736; c=relaxed/simple; bh=IdGVpq99NNO+hKs44+lGcKfOIZlHBFrTSuNJuQcc74M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oEIK6iNEwf81Y2GpSQLw7vW1yAbfgGJe8uzvlhRm0BvljHT/YijMdiCsjKT3rxP9vHwFYx6andcaM0zkl68ch0HmpfB3w9B1K7btr+fpdfHu2vvdcEzOb58OiJ+tcTNUxpmAjq4wv+mMA3X9xDmgXdZFUrYGbPETBCoAtWV2ZGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WodLea8V; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WodLea8V" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909735; x=1744445735; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IdGVpq99NNO+hKs44+lGcKfOIZlHBFrTSuNJuQcc74M=; b=WodLea8VzdmcDwJBauP8yLV7m38Ns3GRJCMqc3KQ1yxyuzkejeTuz8Td Dl+J4ba1RWzUMj0z3LXAAwIP8dF8pLB4lXurIBn2W4yjESmKDbMlkVSll K6vr3Wgl0WrlnshmIptD48CSdx1QpHdrTutgwBcNLUN9tgYY9XuMN2ymU L7t8p6mttFmiiJmUzwCYUzRDPmPvYRqjFp33F6Jej6KMSGlMOVJ3yhyuX agRlenxXXJogjqTP/py4cvk8bcdHuoaOLCcZm5empW/yZK2TIcI3GzDhL PIUgXfQ2763sBdNhtZ2RKXD+PL7kbVKz4TqsZpMaH+Xrtq4uyB4veg8wu Q==; X-CSE-ConnectionGUID: apEeIkQgT9SJwlIhOBED6g== X-CSE-MsgGUID: pAXpwrC9TOO2Gj9eQkPS5Q== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465080" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465080" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:35 -0700 X-CSE-ConnectionGUID: vuvOm5lwQjeVQfgKlRyHMw== X-CSE-MsgGUID: D9L7gTzXTAWqr0a0GPgB3g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137851" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:34 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 06/12] iommufd/selftest: Add set_dev_pasid and remove_dev_pasid in mock iommu Date: Fri, 12 Apr 2024 01:15:10 -0700 Message-Id: <20240412081516.31168-7-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The two callbacks are needed to make pasid_attach/detach path complete for mock device. A nop is enough for set_dev_pasid, a domain type check in the remove_dev_pasid is also helpful. Signed-off-by: Yi Liu --- drivers/iommu/iommufd/selftest.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 7a2199470f31..45e1328f0f5d 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -511,9 +511,35 @@ static struct iommu_device *mock_probe_device(struct device *dev) { if (dev->bus != &iommufd_mock_bus_type.bus) return ERR_PTR(-ENODEV); + + dev->iommu->max_pasids = 1 << 20;//20 bits return &mock_iommu_device; } +static void mock_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, + struct iommu_domain *domain) +{ + /* Domain type specific cleanup: */ + if (domain) { + switch (domain->type) { + case IOMMU_DOMAIN_NESTED: + case IOMMU_DOMAIN_UNMANAGED: + break; + default: + /* should never reach here */ + WARN_ON(1); + break; + } + } +} + +static int mock_domain_set_dev_pasid_nop(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) +{ + return 0; +} + static const struct iommu_ops mock_ops = { /* * IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type() @@ -529,6 +555,7 @@ static const struct iommu_ops mock_ops = { .capable = mock_domain_capable, .device_group = generic_device_group, .probe_device = mock_probe_device, + .remove_dev_pasid = mock_iommu_remove_dev_pasid, .default_domain_ops = &(struct iommu_domain_ops){ .free = mock_domain_free, @@ -536,6 +563,7 @@ static const struct iommu_ops mock_ops = { .map_pages = mock_domain_map_pages, .unmap_pages = mock_domain_unmap_pages, .iova_to_phys = mock_domain_iova_to_phys, + .set_dev_pasid = mock_domain_set_dev_pasid_nop, }, }; @@ -600,6 +628,7 @@ static struct iommu_domain_ops domain_nested_ops = { .free = mock_domain_free_nested, .attach_dev = mock_domain_nop_attach, .cache_invalidate_user = mock_domain_cache_invalidate_user, + .set_dev_pasid = mock_domain_set_dev_pasid_nop, }; static inline struct iommufd_hw_pagetable * @@ -1491,6 +1520,8 @@ int __init iommufd_test_init(void) &iommufd_mock_bus_type.nb); if (rc) goto err_sysfs; + + mock_iommu_device.max_pasids = (1 << 20);//20 bits return 0; err_sysfs: From patchwork Fri Apr 12 08:15:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627135 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 DCC2F50A63 for ; Fri, 12 Apr 2024 08:15:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909738; cv=none; b=k3MqG6H7N/ON2NlSj159onK7G6JYgxNsZ9Bo+pISy7kx8reiGxPRSBF9fE8ORc68SSBmY+5hdiemfI5ch3EllWUWczlcA+OQ5ZxykDHw64jxFgDxTfGKcULcKZx3lI05+qfR/CpH8YO4DFoRQLKtyAQDTN+ttmdD/3kOokiVE6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909738; c=relaxed/simple; bh=Am3pIE7+ge5z26u2xgPKEdvdLsxsgHeEHDf+EeiVypU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AhepG1X1rVaJEcpASLOu6F61dlssFyO4eucM34Pp4T6O29kf3vfCRGlZMnw+dNyj6giKI173VydbLeQCU2iFlO0gX31JQ0OhuAfXrWkFC0KJQl9e8YQzuXYfEjocbGh9JbFwETsX4EC7bRhBMuZqh2xhzqW84/XbFzPEeMM2Bhg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ZOPbCCM0; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ZOPbCCM0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909736; x=1744445736; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Am3pIE7+ge5z26u2xgPKEdvdLsxsgHeEHDf+EeiVypU=; b=ZOPbCCM0y+W/lP5pXNuFofmUeVk++PEHMvZw65HuDnzjD1t+okPKwAOI 3MrU2D3mTTKrIaVRgmivR0Ii0MWWGtVETdByF5ZmuHYCv0FeuY53EwPlz Htwb4mLDJ9bs94/3TmTHhtyHfJE23xspCQQW1R/wP3LDUpwf45pLfRzWm nChbqlpaT+3KLoC6ewfr5YdgorZXtFnM334XQT7pt4NaOcgqrvV68TjDs B452VeOQEldUJrYXw3IkvSEOHqxIPC5w/RF/qx+47Z7RMwebVZp9xVTfA Fk7n7JJuW+5o0vgpOKaAXlQceK8Dw/OWe2VvS+J8ImHE03bfj93rBFJDL w==; X-CSE-ConnectionGUID: wMB8jrfrT+GEGlE6g/CtyA== X-CSE-MsgGUID: +ZdQWbyCSaebc4vEhoFTkg== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465086" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465086" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:35 -0700 X-CSE-ConnectionGUID: 9pbjeWMFTCyhhXnnI6CGTg== X-CSE-MsgGUID: h7Cc+wATT966wf6EROEluw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137857" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:34 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 07/12] iommufd/selftest: Add a helper to get test device Date: Fri, 12 Apr 2024 01:15:11 -0700 Message-Id: <20240412081516.31168-8-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 There is need to get the selftest device (sobj->type == TYPE_IDEV) in multiple places, so have a helper to for it. Signed-off-by: Yi Liu --- drivers/iommu/iommufd/selftest.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 45e1328f0f5d..e21b076b2223 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -794,29 +794,39 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd, return rc; } -/* Replace the mock domain with a manually allocated hw_pagetable */ -static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd, - unsigned int device_id, u32 pt_id, - struct iommu_test_cmd *cmd) +static struct selftest_obj * +iommufd_test_get_self_test_device(struct iommufd_ctx *ictx, u32 id) { struct iommufd_object *dev_obj; struct selftest_obj *sobj; - int rc; /* * Prefer to use the OBJ_SELFTEST because the destroy_rwsem will ensure * it doesn't race with detach, which is not allowed. */ - dev_obj = - iommufd_get_object(ucmd->ictx, device_id, IOMMUFD_OBJ_SELFTEST); + dev_obj = iommufd_get_object(ictx, id, IOMMUFD_OBJ_SELFTEST); if (IS_ERR(dev_obj)) - return PTR_ERR(dev_obj); + return (struct selftest_obj *)dev_obj; sobj = container_of(dev_obj, struct selftest_obj, obj); if (sobj->type != TYPE_IDEV) { - rc = -EINVAL; - goto out_dev_obj; + iommufd_put_object(ictx, dev_obj); + return ERR_PTR(-EINVAL); } + return sobj; +} + +/* Replace the mock domain with a manually allocated hw_pagetable */ +static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd, + unsigned int device_id, u32 pt_id, + struct iommu_test_cmd *cmd) +{ + struct selftest_obj *sobj; + int rc; + + sobj = iommufd_test_get_self_test_device(ucmd->ictx, device_id); + if (IS_ERR(sobj)) + return PTR_ERR(sobj); rc = iommufd_device_replace(sobj->idev.idev, &pt_id); if (rc) @@ -826,7 +836,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd, rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); out_dev_obj: - iommufd_put_object(ucmd->ictx, dev_obj); + iommufd_put_object(ucmd->ictx, &sobj->obj); return rc; } From patchwork Fri Apr 12 08:15:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627136 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 68AEE5028B for ; Fri, 12 Apr 2024 08:15:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909738; cv=none; b=LTrqHImONztOk0+E1/zc7/8M59qwdK02kfHkMahsxO+HCOuqvR3SGtTD8BJgxNz1r0r2AxwiUP8WIPm7AUmamGLhK/9hVXXGfJNRFEKfKJitAvSjAZrtXNUwzbF59iBWlm8RTMUUx7YJNJchqTK3rM+oeOl/nKruP+DTw+/jyK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909738; c=relaxed/simple; bh=215NWd7XdkLGszQ3ypBe/6MHxaDS5c0uvB3nqJq+7o8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rWPdVp+Vfv9vs279Gx/IqPyPZsAzkYRrZCcHWjdlQy6IEnuv6GAvSH45RhldhzVISA8B3PSiDeaP6FSunJpzBa2IaFJwBRTWTcr+GSKuwL/yNgutmv5j9JGJbvLg6z8HRtlbNRySEE45glEARElk7/l5FiqhLTMThZtmikfK0H8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Gmu7cvqd; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Gmu7cvqd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909737; x=1744445737; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=215NWd7XdkLGszQ3ypBe/6MHxaDS5c0uvB3nqJq+7o8=; b=Gmu7cvqdfhm+5KH3mORrfLW9eGXdRDLicH6D25+ntWRui666w5ow6jkV OCbhc7yNjbpKthIN0Q6VHnE8J8Scwuyo14cN95S9MSgUV3radsu5hIxkD G/uAEsfc3Yu4Hh0ydMnUSKxl+mdlSmTpKheFcmDtOnTpZDPMk73PDG+zG WVfAJINV2qBuVZLvGU3zjI01tNiWYdBJ/82z8QJeNK/Wjd4vOzgsQ3KHP 3P7njXVazlFbG2/ZZcqtYoqMZGZj5jBmuI6m5SHle6kg+P7Mksz+fQ2uC 6TpAirKJS5+sQubig0rHBmAT7l4ZXPXd6j2vIs2//3PHdPucQKfNAPHaW A==; X-CSE-ConnectionGUID: j8+IIEUGRVaRjcpVfkmFDQ== X-CSE-MsgGUID: L167YS5pR12Lj46P+9HRUg== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465092" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465092" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:36 -0700 X-CSE-ConnectionGUID: veMmGnm2TgSJsxptZ65Huw== X-CSE-MsgGUID: zcqH2YMCThahoYJ37qkDOA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137862" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:35 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 08/12] iommufd/selftest: Add test ops to test pasid attach/detach Date: Fri, 12 Apr 2024 01:15:12 -0700 Message-Id: <20240412081516.31168-9-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This adds 4 test ops for pasid attach/replace/detach testing. There are ops to attach/detach pasid, and also op to check the attached domain of a pasid. Signed-off-by: Yi Liu --- drivers/iommu/iommufd/iommufd_test.h | 30 ++++++ drivers/iommu/iommufd/selftest.c | 135 +++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h index e854d3f67205..ee6310f07749 100644 --- a/drivers/iommu/iommufd/iommufd_test.h +++ b/drivers/iommu/iommufd/iommufd_test.h @@ -22,6 +22,10 @@ enum { IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS, IOMMU_TEST_OP_DIRTY, IOMMU_TEST_OP_MD_CHECK_IOTLB, + IOMMU_TEST_OP_PASID_ATTACH, + IOMMU_TEST_OP_PASID_REPLACE, + IOMMU_TEST_OP_PASID_DETACH, + IOMMU_TEST_OP_PASID_CHECK_DOMAIN, }; enum { @@ -127,6 +131,32 @@ struct iommu_test_cmd { __u32 id; __u32 iotlb; } check_iotlb; + struct { + __u32 pasid; + __u32 pt_id; + /* @id is stdev_id for IOMMU_TEST_OP_PASID_ATTACH + * pasid#1024 is for special test, avoid use it + * in normal case. + */ + } pasid_attach; + struct { + __u32 pasid; + __u32 pt_id; + /* @id is stdev_id for IOMMU_TEST_OP_PASID_ATTACH + * pasid#1024 is for special test, avoid use it + * in normal case. + */ + } pasid_replace; + struct { + __u32 pasid; + /* @id is stdev_id for IOMMU_TEST_OP_PASID_DETACH */ + } pasid_detach; + struct { + __u32 pasid; + __u32 hwpt_id; + __u64 out_result_ptr; + /* @id is stdev_id for IOMMU_TEST_OP_HWPT_GET_DOMAIN */ + } pasid_check; }; __u32 last; }; diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index e21b076b2223..45469213f2f9 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -516,6 +516,8 @@ static struct iommu_device *mock_probe_device(struct device *dev) return &mock_iommu_device; } +static bool pasid_1024_attached; + static void mock_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, struct iommu_domain *domain) { @@ -524,6 +526,8 @@ static void mock_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, switch (domain->type) { case IOMMU_DOMAIN_NESTED: case IOMMU_DOMAIN_UNMANAGED: + if (pasid == 1024) + pasid_1024_attached = false; break; default: /* should never reach here */ @@ -537,6 +541,20 @@ static int mock_domain_set_dev_pasid_nop(struct iommu_domain *domain, struct device *dev, ioasid_t pasid, struct iommu_domain *old) { + /* + * First attach with pasid 1024 succ, second attach would fail, + * and so on. This is helpful to test the case in which the iommu + * layer needs to rollback to old domain due to driver failure. + */ + if (pasid == 1024) { + if (pasid_1024_attached) { + pasid_1024_attached = false; + // Fake an error to fail the replacement + return -ENOMEM; + } + pasid_1024_attached = true; + } + return 0; } @@ -1414,6 +1432,114 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id, return rc; } +static int iommufd_test_pasid_attach(struct iommufd_ucmd *ucmd, + struct iommu_test_cmd *cmd) +{ + struct selftest_obj *sobj; + int rc; + + sobj = iommufd_test_get_self_test_device(ucmd->ictx, cmd->id); + if (IS_ERR(sobj)) + return PTR_ERR(sobj); + + rc = iommufd_device_pasid_attach(sobj->idev.idev, + cmd->pasid_attach.pasid, + &cmd->pasid_attach.pt_id); + iommufd_put_object(ucmd->ictx, &sobj->obj); + return rc; +} + +static int iommufd_test_pasid_replace(struct iommufd_ucmd *ucmd, + struct iommu_test_cmd *cmd) +{ + struct selftest_obj *sobj; + int rc; + + sobj = iommufd_test_get_self_test_device(ucmd->ictx, cmd->id); + if (IS_ERR(sobj)) + return PTR_ERR(sobj); + + rc = iommufd_device_pasid_replace(sobj->idev.idev, + cmd->pasid_attach.pasid, + &cmd->pasid_attach.pt_id); + iommufd_put_object(ucmd->ictx, &sobj->obj); + return rc; +} + +static int iommufd_test_pasid_detach(struct iommufd_ucmd *ucmd, + struct iommu_test_cmd *cmd) +{ + struct selftest_obj *sobj; + + sobj = iommufd_test_get_self_test_device(ucmd->ictx, cmd->id); + if (IS_ERR(sobj)) + return PTR_ERR(sobj); + + iommufd_device_pasid_detach(sobj->idev.idev, + cmd->pasid_detach.pasid); + iommufd_put_object(ucmd->ictx, &sobj->obj); + return 0; +} + +static inline struct iommufd_hw_pagetable * +iommufd_get_hwpt(struct iommufd_ucmd *ucmd, u32 id) +{ + struct iommufd_object *pt_obj; + + pt_obj = iommufd_get_object(ucmd->ictx, id, IOMMUFD_OBJ_ANY); + if (IS_ERR(pt_obj)) + return ERR_CAST(pt_obj); + + if (pt_obj->type != IOMMUFD_OBJ_HWPT_NESTED && + pt_obj->type != IOMMUFD_OBJ_HWPT_PAGING) { + iommufd_put_object(ucmd->ictx, pt_obj); + return ERR_PTR(-EINVAL); + } + + return container_of(pt_obj, struct iommufd_hw_pagetable, obj); +} + +static int iommufd_test_pasid_check_domain(struct iommufd_ucmd *ucmd, + struct iommu_test_cmd *cmd) +{ + struct iommu_domain *attached_domain, *expect_domain = NULL; + struct iommufd_hw_pagetable *hwpt = NULL; + struct selftest_obj *sobj; + struct mock_dev *mdev; + bool result; + int rc = 0; + + sobj = iommufd_test_get_self_test_device(ucmd->ictx, cmd->id); + if (IS_ERR(sobj)) + return PTR_ERR(sobj); + + mdev = sobj->idev.mock_dev; + + attached_domain = iommu_get_domain_for_dev_pasid(&mdev->dev, + cmd->pasid_check.pasid, 0); + if (IS_ERR(attached_domain)) + attached_domain = NULL; + + if (cmd->pasid_check.hwpt_id) { + hwpt = iommufd_get_hwpt(ucmd, cmd->pasid_check.hwpt_id); + if (IS_ERR(hwpt)) { + rc = PTR_ERR(hwpt); + goto out_put_dev; + } + expect_domain = hwpt->domain; + } + + result = (attached_domain == expect_domain) ? 1 : 0; + if (copy_to_user(u64_to_user_ptr(cmd->pasid_check.out_result_ptr), + &result, sizeof(result))) + rc = -EFAULT; + if (hwpt) + iommufd_put_object(ucmd->ictx, &hwpt->obj); +out_put_dev: + iommufd_put_object(ucmd->ictx, &sobj->obj); + return rc; +} + void iommufd_selftest_destroy(struct iommufd_object *obj) { struct selftest_obj *sobj = container_of(obj, struct selftest_obj, obj); @@ -1489,6 +1615,14 @@ int iommufd_test(struct iommufd_ucmd *ucmd) cmd->dirty.page_size, u64_to_user_ptr(cmd->dirty.uptr), cmd->dirty.flags); + case IOMMU_TEST_OP_PASID_ATTACH: + return iommufd_test_pasid_attach(ucmd, cmd); + case IOMMU_TEST_OP_PASID_REPLACE: + return iommufd_test_pasid_replace(ucmd, cmd); + case IOMMU_TEST_OP_PASID_DETACH: + return iommufd_test_pasid_detach(ucmd, cmd); + case IOMMU_TEST_OP_PASID_CHECK_DOMAIN: + return iommufd_test_pasid_check_domain(ucmd, cmd); default: return -EOPNOTSUPP; } @@ -1532,6 +1666,7 @@ int __init iommufd_test_init(void) goto err_sysfs; mock_iommu_device.max_pasids = (1 << 20);//20 bits + pasid_1024_attached = false; return 0; err_sysfs: From patchwork Fri Apr 12 08:15:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627137 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 4465150A93 for ; Fri, 12 Apr 2024 08:15:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909739; cv=none; b=g7DgDFoOi9qi5ktsW8nbgyjLb3/jmapipBCsKGAfnmYiLQjLqzTO+34t1WHZoIsUyLb2WUFiOXhM8hyxqc307oQevaTDj3b70VGLj9+iMvyyZnLOzVrXidQq1bSuMOdiYWaZBaFQMCNqJSAXcSJTIg9PyeYSKgxXFvvm4TUlItk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909739; c=relaxed/simple; bh=U/H8C1aSn5uCaTv+J9R/E8WKqCrtThds563oS4QgLaA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MSDcc4AaO4AgnXaqGnv6gv5qV9E9xGE+dEcLXNyqt+g+967YxV6KIDrZh1FDejkLEaGfcpOgPryi7i9up2aS8GMsWx6c1f36G2s/oNgCsp7ipiKeJtBvBcYoAcNc8z8UJ2CTePrsaSvPNN9v+/m2teZxwuqhndRndttoBnLIIuQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=g0pmhj87; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="g0pmhj87" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909738; x=1744445738; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=U/H8C1aSn5uCaTv+J9R/E8WKqCrtThds563oS4QgLaA=; b=g0pmhj87KQAp6fdHLbWC/sA85XkhhQ9hYBPfniuEaG7+OOmMrUvyjuOK +1ShJDnSW6C1akXfm5Cxj4kahJ9RUm79/XXF5oLVdkWHhTDqgyHBrTvgR Tnl5WTZ0ycaKnIhrhTBF9X1UZmDSq9Q6B7Nj9RphvlLZ+fwN1R63DQ79J VwqSZNvATySdgXAB2nRP7ydSW+72UiaO+Jw2CgcFFQpSAjk+aRPwSG4gR TGEjKepVN/+Xnhws1dKMBYkyDtfuF9vzDemw0Axz02WpSvQpu01VGorgS eZ1Lr42dYSRKi5JJlpiEH9AQe+ySEDq7Z1mi+ejVqG2eCZpFiWVOROquP w==; X-CSE-ConnectionGUID: gZsxdIeqQ068nncTVJVwKw== X-CSE-MsgGUID: Hf0KMd+vRvSmoU3Sc61r7Q== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465099" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465099" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:37 -0700 X-CSE-ConnectionGUID: kEN97UcXSU6AmousBtC0Mg== X-CSE-MsgGUID: xHFES3TNQo2GDCY2P72QcA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137873" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:36 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 09/12] iommufd/selftest: Add coverage for iommufd pasid attach/detach Date: Fri, 12 Apr 2024 01:15:13 -0700 Message-Id: <20240412081516.31168-10-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This tests iommufd pasid attach/replace/detach. Signed-off-by: Yi Liu --- tools/testing/selftests/iommu/iommufd.c | 207 ++++++++++++++++++ .../selftests/iommu/iommufd_fail_nth.c | 28 ++- tools/testing/selftests/iommu/iommufd_utils.h | 78 +++++++ 3 files changed, 309 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c index edf1c99c9936..d18b4d24fe65 100644 --- a/tools/testing/selftests/iommu/iommufd.c +++ b/tools/testing/selftests/iommu/iommufd.c @@ -2346,4 +2346,211 @@ TEST_F(vfio_compat_mock_domain, huge_map) } } +FIXTURE(iommufd_device_pasid) +{ + int fd; + uint32_t ioas_id; + uint32_t hwpt_id; + uint32_t stdev_id; + uint32_t device_id; +}; + +FIXTURE_SETUP(iommufd_device_pasid) +{ + self->fd = open("/dev/iommu", O_RDWR); + ASSERT_NE(-1, self->fd); + test_ioctl_ioas_alloc(&self->ioas_id); + + test_cmd_mock_domain(self->ioas_id, &self->stdev_id, + &self->hwpt_id, &self->device_id); +} + +FIXTURE_TEARDOWN(iommufd_device_pasid) +{ + teardown_iommufd(self->fd, _metadata); +} + +TEST_F(iommufd_device_pasid, pasid_attach) +{ + if (self->device_id) { + struct iommu_hwpt_selftest data = { + .iotlb = IOMMU_TEST_IOTLB_DEFAULT, + }; + uint32_t nested_hwpt_id[2] = {}; + uint32_t parent_hwpt_id = 0; + uint32_t pasid = 100; + bool result; + + /* Allocate two nested hwpts sharing one common parent hwpt */ + test_cmd_hwpt_alloc(self->device_id, self->ioas_id, + IOMMU_HWPT_ALLOC_NEST_PARENT, + &parent_hwpt_id); + + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0, + &nested_hwpt_id[0], + IOMMU_HWPT_DATA_SELFTEST, + &data, sizeof(data)); + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0, + &nested_hwpt_id[1], + IOMMU_HWPT_DATA_SELFTEST, + &data, sizeof(data)); + + /* + * Attach ioas to pasid 100, should succeed, domain should + * be valid. + */ + test_cmd_pasid_attach(pasid, self->ioas_id); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, self->hwpt_id, + &result)); + EXPECT_EQ(1, result); + + /* + * Try attach pasid 100 with self->ioas_id, should succeed + * as it is the same with existing hwpt. + */ + test_cmd_pasid_attach(pasid, self->ioas_id); + + /* + * Try attach pasid 100 with another hwpt, should FAIL + * as attach does not allow overwrite, use REPLACE instead. + */ + test_err_cmd_pasid_attach(EBUSY, pasid, nested_hwpt_id[0]); + + /* + * Detach hwpt from pasid 100, and check if the pasid 100 + * has null domain. Should be done before the next attach. + */ + test_cmd_pasid_detach(pasid); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, 0, &result)); + EXPECT_EQ(1, result); + + /* + * Attach nested hwpt to pasid 100, should succeed, domain + * should be valid. + */ + test_cmd_pasid_attach(pasid, nested_hwpt_id[0]); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, nested_hwpt_id[0], + &result)); + EXPECT_EQ(1, result); + + /* + * Detach hwpt from pasid 100, and check if the pasid 100 + * has null domain + */ + test_cmd_pasid_detach(pasid); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, 0, &result)); + EXPECT_EQ(1, result); + + /* Replace tests */ + pasid = 200; + + /* + * Replace pasid 200 without attaching it first, should + * fail with -EINVAL. + */ + test_err_cmd_pasid_replace(EINVAL, pasid, parent_hwpt_id); + + /* + * Attach a s2 hwpt to pasid 200, should succeed, domain should + * be valid. + */ + test_cmd_pasid_attach(pasid, parent_hwpt_id); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, parent_hwpt_id, + &result)); + EXPECT_EQ(1, result); + + /* + * Replace pasid 200 with self->ioas_id, should succeed, + * and have valid domain. + */ + test_cmd_pasid_replace(pasid, self->ioas_id); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, self->hwpt_id, + &result)); + EXPECT_EQ(1, result); + + /* + * Replace a nested hwpt for pasid 200, should succeed, + * and have valid domain. + */ + test_cmd_pasid_replace(pasid, nested_hwpt_id[0]); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, nested_hwpt_id[0], + &result)); + EXPECT_EQ(1, result); + + /* + * Replace with another nested hwpt for pasid 200, should + * succeed, and have valid domain. + */ + test_cmd_pasid_replace(pasid, nested_hwpt_id[1]); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, nested_hwpt_id[1], + &result)); + EXPECT_EQ(1, result); + + /* + * Detach hwpt from pasid 200, and check if the pasid 200 + * has null domain. + */ + test_cmd_pasid_detach(pasid); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, 0, &result)); + EXPECT_EQ(1, result); + + /* Negative Tests for pasid replace, use pasid 1024 */ + + /* + * Attach a s2 hwpt to pasid 1024, should succeed, domain should + * be valid. + */ + pasid = 1024; + test_cmd_pasid_attach(pasid, parent_hwpt_id); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, parent_hwpt_id, + &result)); + EXPECT_EQ(1, result); + + /* + * Replace pasid 1024 with self->ioas_id, should fail. + * but have the old valid domain. + */ + test_err_cmd_pasid_replace(ENOMEM, pasid, self->ioas_id); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, parent_hwpt_id, + &result)); + EXPECT_EQ(1, result); + + /* + * Detach hwpt from pasid 1024, and check if the pasid 1024 + * has null domain. + */ + test_cmd_pasid_detach(pasid); + ASSERT_EQ(0, + test_cmd_pasid_check_domain(self->fd, self->stdev_id, + pasid, 0, &result)); + EXPECT_EQ(1, result); + + test_ioctl_destroy(nested_hwpt_id[0]); + test_ioctl_destroy(nested_hwpt_id[1]); + test_ioctl_destroy(parent_hwpt_id); + } +} + TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c index f590417cd67a..6d1b03e73b9d 100644 --- a/tools/testing/selftests/iommu/iommufd_fail_nth.c +++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c @@ -206,12 +206,16 @@ FIXTURE(basic_fail_nth) { int fd; uint32_t access_id; + uint32_t stdev_id; + uint32_t pasid; }; FIXTURE_SETUP(basic_fail_nth) { self->fd = -1; self->access_id = 0; + self->stdev_id = 0; + self->pasid = 0; //test should use a non-zero value } FIXTURE_TEARDOWN(basic_fail_nth) @@ -223,6 +227,8 @@ FIXTURE_TEARDOWN(basic_fail_nth) rc = _test_cmd_destroy_access(self->access_id); assert(rc == 0); } + if (self->pasid && self->stdev_id) + _test_cmd_pasid_detach(self->fd, self->stdev_id, self->pasid); teardown_iommufd(self->fd, _metadata); } @@ -579,7 +585,6 @@ TEST_FAIL_NTH(basic_fail_nth, device) struct iommu_test_hw_info info; uint32_t ioas_id; uint32_t ioas_id2; - uint32_t stdev_id; uint32_t idev_id; uint32_t hwpt_id; __u64 iova; @@ -608,7 +613,7 @@ TEST_FAIL_NTH(basic_fail_nth, device) fail_nth_enable(); - if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, NULL, + if (_test_cmd_mock_domain(self->fd, ioas_id, &self->stdev_id, NULL, &idev_id)) return -1; @@ -619,11 +624,26 @@ TEST_FAIL_NTH(basic_fail_nth, device) IOMMU_HWPT_DATA_NONE, 0, 0)) return -1; - if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL)) + if (_test_cmd_mock_domain_replace(self->fd, self->stdev_id, ioas_id2, NULL)) + return -1; + + if (_test_cmd_mock_domain_replace(self->fd, self->stdev_id, hwpt_id, NULL)) return -1; - if (_test_cmd_mock_domain_replace(self->fd, stdev_id, hwpt_id, NULL)) + self->pasid = 200; + + /* Tests for pasid attach/replace/detach */ + if (_test_cmd_pasid_attach(self->fd, self->stdev_id, self->pasid, ioas_id)) return -1; + + if (_test_cmd_pasid_replace(self->fd, self->stdev_id, self->pasid, ioas_id2)) + return -1; + + if (_test_cmd_pasid_detach(self->fd, self->stdev_id, self->pasid)) + return -1; + + self->pasid = 0; + return 0; } diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h index 8d2b46b2114d..9b112b108670 100644 --- a/tools/testing/selftests/iommu/iommufd_utils.h +++ b/tools/testing/selftests/iommu/iommufd_utils.h @@ -684,3 +684,81 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data, #define test_cmd_get_hw_capabilities(device_id, caps, mask) \ ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, 0, &caps)) + +static int _test_cmd_pasid_attach(int fd, __u32 stdev_id, __u32 pasid, __u32 pt_id) +{ + struct iommu_test_cmd test_attach = { + .size = sizeof(test_attach), + .op = IOMMU_TEST_OP_PASID_ATTACH, + .id = stdev_id, + .pasid_attach = { + .pasid = pasid, + .pt_id = pt_id, + }, + }; + + return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_PASID_ATTACH), &test_attach); +} + +#define test_cmd_pasid_attach(pasid, hwpt_id) \ + ASSERT_EQ(0, _test_cmd_pasid_attach(self->fd, self->stdev_id, pasid, hwpt_id)) + +#define test_err_cmd_pasid_attach(_errno, pasid, hwpt_id) \ + EXPECT_ERRNO(_errno, \ + _test_cmd_pasid_attach(self->fd, self->stdev_id, pasid, hwpt_id)) + +static int _test_cmd_pasid_replace(int fd, __u32 stdev_id, __u32 pasid, __u32 pt_id) +{ + struct iommu_test_cmd test_replace = { + .size = sizeof(test_replace), + .op = IOMMU_TEST_OP_PASID_REPLACE, + .id = stdev_id, + .pasid_replace = { + .pasid = pasid, + .pt_id = pt_id, + }, + }; + + return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_PASID_REPLACE), &test_replace); +} + +#define test_cmd_pasid_replace(pasid, hwpt_id) \ + ASSERT_EQ(0, _test_cmd_pasid_replace(self->fd, self->stdev_id, pasid, hwpt_id)) + +#define test_err_cmd_pasid_replace(_errno, pasid, hwpt_id) \ + EXPECT_ERRNO(_errno, \ + _test_cmd_pasid_replace(self->fd, self->stdev_id, pasid, hwpt_id)) + +static int _test_cmd_pasid_detach(int fd, __u32 stdev_id, __u32 pasid) +{ + struct iommu_test_cmd test_detach = { + .size = sizeof(test_detach), + .op = IOMMU_TEST_OP_PASID_DETACH, + .id = stdev_id, + .pasid_detach = { + .pasid = pasid, + }, + }; + + return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_PASID_DETACH), &test_detach); +} + +#define test_cmd_pasid_detach(pasid) \ + ASSERT_EQ(0, _test_cmd_pasid_detach(self->fd, self->stdev_id, pasid)) + +static int test_cmd_pasid_check_domain(int fd, __u32 stdev_id, __u32 pasid, + __u32 hwpt_id, bool *result) +{ + struct iommu_test_cmd test_pasid_check = { + .size = sizeof(test_pasid_check), + .op = IOMMU_TEST_OP_PASID_CHECK_DOMAIN, + .id = stdev_id, + .pasid_check = { + .pasid = pasid, + .hwpt_id = hwpt_id, + .out_result_ptr = (__u64)result, + }, + }; + + return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_PASID_CHECK_DOMAIN), &test_pasid_check); +} From patchwork Fri Apr 12 08:15:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627138 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 7EE6E5102B for ; Fri, 12 Apr 2024 08:15:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909740; cv=none; b=Vz4e7at1apGsKwhKOttwc45SU/9nT4/Hbl47io/Gb9SJ7GWhx5G1Ed0Xy0g5qzEi/2hyygZeBUii53SsdYG/yijSG2kuEyHRiVEBwnZlJuyKEMFCF0jr9BMlUGhtZmmSCywTH6sBpTbHtxD/r8VuURSYWtNDV50OEOgikc3zKJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909740; c=relaxed/simple; bh=VbKNr1VzuHL0JQ6LpoEN602hRMaWoWJn/sxBUpLCH6w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EuCi4rVOf25jGUlah+gxADNUgFdhu8d11OoeLxkH6gpXdLdKapGzO9yWa0Eaz9UKTTVz6sAl2LgaBx/rBl2YJ0S6dXGpOYDcJa/pdGbI2URrNnDaO/TZNzNo8VVQ7uyFTDct2Hr5OFsIsmAjNx6KDMZN3RHTXxOByt6GvPnoX88= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=XwsePGJM; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="XwsePGJM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909739; x=1744445739; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VbKNr1VzuHL0JQ6LpoEN602hRMaWoWJn/sxBUpLCH6w=; b=XwsePGJMXFT/4fBnAGaJv5W/KXSd1EYD3ZhYWNKBgprtEwBhkxs8eOta 9x1wThxwGYd0hn6U6hQDlzGUZH5mOVn+xbKjk0SuYHGGwfTQdR0aBHR9k IBymcA0IhQgxPJ4k8Gzkc0M6UyVMoq3nKAENVykTdbvfIpWidSVQpf9h+ 18o6CCYfwk1aSbD7D0nqqwp3E939r5cpJ23eXS6LxvQPU41JPlVaKMw4u ppvFzmgQ8PCljBto+1UD33yzewCPXEbBEofSGuN67l13TnF8FS9YS6dcV Mf6vhQB/pm2mYeW4M81J/qVHheCi1mjaC/Vqn4lsKMFu4pZT1In7x7wfZ w==; X-CSE-ConnectionGUID: /s+7or3sT3CqzQvQ64nIZA== X-CSE-MsgGUID: 2RJUyYEiSEmNvLNWKX8Ojg== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465107" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465107" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:38 -0700 X-CSE-ConnectionGUID: r6KZQcsvTkWjs995ZdOV9g== X-CSE-MsgGUID: l3tgAg2aRHeBQ2zY932b0w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137877" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:36 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 10/12] iommu/vt-d: Return if no dev_pasid is found in domain Date: Fri, 12 Apr 2024 01:15:14 -0700 Message-Id: <20240412081516.31168-11-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 If no dev_pasid is found, it should be a problem of caller. So a WARN_ON is fine, but no need to go further as nothing to be cleanup and also it may hit unknown issue. Signed-off-by: Yi Liu --- drivers/iommu/intel/iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index df49aed3df5e..fff7dea012a7 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4614,8 +4614,9 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, break; } } - WARN_ON_ONCE(!dev_pasid); spin_unlock_irqrestore(&dmar_domain->lock, flags); + if (WARN_ON_ONCE(!dev_pasid)) + return; domain_detach_iommu(dmar_domain, iommu); intel_iommu_debugfs_remove_dev_pasid(dev_pasid); From patchwork Fri Apr 12 08:15:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627139 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 0ED361B81F for ; Fri, 12 Apr 2024 08:15:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909740; cv=none; b=Zwd/kQxlhfSPmv1FZKZhmulo8ntQtreebBS26XJgHqdXA0e61IuFfxpFZXFV0VHPXGfG1MFuMuygclYoNU/urzqaTOPPtmpMHH3lqAjuati0GIpo9q3srpIX1mRivhgjy4VBdsed6m26Yxd3nRNT1pJGGqMlHSxh4Kh1r6lMZC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909740; c=relaxed/simple; bh=+YxNjmAnxPz08ugfMnJTp/OXUrhN2kOcrXB2YzepySE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=P59i6610FnOfETUqRLncIM/YmlbGuJ6Y9UyT9hTRR790IKvqrscCZefvuBj8dD17saQUO06CXJlU7Xdc/k2USLtdb735PYI5I71gODSNHeX0bcDconBfVKxJn/gp+yMI8I3BPCRqCd1ImUlgwqJFWtLJL7xQ3gMl9/ZXQJf6Ix0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ZP+6CS3r; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ZP+6CS3r" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909740; x=1744445740; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+YxNjmAnxPz08ugfMnJTp/OXUrhN2kOcrXB2YzepySE=; b=ZP+6CS3rOUz8FgWsLbz0rZMGW6GdVc72yrW8Hxej5MMigXwzG4YvK92o m05jaegUmXUoh1+Cifbqm4abyzPGUEApx1K/gIN7sKE9kXZzz02ic/Jxk GkZYbdiqnRA5CKPQuok3oQuqWre2fgX2MAVDiUVnLrCIWb4CMDj+jB4V2 O6dscsw5n+QSdpjgDaY6OrzJZnJ2iKa+2mfETnmLFqDBl5vE/he+KS3pF QX007pTYa9j//la99fAy/JixdV+kdS3gq1FZZcx6vzKSZFJTejb3VA2hx +9wzsBxehKGZ0YuQ5mNDCuoUxQKSHMY5zHtcJCAR8AaH4KTNsKi6mvEBK Q==; X-CSE-ConnectionGUID: OS+Wesm8QoCkUKv+Y28MyA== X-CSE-MsgGUID: Sh5bUgtxScqw0e/Gju1tEw== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465114" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465114" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:38 -0700 X-CSE-ConnectionGUID: BLkJyJ6RT++WXfcfpW8FJw== X-CSE-MsgGUID: Cp2l4cqISM+3TniCaJCaMA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137881" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:37 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 11/12] iommu/vt-d: Make intel_iommu_set_dev_pasid() to handle domain replacement Date: Fri, 12 Apr 2024 01:15:15 -0700 Message-Id: <20240412081516.31168-12-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Existing intel_iommu_set_dev_pasid() does not support domain replacement. However, iommu layer requires set_dev_pasid() to handle domain replacement. Signed-off-by: Yi Liu --- drivers/iommu/intel/iommu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index fff7dea012a7..9e79ffdd47db 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4646,6 +4646,10 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, if (context_copied(iommu, info->bus, info->devfn)) return -EBUSY; + /* Block old translation */ + if (old) + intel_iommu_remove_dev_pasid(dev, pasid, old); + ret = prepare_domain_attach_device(domain, dev); if (ret) return ret; From patchwork Fri Apr 12 08:15:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13627140 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (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 EA88051C42 for ; Fri, 12 Apr 2024 08:15:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909742; cv=none; b=kYT+DVUq1PoFve+fyyCi6yGnwqNd8vFPzN+00Ac6E7WFJ2fUfKZxMBHJQc7PcXZpI+48CuU5ruBg7Ye5s7whhAiqZx4O5NT86aUt8+lo/DWtIVd1r7XKwTi7Ms81cdb8ObkSRebl6i9w3JHA/MTnnxy54/9HQRq4vioqN+Qp6Cg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712909742; c=relaxed/simple; bh=P1lzQYpZeJqGVZFZCQ+jo9tmCkUyhO8d2a1+/TbV4Ks=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nHsslVoGPKydY/rWfKCBgsq2q+Birs6B9t17qTvBtUhUP1V4ccepjIRFCz/9apHc6/Imc8yqjTVe4+sXseHI8MfFLkLKez8dP581DHaC1yWIm1Yc1fU4BxdszFJB7tJTsWrX8gUfwJW/sjTlsKOkC/EUAUjh4hFPogXqlnHg/Iw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=HMaIyPrF; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="HMaIyPrF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712909741; x=1744445741; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=P1lzQYpZeJqGVZFZCQ+jo9tmCkUyhO8d2a1+/TbV4Ks=; b=HMaIyPrFvfM26TRSIdB0OqPamhcmF1yNU1HnyWdLOGh0A1O92oNGrXfz Eeb5bHsDen1jBf7PlAO7fq500Gw5g08Hj9ttUMVQP4K/laDugXNr1XH8Z kvuGsXzpag6UbJze5r+Jw2n9LyqxcydHN2ZbDvqlTsp1vRcNx3z0ODDoL vUpkbOxRBlaQGy5mcGZc5yUPHkD9IxDjPfK3RYowqgbvhKV4KZefS8/g7 3S4SJGYAPIe+tyGi3ZlzZZQNYgC9ZKyrIrrg0N+msehztYzZZH7C7gfSa Y982iNitMk/V9tyBGrta+B26+ds/oqG5BS4PNfGNDM6REJD3z7rCEvM+l Q==; X-CSE-ConnectionGUID: pi8PLVT6Q3a9s/tHXP071w== X-CSE-MsgGUID: ujdRxp9VRiSCrvkPxt6x4Q== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8465125" X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="8465125" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 01:15:39 -0700 X-CSE-ConnectionGUID: 6n2xSq2YStuTo4ubur7/nQ== X-CSE-MsgGUID: Bg9fkzQeTj6dD7KrThMF+Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,195,1708416000"; d="scan'208";a="52137885" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orviesa002.jf.intel.com with ESMTP; 12 Apr 2024 01:15:38 -0700 From: Yi Liu To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com, baolu.lu@linux.intel.com Cc: alex.williamson@redhat.com, robin.murphy@arm.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, iommu@lists.linux.dev, zhenzhong.duan@intel.com, jacob.jun.pan@intel.com Subject: [PATCH v2 12/12] iommu/vt-d: Add set_dev_pasid callback for nested domain Date: Fri, 12 Apr 2024 01:15:16 -0700 Message-Id: <20240412081516.31168-13-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412081516.31168-1-yi.l.liu@intel.com> References: <20240412081516.31168-1-yi.l.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Lu Baolu This allows the upper layers to set a nested type domain to a PASID of a device if the PASID feature is supported by the IOMMU hardware. The set_dev_pasid callback for non-nested domain has already be there, so this only needs to add it for nested domains. Note that the S2 domain with dirty tracking capability is not supported yet as no user for now. Signed-off-by: Lu Baolu Signed-off-by: Yi Liu --- drivers/iommu/intel/iommu.c | 23 +++++++++++++++++++---- drivers/iommu/intel/iommu.h | 3 +++ drivers/iommu/intel/nested.c | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 9e79ffdd47db..052b90917ced 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -319,6 +319,11 @@ static int domain_type_is_si(struct dmar_domain *domain) return domain->domain.type == IOMMU_DOMAIN_IDENTITY; } +static int domain_type_is_nested(struct dmar_domain *domain) +{ + return domain->domain.type == IOMMU_DOMAIN_NESTED; +} + static int domain_pfn_supported(struct dmar_domain *domain, unsigned long pfn) { int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; @@ -4626,9 +4631,9 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, intel_drain_pasid_prq(dev, pasid); } -static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid, - struct iommu_domain *old) +int intel_iommu_set_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) { struct device_domain_info *info = dev_iommu_priv_get(dev); struct dmar_domain *dmar_domain = to_dmar_domain(domain); @@ -4650,7 +4655,15 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, if (old) intel_iommu_remove_dev_pasid(dev, pasid, old); - ret = prepare_domain_attach_device(domain, dev); + /* + * Nested type domain should adjust its parent domain according + * to iommu capability. + */ + if (domain_type_is_nested(dmar_domain)) + ret = prepare_domain_attach_device( + &dmar_domain->s2_domain->domain, dev); + else + ret = prepare_domain_attach_device(domain, dev); if (ret) return ret; @@ -4664,6 +4677,8 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, if (domain_type_is_si(dmar_domain)) ret = intel_pasid_setup_pass_through(iommu, dev, pasid); + else if (domain_type_is_nested(dmar_domain)) + ret = intel_pasid_setup_nested(iommu, dev, pasid, dmar_domain); else if (dmar_domain->use_first_level) ret = domain_setup_first_level(iommu, dmar_domain, dev, pasid); diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 404d2476a877..3dfd183c9736 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -1082,6 +1082,9 @@ void device_block_translation(struct device *dev); int prepare_domain_attach_device(struct iommu_domain *domain, struct device *dev); void domain_update_iommu_cap(struct dmar_domain *domain); +int intel_iommu_set_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old); int dmar_ir_support(void); diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c index a7d68f3d518a..7cb124cc0ca0 100644 --- a/drivers/iommu/intel/nested.c +++ b/drivers/iommu/intel/nested.c @@ -70,6 +70,20 @@ static int intel_nested_attach_dev(struct iommu_domain *domain, return 0; } +static int intel_nested_set_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) +{ + struct device_domain_info *info = dev_iommu_priv_get(dev); + struct dmar_domain *dmar_domain = to_dmar_domain(domain); + struct intel_iommu *iommu = info->iommu; + + if (iommu->agaw < dmar_domain->s2_domain->agaw) + return -EINVAL; + + return intel_iommu_set_dev_pasid(domain, dev, pasid, old); +} + static void intel_nested_domain_free(struct iommu_domain *domain) { struct dmar_domain *dmar_domain = to_dmar_domain(domain); @@ -170,6 +184,7 @@ static int intel_nested_cache_invalidate_user(struct iommu_domain *domain, static const struct iommu_domain_ops intel_nested_domain_ops = { .attach_dev = intel_nested_attach_dev, + .set_dev_pasid = intel_nested_set_dev_pasid, .free = intel_nested_domain_free, .cache_invalidate_user = intel_nested_cache_invalidate_user, };