From nobody Fri Feb 13 15:06:14 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (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 053F63FE4A for ; Mon, 27 May 2024 04:08:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716782893; cv=none; b=E/6ShkjO3hiiz4SWUlCBIGnwUcXsqgiNcmlk7BbIfGrP2zT4GxHnoHU+PgTHazQZwuTt2Gv90qawHXxaeXL92KNDp26aFcbmrqDvwS63+vcWxDJD6Vcfvr3OYt3lSkrjsCN6Ec6f34Vrpj6Ev/a3YEEXBdbdSAE9r3Tod4x+TAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716782893; c=relaxed/simple; bh=Ju3G17O0Dzsql60Guq1FcQXLwqsVgJXNVCWd7rDhOU8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LPF6W46rL/3tbTthEH8a3cN7Qqq1+U4MUqtotcEoiYbMAQwc2GlnxqWhOXjRHGJvAhbWnDSWJlri3J5bqTKBy1MNgsOe1MW+4gnjybwQ2GQDDVB3TvwqzMjih3m2wn/y9lFtnUBRjhIYKUlFaiehot8FJzhFBWso2U10+S5a3U4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=fkNwv5Ja; arc=none smtp.client-ip=198.175.65.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="fkNwv5Ja" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1716782892; x=1748318892; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ju3G17O0Dzsql60Guq1FcQXLwqsVgJXNVCWd7rDhOU8=; b=fkNwv5JapsYDH7UCtnShQ+lM+Dc2s2YSPLWsSD/Pw0EcsGfw92G76mIL gDKvu6GA2QM4KkNeM5XB9sCgm7ju1JPtqssg4aY7U2u/jMBARpTLdwO83 MpTfJtFcjAq+wCfX6EbcCVdbXYFU3fLDeZyOUUNdE6uHp8dDAmES0l5th BohFUrViOhmT/IhvMZUambxPuOk5TS25KvZ8RXcLCZIKIvEgpvCiNIaI6 +zoufigKUwhSOnESXRhdzHMrJcTFV2vWLBa8Eby3TQJpTdG16Son9JAl1 ATRPu9nM4NJH3l22k41PVDvv2pZuJ12A4Ncrjnzf9ar6J89h3dLRxzuR7 Q==; X-CSE-ConnectionGUID: JZ+s7w+OSPibLkHl2SzV8A== X-CSE-MsgGUID: lxs6xCATSb2ye1da7FTjWA== X-IronPort-AV: E=McAfee;i="6600,9927,11084"; a="13022917" X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="13022917" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2024 21:07:58 -0700 X-CSE-ConnectionGUID: ogDwHVDMQuaPdPZpSC0J3A== X-CSE-MsgGUID: 7qyVJlQJTx+z8rTQAaZTng== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="39400015" Received: from unknown (HELO allen-box.sh.intel.com) ([10.239.159.127]) by orviesa003.jf.intel.com with ESMTP; 26 May 2024 21:07:54 -0700 From: Lu Baolu To: Jason Gunthorpe , Kevin Tian , Joerg Roedel , Will Deacon , Robin Murphy , Jean-Philippe Brucker , Nicolin Chen , Yi Liu , Jacob Pan , Joel Granados Cc: iommu@lists.linux.dev, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v6 09/10] iommufd/selftest: Add IOPF support for mock device Date: Mon, 27 May 2024 12:05:16 +0800 Message-Id: <20240527040517.38561-10-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240527040517.38561-1-baolu.lu@linux.intel.com> References: <20240527040517.38561-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the selftest mock device to support generating and responding to an IOPF. Also add an ioctl interface to userspace applications to trigger the IOPF on the mock device. This would allow userspace applications to test the IOMMUFD's handling of IOPFs without having to rely on any real hardware. Signed-off-by: Lu Baolu --- drivers/iommu/iommufd/iommufd_test.h | 8 ++++ drivers/iommu/iommufd/selftest.c | 64 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/i= ommufd_test.h index e854d3f67205..acbbba1c6671 100644 --- a/drivers/iommu/iommufd/iommufd_test.h +++ b/drivers/iommu/iommufd/iommufd_test.h @@ -22,6 +22,7 @@ enum { IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS, IOMMU_TEST_OP_DIRTY, IOMMU_TEST_OP_MD_CHECK_IOTLB, + IOMMU_TEST_OP_TRIGGER_IOPF, }; =20 enum { @@ -127,6 +128,13 @@ struct iommu_test_cmd { __u32 id; __u32 iotlb; } check_iotlb; + struct { + __u32 dev_id; + __u32 pasid; + __u32 grpid; + __u32 perm; + __u64 addr; + } trigger_iopf; }; __u32 last; }; diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selft= est.c index 7a2199470f31..431eea438226 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -494,6 +494,7 @@ static bool mock_domain_capable(struct device *dev, enu= m iommu_cap cap) =20 switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: + case IOMMU_CAP_USER_IOASID_TABLE: return true; case IOMMU_CAP_DIRTY_TRACKING: return !(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY); @@ -504,6 +505,8 @@ static bool mock_domain_capable(struct device *dev, enu= m iommu_cap cap) return false; } =20 +static struct iopf_queue *mock_iommu_iopf_queue; + static struct iommu_device mock_iommu_device =3D { }; =20 @@ -514,6 +517,29 @@ static struct iommu_device *mock_probe_device(struct d= evice *dev) return &mock_iommu_device; } =20 +static void mock_domain_page_response(struct device *dev, struct iopf_faul= t *evt, + struct iommu_page_response *msg) +{ +} + +static int mock_dev_enable_feat(struct device *dev, enum iommu_dev_feature= s feat) +{ + if (feat !=3D IOMMU_DEV_FEAT_IOPF || !mock_iommu_iopf_queue) + return -ENODEV; + + return iopf_queue_add_device(mock_iommu_iopf_queue, dev); +} + +static int mock_dev_disable_feat(struct device *dev, enum iommu_dev_featur= es feat) +{ + if (feat !=3D IOMMU_DEV_FEAT_IOPF || !mock_iommu_iopf_queue) + return -ENODEV; + + iopf_queue_remove_device(mock_iommu_iopf_queue, dev); + + return 0; +} + static const struct iommu_ops mock_ops =3D { /* * IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type() @@ -529,6 +555,9 @@ static const struct iommu_ops mock_ops =3D { .capable =3D mock_domain_capable, .device_group =3D generic_device_group, .probe_device =3D mock_probe_device, + .page_response =3D mock_domain_page_response, + .dev_enable_feat =3D mock_dev_enable_feat, + .dev_disable_feat =3D mock_dev_disable_feat, .default_domain_ops =3D &(struct iommu_domain_ops){ .free =3D mock_domain_free, @@ -1375,6 +1404,31 @@ static int iommufd_test_dirty(struct iommufd_ucmd *u= cmd, unsigned int mockpt_id, return rc; } =20 +static int iommufd_test_trigger_iopf(struct iommufd_ucmd *ucmd, + struct iommu_test_cmd *cmd) +{ + struct iopf_fault event =3D { }; + struct iommufd_device *idev; + + idev =3D iommufd_get_device(ucmd, cmd->trigger_iopf.dev_id); + if (IS_ERR(idev)) + return PTR_ERR(idev); + + event.fault.prm.flags =3D IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE; + if (cmd->trigger_iopf.pasid !=3D IOMMU_NO_PASID) + event.fault.prm.flags |=3D IOMMU_FAULT_PAGE_REQUEST_PASID_VALID; + event.fault.type =3D IOMMU_FAULT_PAGE_REQ; + event.fault.prm.addr =3D cmd->trigger_iopf.addr; + event.fault.prm.pasid =3D cmd->trigger_iopf.pasid; + event.fault.prm.grpid =3D cmd->trigger_iopf.grpid; + event.fault.prm.perm =3D cmd->trigger_iopf.perm; + + iommu_report_device_fault(idev->dev, &event); + iommufd_put_object(ucmd->ictx, &idev->obj); + + return 0; +} + void iommufd_selftest_destroy(struct iommufd_object *obj) { struct selftest_obj *sobj =3D container_of(obj, struct selftest_obj, obj); @@ -1450,6 +1504,8 @@ 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_TRIGGER_IOPF: + return iommufd_test_trigger_iopf(ucmd, cmd); default: return -EOPNOTSUPP; } @@ -1491,6 +1547,9 @@ int __init iommufd_test_init(void) &iommufd_mock_bus_type.nb); if (rc) goto err_sysfs; + + mock_iommu_iopf_queue =3D iopf_queue_alloc("mock-iopfq"); + return 0; =20 err_sysfs: @@ -1506,6 +1565,11 @@ int __init iommufd_test_init(void) =20 void iommufd_test_exit(void) { + if (mock_iommu_iopf_queue) { + iopf_queue_free(mock_iommu_iopf_queue); + mock_iommu_iopf_queue =3D NULL; + } + iommu_device_sysfs_remove(&mock_iommu_device); iommu_device_unregister_bus(&mock_iommu_device, &iommufd_mock_bus_type.bus, --=20 2.34.1