From patchwork Thu Mar 9 07:53:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 661328 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72D52C74A5B for ; Thu, 9 Mar 2023 07:55:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229873AbjCIHzs (ORCPT ); Thu, 9 Mar 2023 02:55:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229692AbjCIHy2 (ORCPT ); Thu, 9 Mar 2023 02:54:28 -0500 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B7561815D; Wed, 8 Mar 2023 23:54:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678348445; x=1709884445; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YfHrGmLLlC66IMdEZAzrUwsFDWlZJOwnnXVx0AfELsE=; b=Gewy0W5E1ndfriV9d559DtWNH/EpVKAqsNETSqdb0foa3npJr+ChEPg0 dOYDwjtvbh6y32OW95RG/I42urvcgK+g44cwesj3IvAhfKnpyjENIR1hP 9BzCZMQM1uvfoVaw4RdHumWi3boutiVQV19L2wjCW+JTWV08tTkcVEc4h aIXiunNHJsgcPy3KDuJUPEDlyUtc1TZpxZIbAl4FxB9FsGmI/q+LyMcx1 17EQRgEnIlLCPYB/yOweRhRZefF1/GDM43zMz7lm1N7uWucd/vfPEGmgI CehkquPnZ0wxa+VlykYsmPr4dd0600mDnz4MipV4je3y0zMUjpjxozmh4 g==; X-IronPort-AV: E=McAfee;i="6500,9779,10643"; a="422652847" X-IronPort-AV: E=Sophos;i="5.98,245,1673942400"; d="scan'208";a="422652847" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2023 23:54:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10643"; a="851432750" X-IronPort-AV: E=Sophos;i="5.98,245,1673942400"; d="scan'208";a="851432750" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orsmga005.jf.intel.com with ESMTP; 08 Mar 2023 23:54:02 -0800 From: Yi Liu To: joro@8bytes.org, alex.williamson@redhat.com, jgg@nvidia.com, kevin.tian@intel.com, robin.murphy@arm.com, baolu.lu@linux.intel.com Cc: cohuck@redhat.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, mjrosato@linux.ibm.com, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, yi.y.sun@linux.intel.com, peterx@redhat.com, jasowang@redhat.com, shameerali.kolothum.thodi@huawei.com, lulu@redhat.com, suravee.suthikulpanit@amd.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v2 2/4] iommu: Add new iommu op to get iommu hardware information Date: Wed, 8 Mar 2023 23:53:56 -0800 Message-Id: <20230309075358.571567-3-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230309075358.571567-1-yi.l.liu@intel.com> References: <20230309075358.571567-1-yi.l.liu@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org From: Lu Baolu Introduce a new iommu op to get the IOMMU hardware capabilities for iommufd. This information will be used by any vIOMMU driver which is owned by userspace. This op chooses to make the special parameters opaque to the core. This suits the current usage model where accessing any of the IOMMU device special parameters does require a userspace driver that matches the kernel driver. If a need for common parameters, implemented similarly by several drivers, arises then there's room in the design to grow a generic parameter set as well. No wrapper API is added as it is supposed to be used by iommufd only. Different IOMMU hardware would have different hardware information. So the information reported differs as well. To let the external user understand the difference. enum iommu_hw_info_type is defined. For the iommu drivers that are capable to report hardware information, it should have a unique iommu_hw_info_type. The iommu_hw_info_type is stored in struct iommu_ops. For the driver oesn't report hardware information, just use IOMMU_HW_INFO_TYPE_DEFAULT. Signed-off-by: Lu Baolu Co-developed-by: Nicolin Chen Signed-off-by: Nicolin Chen Signed-off-by: Yi Liu --- include/linux/iommu.h | 13 +++++++++++++ include/uapi/linux/iommufd.h | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7202d8ece343..3ef84ee359d2 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -15,6 +15,7 @@ #include #include #include +#include #define IOMMU_READ (1 << 0) #define IOMMU_WRITE (1 << 1) @@ -222,6 +223,11 @@ struct iommu_iotlb_gather { /** * struct iommu_ops - iommu ops and capabilities * @capable: check capability + * @hw_info: IOMMU hardware information. The type of the returned data is + * defined in include/uapi/linux/iommufd.h. The data buffer is + * allocated in the IOMMU driver and the caller should free it + * after use. Return the data buffer if success, or ERR_PTR on + * failure. * @domain_alloc: allocate iommu domain * @probe_device: Add device to iommu driver handling * @release_device: Remove device from iommu driver handling @@ -246,11 +252,17 @@ struct iommu_iotlb_gather { * @remove_dev_pasid: Remove any translation configurations of a specific * pasid, so that any DMA transactions with this pasid * will be blocked by the hardware. + * @driver_type: One of enum iommu_hw_info_type. This is used in the hw_info + * reporting path. For the drivers that supports it, a unique + * type should be defined. For the driver that does not support + * it, this field is the IOMMU_HW_INFO_TYPE_DEFAULT that is 0. + * Hence, such drivers do not need to care this field. * @pgsize_bitmap: bitmap of all possible supported page sizes * @owner: Driver module providing these ops */ struct iommu_ops { bool (*capable)(struct device *dev, enum iommu_cap); + void *(*hw_info)(struct device *dev, u32 *length); /* Domain allocation and freeing by the iommu driver */ struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type); @@ -279,6 +291,7 @@ struct iommu_ops { void (*remove_dev_pasid)(struct device *dev, ioasid_t pasid); const struct iommu_domain_ops *default_domain_ops; + enum iommu_hw_info_type driver_type; unsigned long pgsize_bitmap; struct module *owner; }; diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index ccd36acad36a..955cbef640da 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -370,4 +370,11 @@ struct iommu_hwpt_alloc { __u32 __reserved; }; #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) + +/** + * enum iommu_hw_info_type - IOMMU Hardware Info Types + */ +enum iommu_hw_info_type { + IOMMU_HW_INFO_TYPE_DEFAULT, +}; #endif From patchwork Thu Mar 9 07:53:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 661329 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1FD9C742A7 for ; Thu, 9 Mar 2023 07:55:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229532AbjCIHzr (ORCPT ); Thu, 9 Mar 2023 02:55:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230100AbjCIHyc (ORCPT ); Thu, 9 Mar 2023 02:54:32 -0500 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 666C5C15C; Wed, 8 Mar 2023 23:54:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678348451; x=1709884451; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jmUqj4gFzFf1bk/blwMUJTq0+ikbJFi2lqRYVPnMXWw=; b=gRpz4ic+Kg7rCIGL5W+BBFbO/DHS9i/NWbHM6Sm6bkv/h1hOe6x8OSEm hDWOCPuk3UenGDcZ5zM4CmvTbBYcp8tGs2KKPNOQEyLmomzyhno3rbtQ5 3E1OtecO1tOijqUq+/Sb65+/JHGwbX0S2IrfG/FRdLLQoXBMw0LotG5bW SZzQYibO8H2C9nVkGnTKlWk5PKnysqs1oUClqiokVBC/cz2F0l687KVnR ci76yotBPWrIcAGPTwlZUQaNFo79C6bJHberg6Cin7ub0Pi7NlWIe+WMn yyUN/LJEjBJ9+Xh1rjnMwdXbA5iqeLrIu2WEjhSh63LlMwJFipEMG55xi Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10643"; a="422652868" X-IronPort-AV: E=Sophos;i="5.98,245,1673942400"; d="scan'208";a="422652868" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2023 23:54:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10643"; a="851432770" X-IronPort-AV: E=Sophos;i="5.98,245,1673942400"; d="scan'208";a="851432770" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orsmga005.jf.intel.com with ESMTP; 08 Mar 2023 23:54:04 -0800 From: Yi Liu To: joro@8bytes.org, alex.williamson@redhat.com, jgg@nvidia.com, kevin.tian@intel.com, robin.murphy@arm.com, baolu.lu@linux.intel.com Cc: cohuck@redhat.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, mjrosato@linux.ibm.com, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, yi.y.sun@linux.intel.com, peterx@redhat.com, jasowang@redhat.com, shameerali.kolothum.thodi@huawei.com, lulu@redhat.com, suravee.suthikulpanit@amd.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v2 4/4] iommufd/selftest: Add coverage for IOMMU_DEVICE_GET_HW_INFO ioctl Date: Wed, 8 Mar 2023 23:53:58 -0800 Message-Id: <20230309075358.571567-5-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230309075358.571567-1-yi.l.liu@intel.com> References: <20230309075358.571567-1-yi.l.liu@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org From: Nicolin Chen Add a mock_domain_hw_info function and an iommu_hw_info_selftest data structure. This allows to test the IOMMU_DEVICE_GET_HW_INFO ioctl by passing the test_reg value for the mock_dev. Signed-off-by: Nicolin Chen Signed-off-by: Yi Liu --- drivers/iommu/iommufd/device.c | 1 + drivers/iommu/iommufd/iommufd_test.h | 15 +++++++++++ drivers/iommu/iommufd/selftest.c | 16 ++++++++++++ tools/testing/selftests/iommu/iommufd.c | 17 +++++++++++- tools/testing/selftests/iommu/iommufd_utils.h | 26 +++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 6948539488a5..5c352807d946 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -8,6 +8,7 @@ #include "io_pagetable.h" #include "iommufd_private.h" +#include "iommufd_test.h" static bool allow_unsafe_interrupts; module_param(allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h index da1898a9128f..578691602d94 100644 --- a/drivers/iommu/iommufd/iommufd_test.h +++ b/drivers/iommu/iommufd/iommufd_test.h @@ -100,4 +100,19 @@ struct iommu_test_cmd { }; #define IOMMU_TEST_CMD _IO(IOMMUFD_TYPE, IOMMUFD_CMD_BASE + 32) +/* Mock structs for IOMMU_DEVICE_GET_HW_INFO ioctl */ +#define IOMMU_HW_INFO_TYPE_SELFTEST 0xfeedbeef +#define IOMMU_HW_INFO_SELFTEST_REGVAL 0xdeadbeef + +/** + * struct iommu_hw_info_selftest + * + * @flags: Must be set to 0 + * @test_reg: Pass IOMMU_HW_INFO_SELFTEST_REGVAL to user selftest program + */ +struct iommu_hw_info_selftest { + __u32 flags; + __u32 test_reg; +}; + #endif diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index d7832ffc3aa6..b50ec3528ec1 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -128,6 +128,20 @@ static struct iommu_domain mock_blocking_domain = { .ops = &mock_blocking_ops, }; +static void *mock_domain_hw_info(struct device *dev, u32 *length) +{ + struct iommu_hw_info_selftest *info; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + info->test_reg = IOMMU_HW_INFO_SELFTEST_REGVAL; + *length = sizeof(*info); + + return info; +} + static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type) { struct mock_iommu_domain *mock; @@ -279,6 +293,8 @@ static void mock_domain_set_plaform_dma_ops(struct device *dev) static const struct iommu_ops mock_ops = { .owner = THIS_MODULE, .pgsize_bitmap = MOCK_IO_PAGE_SIZE, + .driver_type = IOMMU_HW_INFO_TYPE_SELFTEST, + .hw_info = mock_domain_hw_info, .domain_alloc = mock_domain_alloc, .capable = mock_domain_capable, .set_platform_dma_ops = mock_domain_set_plaform_dma_ops, diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c index 5c33b6b52c65..d2ce2ddbdc40 100644 --- a/tools/testing/selftests/iommu/iommufd.c +++ b/tools/testing/selftests/iommu/iommufd.c @@ -124,6 +124,7 @@ TEST_F(iommufd, cmd_length) TEST_LENGTH(iommu_ioas_unmap, IOMMU_IOAS_UNMAP); TEST_LENGTH(iommu_option, IOMMU_OPTION); TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS); + TEST_LENGTH(iommu_hw_info, IOMMU_DEVICE_GET_HW_INFO); #undef TEST_LENGTH } @@ -188,6 +189,7 @@ FIXTURE(iommufd_ioas) uint32_t ioas_id; uint32_t stdev_id; uint32_t hwpt_id; + uint32_t device_id; uint64_t base_iova; }; @@ -214,7 +216,7 @@ FIXTURE_SETUP(iommufd_ioas) for (i = 0; i != variant->mock_domains; i++) { test_cmd_mock_domain(self->ioas_id, &self->stdev_id, - &self->hwpt_id, NULL); + &self->hwpt_id, &self->device_id); self->base_iova = MOCK_APERTURE_START; } } @@ -293,6 +295,19 @@ TEST_F(iommufd_ioas, ioas_area_auto_destroy) } } +TEST_F(iommufd_ioas, device_get_hw_info) +{ + struct iommu_hw_info_selftest info; + + if (self->device_id) { + test_cmd_device_get_hw_info(self->device_id, sizeof(info), &info); + assert(info.test_reg == IOMMU_HW_INFO_SELFTEST_REGVAL); + } else { + test_err_device_get_hw_info(ENOENT, self->device_id, + sizeof(info), &info); + } +} + TEST_F(iommufd_ioas, area) { int i; diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h index 399779acce23..b57e1e60f69d 100644 --- a/tools/testing/selftests/iommu/iommufd_utils.h +++ b/tools/testing/selftests/iommu/iommufd_utils.h @@ -345,3 +345,29 @@ static void teardown_iommufd(int fd, struct __test_metadata *_metadata) }) #endif + +static int _test_cmd_device_get_hw_info(int fd, __u32 device_id, + __u32 data_len, void *data) +{ + struct iommu_hw_info cmd = { + .size = sizeof(cmd), + .dev_id = device_id, + .data_len = data_len, + .data_ptr = (uint64_t)data, + }; + int ret; + + ret = ioctl(fd, IOMMU_DEVICE_GET_HW_INFO, &cmd); + if (ret) + return ret; + return 0; +} + +#define test_cmd_device_get_hw_info(device_id, data_len, data) \ + ASSERT_EQ(0, _test_cmd_device_get_hw_info(self->fd, device_id, \ + data_len, data)) + +#define test_err_device_get_hw_info(_errno, device_id, data_len, data) \ + EXPECT_ERRNO(_errno, \ + _test_cmd_device_get_hw_info(self->fd, device_id, \ + data_len, data))