From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 D404A20C480; Thu, 17 Jul 2025 18:34:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777258; cv=fail; b=qYY6TS0NUTosdmNlylISHXommwrafl4WBu+Dhe6/IUY1/WgjiVEhN3ycgr6EZ+EtYd+Hi8eFyLomixqVHWfsGm40sTrZ7LmU9BPvTmvQh0QvSgp+BzEwk86YFW7bSeOWZgSTWYY4q9xZBd4iSAZp3G78hATjmKEZsn0KSSzWVeg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777258; c=relaxed/simple; bh=QFI8HJK4dFzbwAJvau4vSUdpu6JqHdZRbf1WQqa6ySg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=INp9o2Z6uOfdfZokRc91eVwWcL5e6hnCeSP1KpNus4DQueA1dRXvdX7j6enJ6rmjfHMjD4KaIm+O/nK15GwAukjWFUCur8ZFxS/dnwCxzlDnA6oA3qjRcM/yA2kct1j4qapZpLoH+iFpwTElm4/W8BwpLHu9WgNoN3w/kcEiDt4= ARC-Authentication-Results: i=2; 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=jk21E5ak; arc=fail smtp.client-ip=198.175.65.19 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="jk21E5ak" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777257; x=1784313257; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=QFI8HJK4dFzbwAJvau4vSUdpu6JqHdZRbf1WQqa6ySg=; b=jk21E5ak/B97y8/bFP5f4o0FnkezEAyJh1/mgXg40AHn+2WXvkIuEmFR AvGB7ZjiyyzufJjT5ABAOzEEiH6nDcz1qa5X6xAmpVwVdoF+tyT7cG0MW tx72/HVgQu1+IiK0w/0SkbCf+n9v/lb2hMmSwr4R9IdcgIza+r6vOdTPv vlzh6DZZI4ETylFpKdbGXtPNF15Q22eNvAp7d3A6R9EZVFeMRBop/kAz3 GYkmmr2KfuNcA+V/SVCcrpiTDrRjo0d/muCG8lJuhrii2j+RBsubY2RU3 QWqHylODFB5DyPFZZJPNOXbnllBojeO7snzOkHqWSNzD/iuhHy2dfIMdL Q==; X-CSE-ConnectionGUID: PRccnPN6TxiwBsOY05Agfg== X-CSE-MsgGUID: TNS8RBbxQbygyj2VNdFRtQ== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924053" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924053" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:13 -0700 X-CSE-ConnectionGUID: zXjFbw56RMyjQ0RqFKvPIw== X-CSE-MsgGUID: CGIXkzUMSG2M6qIXHcB7wQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254603" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:12 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:11 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:11 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:10 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=q6q+SmU0j3D9yiTrUgDc0pYlMWUOwDO76GJEs61m24Xwbp4EHWXEc9W+PhowCDe+0lC7Kz9PkCDmCoSPf411QNudMKgO/vuh6jzRWcuiUlalrbHMZnnz15D/H78cxqaKySsq5nYwBQtfHKedUynERIG6xHSyFPQkNVKqFD8lX/3iI5n4A4DrSw0h/Vd2GVrkg6RE3X9pbRh8MmWmbEiicVswTExQGl2tKDijt35BbShBuO785p1IBFzT3YwZEBrhHW22vkZdVw9cSbAMmC52QhaxHWSmqJgaPMuYWJE2vOmBaxOJgsi5hXD8DjDETOt7J29GbJGHIsBa218GbE2UeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Q1xBH+xuabjfjpyhPSgBgyOpgvAwquo333DCYBPWgJg=; b=n2a1ed0KlWN/994KFvN6HvFe2CjNbjyafKhnbdiOE30ic+pq8NoU7F+A44EnJ+ZM9/OPbxonJNGRqoqOLAfGc0Y0zYg19/YT0bvFAS+8C8cmTDvfX+ggn06lSECCxtKDVZ69UW3z4JLjHkYEhLpSzpFWxczhRVTt3YsCoiOR2w0C52XoMibeTMXreoqxle4fRvOVUz3d2F7S12pEQg1OB+qY5CAvnIH9XkflnFn3jFk36fwECeYNIbPVDqE9JtTtMZkeXr97CZfXhI3E/hdYmuUP4PkVejCJVbLs1rWSJj/6LVAlwgOzuXIvoMx8rIXpYnUNCZcx9Yq09FM3+iFXDQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:03 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:03 +0000 From: Dan Williams To: , CC: , , , , Xiaoyao Li , Isaku Yamahata , Yilun Xu , Tom Lendacky , John Allen , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v4 01/10] coco/tsm: Introduce a core device for TEE Security Managers Date: Thu, 17 Jul 2025 11:33:49 -0700 Message-ID: <20250717183358.1332417-2-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: acbcffa9-8da6-4dc6-48d7-08ddc560812c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?pxyM8BXsgxUYEibs7CVJSwWcBCGDE1tddOT1yUn/i2fz191eUJQCtajF4nX5?= =?us-ascii?Q?O/HdsJTjayfIJNqwtW9AYxbH67hbRCj0SAvky6PSXxsI/4T+lNnZ1wnRBOd0?= =?us-ascii?Q?/Hr2dubuiAxYJipRHBDqDWvF0XLHq7oqxZQn7RQeeWH7046U3DNAqC3CL44j?= =?us-ascii?Q?mW1oXuV+ebbljKEcP/aHdzvdnJTIdIYakl3jwIRTcltsrXKYAY63/sMudSTO?= =?us-ascii?Q?rdW1oXJkavP+aO/SE6Kr1K8PWBn0JoZLbyuAeI3Rb6TyLEbuGd/0Dmaz7YNF?= =?us-ascii?Q?gcZ0PrCkv/p+gI83MOaU5OfMpAmWpnYKFtrmfPPreuYUUS1hYmYVNikmoJd7?= =?us-ascii?Q?zyi3XElXG7NsI1DQtLXlraaP+4Sv+s5VOd7LrTjcn9rJVX5SSeDYLc/O4jOw?= =?us-ascii?Q?40zbJ6bozPiD+TRPmlt8YSwOm8pLqn/9XFSKq0vk9Y0VbEZiAMfU/a2OZ5P8?= =?us-ascii?Q?yDKRflt06wmKQmCRocACT3DQx20ZwRk2JKTG2Ny+MRnFAQDPnQ4yb1cjjLWs?= =?us-ascii?Q?Q6vtzsWGmpLlVVUAnFwjmtN4mKNiXIDZUIbmq4NrRMqT2DeO7gnyZfMhSfsd?= =?us-ascii?Q?Ca99zsltlFoHPouGYL+2ufPOryumCaiVAGHcXdJcBteFRoKBWZuZrmXeitb2?= =?us-ascii?Q?232aq6H7/PRtjH2+XRzdQAlq/iIO+q1tMrgstabfi/JoJTZF7fEWA79SrX1P?= =?us-ascii?Q?Z5rZgf+70CBR7HFixAh+CPH3nfYE3JaGszkrBBJJE77GEzK55ulp+WhSZtOP?= =?us-ascii?Q?DYA5EAKjazDw0WTZMK4Ak8LrXEtYEwshMJ7pXsGxeJUNrKX1kgalhxf/hpWo?= =?us-ascii?Q?Rija9JXWcaEEt9A1DRSDGhHVELAPy39j59BFuxeq0PteJjijmqxY9Q5ANPuu?= =?us-ascii?Q?xEmDk9pCHQkIqh+HAzsnoGK11mBELE/ABYqxUiodzCKAo/2IRfT8kXDephyH?= =?us-ascii?Q?wtTZDEEN5Ql/+/ZC8BqBSWNiDjQox7Nv4fQSq0Er0hhCDKsqpaUHdHSrW6Y9?= =?us-ascii?Q?qYVWtqpCa+T/OWP5ziZ1dwF7i2VZlZBST/s0ET54Ecs0hKE58kptg08OW0vU?= =?us-ascii?Q?4YbDasV09nCo9fpZOYkBZsL6wtnk+Pe4tnUR776npCqOiTSh0/oH78/DOBB4?= =?us-ascii?Q?P+3Z1KKkYBFbYhTJa14k1FBy/wRC8ETN+CVCtggF0c7GIL/dqG/hCzIOxqsB?= =?us-ascii?Q?5czCi0QpbAkFB8og0HEqWaDONEamZn6k518z/VnAJsNepDaJJiI5PIdLIXmq?= =?us-ascii?Q?+9HDSlHPVVmFv1RvsZWYQD0ASNl3cX2pa5scIU+ttDWnUCWTLRehbYZeXxHN?= =?us-ascii?Q?C5+z8xw5Zf9xXmFfmr4AFBJiEZbwZaajEl7c4NI4zvmts/ASLdl5r89poYU0?= =?us-ascii?Q?BoagdWtfHEzJq/T+mGHeH+wiOeYKgiK3zSSzvUXEyEaf8w+DSZJaZkB3AYuw?= =?us-ascii?Q?Ddkc/4OjnA4=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(7053199007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?TKi/baO0rgTpighF9gojFKY0uV7LASYU9zMGFpF4vtNUuZY2ClEtHlUSRJy2?= =?us-ascii?Q?rOHGCandQ97PSaej2CAkIiyrVe7ystVDAypBzhlIRgNbTovgJ8gzCaNAe/SF?= =?us-ascii?Q?erTTe2DM01OJO1MANMd8gF1o+mWWZeEfxiMCV8SgCnLEuzSPkNMQ2F0nG4cE?= =?us-ascii?Q?oy2lOo8dNn5IRoU5NETRAUcs+EM5c+gAJFCYD36pSdM+7M0gBYVjC73k47Fa?= =?us-ascii?Q?amHT+xL4H+fzrwNUzlp2bv8hJa6BtLKgMYehwfOJj+rUguo7jVm5Ly+PID2J?= =?us-ascii?Q?XSKKKmlWayqkC4wZJcYOVX7JaxS6uwLX4vBGrtJSJ9kcdebwkyhpDgQRm7Gq?= =?us-ascii?Q?7gZHOUTQehPIcvz9ic3//6N96dso9SV9kvdGvtb2hDuU7kbx5cAtKWQv5ErO?= =?us-ascii?Q?5b2xPLppZgkHxyQ0CNAItdv44vuH1pLhwKtofrqhcqVWOeyblVCSIc6CfK6c?= =?us-ascii?Q?2XegDZhiR5q4R+rGURg1IxtFaOI+x6BkAI6bRaRPK5fi1SefhbCr6nXFI+gU?= =?us-ascii?Q?j3AnvW4EII4oKAO4gMbUSOJF0yn188P7JjaKmPvIu3sjebtYMLJiN656MsGO?= =?us-ascii?Q?CAjGPs6a3rD0l9xdnfwgg5SAA5ZqzGm9xCSUmij4yVkDESD/zElkE9EPEkNR?= =?us-ascii?Q?xgaTdeKAqgw+SR0aySBUYr/qkHAJhWG1V24LecZRK9AnE41iWlp9i3NYVeBX?= =?us-ascii?Q?+eYcnuxYvYXbjPDuJzx9HzsR6SpFFCKFVBzIdiF4kGcO2+MGwIFOeIvYkPDO?= =?us-ascii?Q?eCnVwzpPWuOuHrjBBnJxfqZSggUgt0GQ/fd4pgfb1ZiAukNNStUIC+53up+T?= =?us-ascii?Q?VtxXL2z6nUPz0eYZg0dFh5o7JhgFp3pO6M/JrGhFFeStarfKaN8qqqUsz7gt?= =?us-ascii?Q?YRYKt/B/EHrhbrnZmzDox0ih9SZkWyU2tlkM0C7BVmyOQ5c9cByfmcPCitBC?= =?us-ascii?Q?kSVfE58ABQXAMrQZOXu9Z3b9xbZZMykv/HTDZkiEGDjrz5pvGn8zufAeoU9L?= =?us-ascii?Q?XPZSFdUUrmLF2MxeJLbIeg7e+uvA783WKgh+zMB25O5lTH3GHnV0qFIMC1uc?= =?us-ascii?Q?jt0FgSlt5irzibtHeMsC/OpKrW1424jJyo+yb21pcO3jskIw4WhXFhS/kfGV?= =?us-ascii?Q?+L/pmgxlcnjomGm2ZhL1vu663YsTgEmqVq9ujdR36AiYY6t1GS3oNfOcboA7?= =?us-ascii?Q?PHMmiHTjfpQQRNWjEtQ9VFhSoiVzWfAdR2ioXV6eHCzuKWJdEpjSJxxNbSMv?= =?us-ascii?Q?DAI/QR1SmH7gExspxOScF0Y4/RM4hP4h/QtzNi/CAxqxwgpgngYatflgv96v?= =?us-ascii?Q?rSl92uhtBXDOfFrdYIafon69AoUQWSfk086Eo2GqZbq4Ua1rHKLeBuIkKcQY?= =?us-ascii?Q?oR9d941Jfc0isjRmgc/dU6PVLnDrpwoVlCwvIHuildz6JiWWZa3srWBHR8wA?= =?us-ascii?Q?PWVc+WhWljmxU0GJtG1kbHFyVDznpV+IQOIfwIcDzu1snHP0R/mh4W83prs1?= =?us-ascii?Q?+mKaf3/ynbXVS3ukqORiHdakoTDuvpnoETb4cJf8DtR1w+W5QN/BWSr0wlj/?= =?us-ascii?Q?ZMHH+mKA5VbgtB0ue3aQidNUFdkRAibFeCKJbx0ddXLzkzxmEnxXIRKv6f+H?= =?us-ascii?Q?vw=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: acbcffa9-8da6-4dc6-48d7-08ddc560812c X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:03.2526 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KjEmPzn7PBqn+GUH2+EpPYNUdSVX6T1PhpPzJR2oxnwez8GEukTzpDjXJC91dGqNaydii3XyvGIoZ8kTcR02iZB2yXO7760C8fK8Mt/VSfM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" A "TSM" is a platform component that provides an API for securely provisioning resources for a confidential guest (TVM) to consume. The name originates from the PCI specification for platform agent that carries out operations for PCIe TDISP (TEE Device Interface Security Protocol). Instances of this core device are parented by a device representing the platform security function like CONFIG_CRYPTO_DEV_CCP or CONFIG_INTEL_TDX_HOST. This device interface is a frontend to the aspects of a TSM and TEE I/O that are cross-architecture common. This includes mechanisms like enumerating available platform TEE I/O capabilities and provisioning connections between the platform TSM and device DSMs (Device Security Manager (TDISP)). For now this is just the scaffolding for registering a TSM device sysfs interface. Cc: Xiaoyao Li Cc: Isaku Yamahata Cc: Alexey Kardashevskiy Cc: Yilun Xu Cc: Tom Lendacky Cc: John Allen Co-developed-by: Aneesh Kumar K.V (Arm) Signed-off-by: Aneesh Kumar K.V (Arm) Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-class-tsm | 9 ++ MAINTAINERS | 2 +- drivers/virt/coco/Kconfig | 3 + drivers/virt/coco/Makefile | 2 + drivers/virt/coco/tsm-core.c | 113 ++++++++++++++++++++++ include/linux/tsm.h | 5 + 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-class-tsm create mode 100644 drivers/virt/coco/tsm-core.c diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/= testing/sysfs-class-tsm new file mode 100644 index 000000000000..2949468deaf7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-tsm @@ -0,0 +1,9 @@ +What: /sys/class/tsm/tsmN +Contact: linux-coco@lists.linux.dev +Description: + "tsmN" is a device that represents the generic attributes of a + platform TEE Security Manager. It is typically a child of a + platform enumerated TSM device. /sys/class/tsm/tsmN/uevent + signals when the PCI layer is able to support establishment of + link encryption and other device-security features coordinated + through a platform tsm. diff --git a/MAINTAINERS b/MAINTAINERS index b6219e19a749..cfa3fb8772d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25241,7 +25241,7 @@ M: David Lechner S: Maintained F: Documentation/devicetree/bindings/trigger-source/pwm-trigger.yaml =20 -TRUSTED SECURITY MODULE (TSM) INFRASTRUCTURE +TRUSTED EXECUTION ENVIRONMENT SECURITY MANAGER (TSM) M: Dan Williams L: linux-coco@lists.linux.dev S: Maintained diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig index 819a97e8ba99..bb0c6d6ddcc8 100644 --- a/drivers/virt/coco/Kconfig +++ b/drivers/virt/coco/Kconfig @@ -14,3 +14,6 @@ source "drivers/virt/coco/tdx-guest/Kconfig" source "drivers/virt/coco/arm-cca-guest/Kconfig" =20 source "drivers/virt/coco/guest/Kconfig" + +config TSM + bool diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index f918bbb61737..c0c3733be165 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -2,9 +2,11 @@ # # Confidential computing related collateral # + obj-$(CONFIG_EFI_SECRET) +=3D efi_secret/ obj-$(CONFIG_ARM_PKVM_GUEST) +=3D pkvm-guest/ obj-$(CONFIG_SEV_GUEST) +=3D sev-guest/ obj-$(CONFIG_INTEL_TDX_GUEST) +=3D tdx-guest/ obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ +obj-$(CONFIG_TSM) +=3D tsm-core.o obj-$(CONFIG_TSM_GUEST) +=3D guest/ diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c new file mode 100644 index 000000000000..1f53b9049e2d --- /dev/null +++ b/drivers/virt/coco/tsm-core.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2024 Intel Corporation. All rights reserved. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +static struct class *tsm_class; +static DECLARE_RWSEM(tsm_rwsem); +static DEFINE_IDR(tsm_idr); + +struct tsm_dev { + struct device dev; + int id; +}; + +static struct tsm_dev *alloc_tsm_dev(struct device *parent, + const struct attribute_group **groups) +{ + struct tsm_dev *tsm_dev __free(kfree) =3D + kzalloc(sizeof(*tsm_dev), GFP_KERNEL); + struct device *dev; + int id; + + if (!tsm_dev) + return ERR_PTR(-ENOMEM); + + guard(rwsem_write)(&tsm_rwsem); + id =3D idr_alloc(&tsm_idr, tsm_dev, 0, INT_MAX, GFP_KERNEL); + if (id < 0) + return ERR_PTR(id); + + tsm_dev->id =3D id; + dev =3D &tsm_dev->dev; + dev->parent =3D parent; + dev->groups =3D groups; + dev->class =3D tsm_class; + device_initialize(dev); + return no_free_ptr(tsm_dev); +} + +static void put_tsm_dev(struct tsm_dev *tsm_dev) +{ + if (!IS_ERR_OR_NULL(tsm_dev)) + put_device(&tsm_dev->dev); +} + +DEFINE_FREE(put_tsm_dev, struct tsm_dev *, + if (!IS_ERR_OR_NULL(_T)) put_tsm_dev(_T)) + +struct tsm_dev *tsm_register(struct device *parent, + const struct attribute_group **groups) +{ + struct tsm_dev *tsm_dev __free(put_tsm_dev) =3D + alloc_tsm_dev(parent, groups); + struct device *dev; + int rc; + + if (IS_ERR(tsm_dev)) + return tsm_dev; + + dev =3D &tsm_dev->dev; + rc =3D dev_set_name(dev, "tsm%d", tsm_dev->id); + if (rc) + return ERR_PTR(rc); + + rc =3D device_add(dev); + if (rc) + return ERR_PTR(rc); + + return no_free_ptr(tsm_dev); +} +EXPORT_SYMBOL_GPL(tsm_register); + +void tsm_unregister(struct tsm_dev *tsm_dev) +{ + device_unregister(&tsm_dev->dev); +} +EXPORT_SYMBOL_GPL(tsm_unregister); + +static void tsm_release(struct device *dev) +{ + struct tsm_dev *tsm_dev =3D container_of(dev, typeof(*tsm_dev), dev); + + guard(rwsem_write)(&tsm_rwsem); + idr_remove(&tsm_idr, tsm_dev->id); + kfree(tsm_dev); +} + +static int __init tsm_init(void) +{ + tsm_class =3D class_create("tsm"); + if (IS_ERR(tsm_class)) + return PTR_ERR(tsm_class); + + tsm_class->dev_release =3D tsm_release; + return 0; +} +module_init(tsm_init) + +static void __exit tsm_exit(void) +{ + class_destroy(tsm_class); +} +module_exit(tsm_exit) + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("TEE Security Manager Class Device"); diff --git a/include/linux/tsm.h b/include/linux/tsm.h index 431054810dca..a90b40b1b13c 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -5,6 +5,7 @@ #include #include #include +#include =20 #define TSM_REPORT_INBLOB_MAX 64 #define TSM_REPORT_OUTBLOB_MAX SZ_32K @@ -109,4 +110,8 @@ struct tsm_report_ops { =20 int tsm_report_register(const struct tsm_report_ops *ops, void *priv); int tsm_report_unregister(const struct tsm_report_ops *ops); +struct tsm_dev; +struct tsm_dev *tsm_register(struct device *parent, + const struct attribute_group **groups); +void tsm_unregister(struct tsm_dev *tsm_dev); #endif /* __TSM_H */ --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 45D3020ED; Thu, 17 Jul 2025 18:34:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777256; cv=fail; b=kR7PWolLMEFEFBaHV5gcQHsZWCREvkFEFpEIRp/JLMcp/GxuQerGQ+I0iCukNCJYv8D6fdOsDW/MSGkVyofWOL8RDRu6Oh6I4+go8lXn+YbjSWpAfM9Kd2ycctQmfVAm/p5NTq2jPlbyDHB1Kzy9yyjwLWHj+YlAboebQdyBDII= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777256; c=relaxed/simple; bh=z3HqKNswQOXo/dVVRa+09npNML6gvL6sJRDbj9Jf9Bo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=t03Cqa6RTn5mCI86Pc+AsKjUa8rcRCTBk3ooAL7QcdphMuPsZX2NCZA2dRw9QbSeu8Xv7yDubcD+cPSDdlTgxWL4ekon9V0QMEyldYEQ8WWB7z+ydEx6gm/NSNyt6qhxrGZWRJYyjvs9eSR0wqnH+4OwaeJcR2tXOqT5hQ/YFjk= ARC-Authentication-Results: i=2; 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=lPOfPwK9; arc=fail smtp.client-ip=198.175.65.19 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="lPOfPwK9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777255; x=1784313255; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=z3HqKNswQOXo/dVVRa+09npNML6gvL6sJRDbj9Jf9Bo=; b=lPOfPwK9Tgy2IWY2eSz5yGfASvJwGOleLH5VbyTpeknpS104izzCL9wR c0FWzoTLBtbYvvhNWzjiglfWX3yHj9iu0AoKFxAr3Q3fOQVDMYS2j6reK hbMpzHnLZPoWFWyUMkDk4CuW6jYEtaZDHG0SmMp95B4CyGpt0Nw/1VxkL N+1iUUgQ8mvh9IYvRywfKPprt/C7/rNbDQ78PC7T2lyVMYMkY7KjaHar0 FKaYPGV4ajWsK9ylPWpkaFpxU5WamJhMPjaEJQYkZEgWjU+1D6Vo8U3nA /NF0vufii+xPlHaaRg0g+xaflzEsxgR3B7lOEpI24dMBxt2s6mrhat9iR g==; X-CSE-ConnectionGUID: LncdcJMpTkeuC2Iu4E96+g== X-CSE-MsgGUID: uJd0Yux/RzWocV6RuGmYmQ== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924062" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924062" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:13 -0700 X-CSE-ConnectionGUID: pvM29X/TTl2f7HmoLZXGPg== X-CSE-MsgGUID: YpkYFz4nTKSW6s9FfWOOXA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254613" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:13 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:12 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:12 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:11 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=lcpyf0kh6kqhC5pjsaq6bLUfGeIzGI4xSreE6BBIM8VEOqTWUCynXPzppalpx4vQP9CDlgnCaWdKAkqX41Sg4KH8+3fMUZ1NyJgIeSj5NfZGnve4VdDAQHuud+I/tOF+5D7stKmIZlbaAYWAchB917eRXaQ9tvf+YGC4Ji0bBCgOtfOdM1QplBCW9mPoBPQ/aiZ2w2iXn6cggoAFUofNHSeMl/ktimAKTC2TmjSx7d3ALwbegblBs1UCTur1f1Q4Z3jFTysX0Vp+UBF/gFXq+V5FaFxrEtiG4g7sCEbryeCpuWe2tYhrp1DnJvEHh1u5GotUNZM0PjcjdR+9quUTkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=wbWEZQTmr3QiLm/0ySTcCEK/GVJAIf1o58ex6NKvEME=; b=fCNdCn8UQZxJRuX7tv4++XRXrylsL1/xuL/l4EcEVY3QZ8dpeGUhF+LWFGbz/egBxRXsSNm/ochmDQNTE84nAKizHclc8g3tf+qxy7Q33WlyrAGvaMUqNI3V0/i2YTGnMztnvh9nGEXlYouc3rrR3wFXvYs96gf26DltkOyu5Xm5CghEDzwEA1hRhYidP2gr/IBv6bmRkidgKCUGtux+9fsG+r/KloqcS4yiuPvE4B/XbiFAj8/DLT0VO1yLvfkPbFGyG53yuAUASZqaNlO0PgQ1FbLbqOX2KIjYG4lMFLCsnocjyMyD1WcdCY12TQqxr0VXKi2v2GZv1Cuc1gp7Pw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:04 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:04 +0000 From: Dan Williams To: , CC: , , , , Yilun Xu , Jonathan Cameron , Aneesh Kumar K.V Subject: [PATCH v4 02/10] PCI/IDE: Enumerate Selective Stream IDE capabilities Date: Thu, 17 Jul 2025 11:33:50 -0700 Message-ID: <20250717183358.1332417-3-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: 114ef056-c5df-4188-ba13-08ddc56081bf X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?XdyAGlCHRetNOzdIP13i4lyO/zNhjWFcB5ApDFKeBFpoD/4N+T35AoU0/y9u?= =?us-ascii?Q?5WEm0FKZf9OjQipg0RDRWZFCJSbgR7b+5x7X2cUBc30oJIPotx+RWtn8rfry?= =?us-ascii?Q?qosleMtcrieyzGoXCEAezJV3W6B7JQcQ2KZeBDd1nnm80f6Ad7GJsx5ZwQyr?= =?us-ascii?Q?NugfgInPCNaliO/SRwwzAOZlPZKbUVpMR9lX10l60QyZVLPgFcgyhOr4P12G?= =?us-ascii?Q?IeWxm6n/Ux9boX1LKTMPTGCavwCrwC+2sFJfJ9mKBqQu1hh0oja5Owegew7M?= =?us-ascii?Q?JLDhq/1eRO3M3ozrfodwObm6hHC9M8ClwEfTX+Hpbg4+AXWk+dwbzqsTBNyp?= =?us-ascii?Q?R10TZkych7myCccXDZbt8JIN7acymaXHW0v+XaENIjpGtlN0K8iO4CmgIexX?= =?us-ascii?Q?xELUEtFuiQBy0PBOmh49OgJg/SiIt6fLBcGnMJlPU6pv0wovrdnhmRaAsGJF?= =?us-ascii?Q?kJQoBP7ayac7d9AnHSJl5CiQJ2PMgqIqT3rRtlDuMDoXq6TD7Ih4iLws0i7B?= =?us-ascii?Q?G824RbLsY39SpH1QvygetpdObzwoYKy/XSkQ4B5cCbTwwLzJZ8IF5r9SG8Qb?= =?us-ascii?Q?5QbR9sP5lm/yD1OQbo2jpIreFQOHyB3cgG7a+p+0TDBhKRmwOQ5roU/W0/Py?= =?us-ascii?Q?/bDqQDmXyxAUBNwQY+6o7R4RtmshHL6qm7fNb8k1ULEbmq9vIgPd2JJvS8VK?= =?us-ascii?Q?jx25HXbdGNZA7pTEYs2SLSTJRkAemAXmB7dDhhlVcaRLPT3uLj9MudEeP61B?= =?us-ascii?Q?oUBHmIap/Wzcik3i4H6AtCUMA0eTN1Yr/ttu0cL343ysFlaTU2JPOpoToo5z?= =?us-ascii?Q?HNRV2mQTHnMg/5l8BuUgxD8T2NE3/0Gt/tMuqFl8w6Pd/2cV/xvh8C0ipIpM?= =?us-ascii?Q?COJAnrbR0Rk9P9fGfIFGhnq5jVhwJQPEdqR+dQGe5m7608Dh4lfl6UJjwwPs?= =?us-ascii?Q?To8gXvdq7J5+Jn0COhExz8Bc+A89CIU5tj0yA65E9KeRbLhjODq+aDH6P9cc?= =?us-ascii?Q?YV9TvfcqV2lcS66cjey21aNSgcGqFQzcgQGbIpVZECxR3Zy2suxEqFmKDe5Z?= =?us-ascii?Q?9P3ayVEJoxpN77J0FCDCbM5NNnbvostBpFV+bnrYWspGMQmdAB2qhafCo1S+?= =?us-ascii?Q?P8YaHP/uGJgIZeq/WmQjQGlmZJHwm7h6juBafQAVHQwQCy+2e/njs/hFholp?= =?us-ascii?Q?gpSGcrLBo2a3zGNfJZhvlB5TFbKDpUYjKOao3MNzk+Ms0CtgENGw/HPp+X3D?= =?us-ascii?Q?xftOP6Xlrn+mpvpGKpd1fXRx+ObPIT2RgZex9EQinhME2w4nyo602Pnos4WH?= =?us-ascii?Q?RpIK6LGVous1V4FzB79ZRkpHgJoG+hrL0CPGr73MmbZ9HgeWNjg5vQzJ/F9m?= =?us-ascii?Q?WgV12fq0CoqbUSpmrodY+94PLgnk7zpwLMKUh82ecE549MjIXKCZ7iN9Wsku?= =?us-ascii?Q?LhbxB2H7sWU=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Aoga1Tl7DERMwEKUkp20R8q6PPhjx3ffM75Gph+HdIdShipF6s7C35k8OD5v?= =?us-ascii?Q?KDspj+mB1YI23ffpsTiz62uSmoL/ZR2LwGXK0t+1gPvM+C7HfievqKH18eDp?= =?us-ascii?Q?+xok+Qsjtz9kO2JJpF8a3HQ4EXbAQKrclfOi70ChxCJfYoyBB9vq02fCLcDO?= =?us-ascii?Q?7GBXJc96oGFZQcdlDkfXyY1Uk9aBcl+hSSQ9nwK5bm4uALqn8whUblRVZB6l?= =?us-ascii?Q?y4ms8d6hunyw+Tndy3wkvs6qrPZ4kekAFt+ZrDnDM6cQy5h7psdfjDeht3Aj?= =?us-ascii?Q?2F5c8qMq/fsjhLEAPYyiquYf+XJNY+nCszriU1t/VRmjSXu04HHA+IFLEtiM?= =?us-ascii?Q?oNOZAMo38i/lgG7pZVRV+tX3sLbxq0l+YvI4E1ygi7jBiw6yX7ngxc4ieaKT?= =?us-ascii?Q?jmOBJl682ay3b9BmFU8i2CVveqIbXJb9tbeIRiwG0iN3crSi0Y4pF8ev+5uK?= =?us-ascii?Q?rSpM3xMPcRhcU6BcbD+wnzb3VLJOW5JEnU6uVYE3ARXXb77HQKMfM1ve6iXV?= =?us-ascii?Q?2VBGaviN3zFhOsRJInK68j0K89cu8JE9dFP0UqXD5V7aCfE5ieEl643+Ucky?= =?us-ascii?Q?0bQtdfCzozWaxt5+IfeSsEJdR27OhWkrEPwe2jNtsu/wRrwIIIJaw2qic66I?= =?us-ascii?Q?xtCrAFNxGujXhYhG/yEopgq2/7fW29O6dh9ZCOa8eqA3b1zO1Lblmu8TnP6M?= =?us-ascii?Q?scusHKFcn4hSqrCE7Up2huloHXX2/zGKTvhSQalNumeD+lFlo9hv6iXXFoUw?= =?us-ascii?Q?X+fUwV/FIY3+dOhYKQ2SkHnPqYhhE8yHtBPDNdsW+Rl2EGzZWJGP9Q5QOCn5?= =?us-ascii?Q?OFt1rkrS+xuKuYnDKVkXied5XpdAWtKPov5HdrZZxh3XXXoG6idipThDeofM?= =?us-ascii?Q?mGthG1hKsUF82KqBglHIGt8PRKzjnpg8JXByU1uJ6aLrjiG3P7E//Emro4nH?= =?us-ascii?Q?sVTp/+yXI69fwo/p5zQ/v8ekilfYUe8qYVtQLW79HNl+8eCjWL8wrXnELWUZ?= =?us-ascii?Q?sW2G6NoHGKJNP0Vci24KS343valHb/vke34bNdDoa2GFwanE7Z4TZTyxE8r1?= =?us-ascii?Q?srKligmFVLZhhye9ZXxKfK3WpPVeiqiLC7HEi5rmlw77uru5TuH4qiAM5YH2?= =?us-ascii?Q?2pPcSIG3tSqHYqGuqEVoi37GIl44t3tlx7ZX4krkVEko26V8ueT3qrIp967C?= =?us-ascii?Q?6Onc8MYmq/p8WGZrH85iwPhz/QDi5gOgfy2bw/18ox5qaoGLxMP2xT1PitkW?= =?us-ascii?Q?IXlOheyj6nY5f3I1pB3plWZi2ZikS3If1eFJuEWcULdAKYZ0RzN5fdfmOsvp?= =?us-ascii?Q?1eZTplBEuK04qBoJ3fi1O3zKnT0cZl98of6GDyy72kg1G40+erbWlHebOHSR?= =?us-ascii?Q?SkYa9+Ie5cw+bLC8W4dah+xdDPuDJkTvd2OYUjpHS2uskdAEIezJH8ltaEAM?= =?us-ascii?Q?RGONqJW3dMUUoD/fLQdFDcIBkAT22wy+tUPR3UEYQDdQkRuBH6FDLn/jXt9n?= =?us-ascii?Q?wPLN1uyDW8YCjNN7WMGHb/YpaLI5roJSjBOGDXVGIHt1QmcvrzJUni/WV20s?= =?us-ascii?Q?z11JQE3LtNUbRR5sKnt43xtG/0xdyplkrawZUo/WAdCC54cXga34Ri0vdzDt?= =?us-ascii?Q?/w=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: 114ef056-c5df-4188-ba13-08ddc56081bf X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:04.2271 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: UzxrEsKutAMORzQmTjHwu9VPVyrEljG65c+pw5TCgwmSViJSAe/p6GQ1a8iMM+viqWkR0mdlUOBqbxH7zuL0GMftqYP4JK+zosx/7mnTwms= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" Link encryption is a new PCIe feature enumerated by "PCIe 6.2 section 7.9.26 IDE Extended Capability". It is both a standalone port + endpoint capability, and a building block for the security protocol defined by "PCIe 6.2 section 11 TEE Device Interface Security Protocol (TDISP)". That protocol coordinates device security setup between a platform TSM (TEE Security Manager) and a device DSM (Device Security Manager). While the platform TSM can allocate resources like Stream ID and manage keys, it still requires system software to manage the IDE capability register block. Add register definitions and basic enumeration in preparation for Selective IDE Stream establishment. A follow on change selects the new CONFIG_PCI_IDE symbol. Note that while the IDE specification defines both a point-to-point "Link Stream" and a Root Port to endpoint "Selective Stream", only "Selective Stream" is considered for Linux as that is the predominant mode expected by Trusted Execution Environment Security Managers (TSMs), and it is the security model that limits the number of PCI components within the TCB in a PCIe topology with switches. Cc: Yilun Xu Cc: Jonathan Cameron Cc: Aneesh Kumar K.V Co-developed-by: Alexey Kardashevskiy Signed-off-by: Alexey Kardashevskiy Co-developed-by: Yilun Xu Signed-off-by: Yilun Xu Signed-off-by: Dan Williams Acked-by: Bjorn Helgaas --- drivers/pci/Kconfig | 14 ++++++ drivers/pci/Makefile | 1 + drivers/pci/ide.c | 93 +++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 6 +++ drivers/pci/probe.c | 1 + include/linux/pci.h | 7 +++ include/uapi/linux/pci_regs.h | 81 ++++++++++++++++++++++++++++++ 7 files changed, 203 insertions(+) create mode 100644 drivers/pci/ide.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 9c0e4aaf4e8c..4bd75d8b9b86 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -122,6 +122,20 @@ config XEN_PCIDEV_FRONTEND config PCI_ATS bool =20 +config PCI_IDE + bool + +config PCI_IDE_STREAM_MAX + int "Maximum number of Selective IDE Streams supported per host bridge" i= f EXPERT + depends on PCI_IDE + range 1 256 + default 64 + help + Set a kernel max for the number of IDE streams the PCI core supports + per device. While the PCI specification max is 256, the hardware + platform capability for the foreseeable future is 4 to 8 streams. Bump + this value up if you have an expert testing need. + config PCI_DOE bool "Enable PCI Data Object Exchange (DOE) support" help diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 67647f1880fb..6612256fd37d 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_PCI_P2PDMA) +=3D p2pdma.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) +=3D xen-pcifront.o obj-$(CONFIG_VGA_ARB) +=3D vgaarb.o obj-$(CONFIG_PCI_DOE) +=3D doe.o +obj-$(CONFIG_PCI_IDE) +=3D ide.o obj-$(CONFIG_PCI_DYNAMIC_OF_NODES) +=3D of_property.o obj-$(CONFIG_PCI_NPEM) +=3D npem.o obj-$(CONFIG_PCIE_TPH) +=3D tph.o diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c new file mode 100644 index 000000000000..e15937cdb2a4 --- /dev/null +++ b/drivers/pci/ide.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Intel Corporation. All rights reserved. */ + +/* PCIe 6.2 section 6.33 Integrity & Data Encryption (IDE) */ + +#define dev_fmt(fmt) "PCI/IDE: " fmt +#include +#include +#include "pci.h" + +static int __sel_ide_offset(u16 ide_cap, u8 nr_link_ide, u8 stream_index, + u8 nr_ide_mem) +{ + u32 offset; + + offset =3D ide_cap + PCI_IDE_LINK_STREAM_0 + + nr_link_ide * PCI_IDE_LINK_BLOCK_SIZE; + + /* + * Assume a constant number of address association resources per + * stream index + */ + offset +=3D stream_index * PCI_IDE_SEL_BLOCK_SIZE(nr_ide_mem); + return offset; +} + +void pci_ide_init(struct pci_dev *pdev) +{ + u8 nr_link_ide, nr_ide_mem, nr_streams; + u16 ide_cap; + u32 val; + + if (!pci_is_pcie(pdev)) + return; + + ide_cap =3D pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_IDE); + if (!ide_cap) + return; + + pci_read_config_dword(pdev, ide_cap + PCI_IDE_CAP, &val); + if ((val & PCI_IDE_CAP_SELECTIVE) =3D=3D 0) + return; + + /* + * Require endpoint IDE capability to be paired with IDE Root + * Port IDE capability. + */ + if (pci_pcie_type(pdev) =3D=3D PCI_EXP_TYPE_ENDPOINT) { + struct pci_dev *rp =3D pcie_find_root_port(pdev); + + if (!rp->ide_cap) + return; + } + + if (val & PCI_IDE_CAP_SEL_CFG) + pdev->ide_cfg =3D 1; + + if (val & PCI_IDE_CAP_TEE_LIMITED) + pdev->ide_tee_limit =3D 1; + + if (val & PCI_IDE_CAP_LINK) + nr_link_ide =3D 1 + FIELD_GET(PCI_IDE_CAP_LINK_TC_NUM_MASK, val); + else + nr_link_ide =3D 0; + + nr_ide_mem =3D 0; + nr_streams =3D min(1 + FIELD_GET(PCI_IDE_CAP_SEL_NUM_MASK, val), + CONFIG_PCI_IDE_STREAM_MAX); + for (u8 i =3D 0; i < nr_streams; i++) { + int pos =3D __sel_ide_offset(ide_cap, nr_link_ide, i, nr_ide_mem); + int nr_assoc; + u32 val; + + pci_read_config_dword(pdev, pos, &val); + + /* + * Let's not entertain streams that do not have a + * constant number of address association blocks + */ + nr_assoc =3D FIELD_GET(PCI_IDE_SEL_CAP_ASSOC_NUM_MASK, val); + if (i && (nr_assoc !=3D nr_ide_mem)) { + pci_info(pdev, "Unsupported Selective Stream %d capability, SKIP the re= st\n", i); + nr_streams =3D i; + break; + } + + nr_ide_mem =3D nr_assoc; + } + + pdev->ide_cap =3D ide_cap; + pdev->nr_link_ide =3D nr_link_ide; + pdev->nr_ide_mem =3D nr_ide_mem; +} diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 12215ee72afb..1c223c79634f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -515,6 +515,12 @@ static inline void pci_doe_sysfs_init(struct pci_dev *= pdev) { } static inline void pci_doe_sysfs_teardown(struct pci_dev *pdev) { } #endif =20 +#ifdef CONFIG_PCI_IDE +void pci_ide_init(struct pci_dev *dev); +#else +static inline void pci_ide_init(struct pci_dev *dev) { } +#endif + /** * pci_dev_set_io_state - Set the new error state if possible. * diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e94978c3be3d..e19e7a926423 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2625,6 +2625,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_doe_init(dev); /* Data Object Exchange */ pci_tph_init(dev); /* TLP Processing Hints */ pci_rebar_init(dev); /* Resizable BAR */ + pci_ide_init(dev); /* Link Integrity and Data Encryption */ =20 pcie_report_downtraining(dev); pci_init_reset_methods(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index f6a713da5c49..3fac811376b5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -532,6 +532,13 @@ struct pci_dev { #endif #ifdef CONFIG_PCI_NPEM struct npem *npem; /* Native PCIe Enclosure Management */ +#endif +#ifdef CONFIG_PCI_IDE + u16 ide_cap; /* Link Integrity & Data Encryption */ + u8 nr_ide_mem; /* Address association resources for streams */ + u8 nr_link_ide; /* Link Stream count (Selective Stream offset) */ + unsigned int ide_cfg:1; /* Config cycles over IDE */ + unsigned int ide_tee_limit:1; /* Disallow T=3D0 traffic over IDE */ #endif u16 acs_cap; /* ACS Capability offset */ u8 supported_speeds; /* Supported Link Speeds Vector */ diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index a3a3e942dedf..ab4ebf0f8a46 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -750,6 +750,7 @@ #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ +#define PCI_EXT_CAP_ID_IDE 0x30 /* Integrity and Data Encryption */ #define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT =20 @@ -1230,4 +1231,84 @@ #define PCI_DVSEC_CXL_PORT_CTL 0x0c #define PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR 0x00000001 =20 +/* Integrity and Data Encryption Extended Capability */ +#define PCI_IDE_CAP 0x4 +#define PCI_IDE_CAP_LINK 0x1 /* Link IDE Stream Supported */ +#define PCI_IDE_CAP_SELECTIVE 0x2 /* Selective IDE Streams Supported */ +#define PCI_IDE_CAP_FLOWTHROUGH 0x4 /* Flow-Through IDE Stream Supported= */ +#define PCI_IDE_CAP_PARTIAL_HEADER_ENC 0x8 /* Partial Header Encryption = Supported */ +#define PCI_IDE_CAP_AGGREGATION 0x10 /* Aggregation Supported */ +#define PCI_IDE_CAP_PCRC 0x20 /* PCRC Supported */ +#define PCI_IDE_CAP_IDE_KM 0x40 /* IDE_KM Protocol Supported */ +#define PCI_IDE_CAP_SEL_CFG 0x80 /* Selective IDE for Config Request Sup= port */ +#define PCI_IDE_CAP_ALG_MASK __GENMASK(12, 8) /* Supported Algorithms */ +#define PCI_IDE_CAP_ALG_AES_GCM_256 0 /* AES-GCM 256 key size, 96b MAC= */ +#define PCI_IDE_CAP_LINK_TC_NUM_MASK __GENMASK(15, 13) /* Link IDE TCs */ +#define PCI_IDE_CAP_SEL_NUM_MASK __GENMASK(23, 16)/* Supported Selective = IDE Streams */ +#define PCI_IDE_CAP_TEE_LIMITED 0x1000000 /* TEE-Limited Stream Supported= */ +#define PCI_IDE_CTL 0x8 +#define PCI_IDE_CTL_FLOWTHROUGH_IDE 0x4 /* Flow-Through IDE Stream Enabl= ed */ + +#define PCI_IDE_LINK_STREAM_0 0xc /* First Link Stream Register Block */ +#define PCI_IDE_LINK_BLOCK_SIZE 8 +/* Link IDE Stream block, up to PCI_IDE_CAP_LINK_TC_NUM */ +#define PCI_IDE_LINK_CTL_0 0x0 /* First Link Control Reg= ister Offset in block */ +#define PCI_IDE_LINK_CTL_EN 0x1 /* Link IDE Stream Enab= le */ +#define PCI_IDE_LINK_CTL_TX_AGGR_NPR_MASK __GENMASK(3, 2) /* Tx Aggrega= tion Mode NPR */ +#define PCI_IDE_LINK_CTL_TX_AGGR_PR_MASK __GENMASK(5, 4) /* Tx Aggrega= tion Mode PR */ +#define PCI_IDE_LINK_CTL_TX_AGGR_CPL_MASK __GENMASK(7, 6) /* Tx Aggrega= tion Mode CPL */ +#define PCI_IDE_LINK_CTL_PCRC_EN 0x100 /* PCRC Enable */ +#define PCI_IDE_LINK_CTL_PART_ENC_MASK __GENMASK(13, 10) /* Partial He= ader Encryption Mode */ +#define PCI_IDE_LINK_CTL_ALG_MASK __GENMASK(18, 14) /* Selection from = PCI_IDE_CAP_ALG */ +#define PCI_IDE_LINK_CTL_TC_MASK __GENMASK(21, 19) /* Traffic Class */ +#define PCI_IDE_LINK_CTL_ID_MASK __GENMASK(31, 24) /* Stream ID */ +#define PCI_IDE_LINK_STS_0 0x4 /* First Link Status Regi= ster Offset in block */ +#define PCI_IDE_LINK_STS_STATE __GENMASK(3, 0) /* Link IDE Stream S= tate */ +#define PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received I= ntegrity Check Fail Msg */ + +/* Selective IDE Stream block, up to PCI_IDE_CAP_SELECTIVE_STREAMS_NUM */ +/* Selective IDE Stream Capability Register */ +#define PCI_IDE_SEL_CAP 0 +#define PCI_IDE_SEL_CAP_ASSOC_NUM_MASK __GENMASK(3, 0) +/* Selective IDE Stream Control Register */ +#define PCI_IDE_SEL_CTL 4 +#define PCI_IDE_SEL_CTL_EN 0x1 /* Selective IDE Stream Enable */ +#define PCI_IDE_SEL_CTL_TX_AGGR_NPR_MASK __GENMASK(3, 2) /* Tx Aggregati= on Mode NPR */ +#define PCI_IDE_SEL_CTL_TX_AGGR_PR_MASK __GENMASK(5, 4) /* Tx Aggregati= on Mode PR */ +#define PCI_IDE_SEL_CTL_TX_AGGR_CPL_MASK __GENMASK(7, 6) /* Tx Aggregati= on Mode CPL */ +#define PCI_IDE_SEL_CTL_PCRC_EN 0x100 /* PCRC Enable */ +#define PCI_IDE_SEL_CTL_CFG_EN 0x200 /* Selective IDE for Configuration= Requests */ +#define PCI_IDE_SEL_CTL_PART_ENC_MASK __GENMASK(13, 10) /* Partial Head= er Encryption Mode */ +#define PCI_IDE_SEL_CTL_ALG_MASK __GENMASK(18, 14) /* Selection from PC= I_IDE_CAP_ALG */ +#define PCI_IDE_SEL_CTL_TC_MASK __GENMASK(21, 19) /* Traffic Class */ +#define PCI_IDE_SEL_CTL_DEFAULT 0x400000 /* Default Stream */ +#define PCI_IDE_SEL_CTL_TEE_LIMITED 0x800000 /* TEE-Limited Stream */ +#define PCI_IDE_SEL_CTL_ID_MASK __GENMASK(31, 24) /* Stream ID */ +#define PCI_IDE_SEL_CTL_ID_MAX 255 +/* Selective IDE Stream Status Register */ +#define PCI_IDE_SEL_STS 8 +#define PCI_IDE_SEL_STS_STATE_MASK __GENMASK(3, 0) /* Selective IDE Str= eam State */ +#define PCI_IDE_SEL_STS_STATE_INSECURE 0 +#define PCI_IDE_SEL_STS_STATE_SECURE 2 +#define PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received Int= egrity Check Fail Msg */ +/* IDE RID Association Register 1 */ +#define PCI_IDE_SEL_RID_1 0xc +#define PCI_IDE_SEL_RID_1_LIMIT_MASK __GENMASK(23, 8) +/* IDE RID Association Register 2 */ +#define PCI_IDE_SEL_RID_2 0x10 +#define PCI_IDE_SEL_RID_2_VALID 0x1 +#define PCI_IDE_SEL_RID_2_BASE_MASK __GENMASK(23, 8) +#define PCI_IDE_SEL_RID_2_SEG_MASK __GENMASK(31, 24) +/* Selective IDE Address Association Register Block, up to PCI_IDE_SEL_CAP= _ASSOC_NUM */ +#define PCI_IDE_SEL_ADDR_BLOCK_SIZE 12 +#define PCI_IDE_SEL_ADDR_1(x) (20 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZ= E) +#define PCI_IDE_SEL_ADDR_1_VALID 0x1 +#define PCI_IDE_SEL_ADDR_1_BASE_LOW_MASK __GENMASK(19, 8) +#define PCI_IDE_SEL_ADDR_1_LIMIT_LOW_MASK __GENMASK(31, 20) +/* IDE Address Association Register 2 is "Memory Limit Upper" */ +#define PCI_IDE_SEL_ADDR_2(x) (24 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZ= E) +/* IDE Address Association Register 3 is "Memory Base Upper" */ +#define PCI_IDE_SEL_ADDR_3(x) (28 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZ= E) +#define PCI_IDE_SEL_BLOCK_SIZE(nr_assoc) (20 + PCI_IDE_SEL_ADDR_BLOCK_SIZ= E * (nr_assoc)) + #endif /* LINUX_PCI_REGS_H */ --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 5662820C469; Thu, 17 Jul 2025 18:34:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777258; cv=fail; b=XPLmpqz3Yn2+rzVudcO67Ka8Vt+XDBWjGfCUx56ljcCo4Ybjffk6om+QoiK0oFXqzmvpHnJWjzF7X0z/1+StkzebL+tMBrzclRt6GNaX8FzXVwVd54VvlETq9ald8mj/1ZYra/rEq5eAIGcsqSFIMVoaX6q4RxBviJ6skA56yfU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777258; c=relaxed/simple; bh=EX8B3K/PqoUCdJ/Cd++Ps82HmEhkd6aTwWbdfdzymc4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=sNsqx9O/oSHbP14rlnbiUEkUlgy/XEui9hD8Ypln70pLmTzqBetSnkPERkybQd0D2V2fCfy6TLxwTvuXfa9jrlMy9rxozzpHc0mFZhIrivfyrb0wbvngzAvdUJOxV6McL7GBFtnVurZo72esWXiqhNAXMGURCZGNyPn4U7UZWXg= ARC-Authentication-Results: i=2; 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=dLFiic1m; arc=fail smtp.client-ip=198.175.65.19 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="dLFiic1m" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777257; x=1784313257; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=EX8B3K/PqoUCdJ/Cd++Ps82HmEhkd6aTwWbdfdzymc4=; b=dLFiic1m3aE1MmgkXgaN8XA5Jnkl887C/gYFWIpOzr9Hi3uBB+YZ2gV0 7pGy3xW5YP/Budh4sWTOK8iChABuQjzs8No96RLjEyIybqz6LqnzA0t0s fkR4/PlL/7sFdH31hLIUGbUD2CGO+BnPqelol64OSMksgw+EQuna/Gv1W hXPSNFqbZrNzqGuWvLZd4b/Z+8L4pFEnCeFb4G+d5jFm9Ura/tNZ7Ii07 7f/N80/tRYg6npD6tAmXuQUF597++krVZZMXzARBLCCc3WKED4Jr8yONg +Eun9Hc9aK09lN/9yp7q0s9S2Wa65+ZpL7cbqVi9VdQxOIETrsrgWtvX6 g==; X-CSE-ConnectionGUID: ChvFWy7YThmMS3jZg3uIUg== X-CSE-MsgGUID: xyx+4Dd+TFKrvgU/oZj16A== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924065" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924065" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:14 -0700 X-CSE-ConnectionGUID: pOaV40LmTLqkTsAN4IwStg== X-CSE-MsgGUID: cy68rZlBQfGqvX8uApOUJg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254620" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:13 -0700 Received: from ORSMSX902.amr.corp.intel.com (10.22.229.24) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:12 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:12 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:12 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PkctWpl6Bka6zvGSogMwTiOAC1p9DRDB656SsDJUNe+Q+AAkmEE+J5CJWfUYIISeUKT8Hke8y3Ykfc08IDhool30F0iBm76t4ZZ2tZsRFTR8w8T7YeQwwVA+NdFLwLwJUChGfigBrOpszDD6sBZ7ghM5A1hBVDdVMEdioa8Y6MOaCc9RXe0HEzzfow7JUgZ2tUGzv0fFZZG/ZAY0xWgAoJOnc13tNlAT3xS+ewIBkeGvcyNeYX6Bp17/sELdLzQS8moxH4/tS9fCHwu+THfSx4EkGX2KvwlGD0y537Opo87r1Pbuw9tCj++qfJ+P4D+ztq9ZighprKs4kG9ER3WlvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=1SZaAEDV2QFqnGESpJ/KiraMoi45NMw8+ioxS5MN0K8=; b=hPslR3neBoxvr/u3gxI7Gn/2F6RZKPquBnkJX8bR95d6qCdl9Hr+UNNe32HZfEjYI5VlbzC6HjQSlyiXgHhZUa7HacoO69eP5y+RSM7Sa6XJOkm+2SL3puObp337DORxuY1HlCYJutXgmVR7vIT82StciSrk2ZCJ5SQzrpeV718pwsP37uVoOPEHIlvdPUK63pWcrhxCvrBWRbCoUa4oT4RFghMIKeH4LwVH6s/YpJ71eeqj2w1Q4RctDt4lIoWux2IgyjdzCkEIpRBx4BieucJWiqevFA5KpZLD2UHOE3OyrCHaiY7XELf1z+rXZ1M0+ptPA32dDcbW6PrYUw3UZQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:05 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:05 +0000 From: Dan Williams To: , CC: , , , Subject: [PATCH v4 03/10] PCI: Introduce pci_walk_bus_reverse(), for_each_pci_dev_reverse() Date: Thu, 17 Jul 2025 11:33:51 -0700 Message-ID: <20250717183358.1332417-4-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: 3094ec94-c3e4-4587-7e37-08ddc5608237 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?bWquOWIth5T3j8BBHUthmaWIbgCrwF8hr4tKifGrrw0DYtkioPd3P7TQU5h/?= =?us-ascii?Q?x3QW8Bz8E/5rnLZWEH+0VH2S2yaVzrqh1MWVZLv8+kdDa42GMNw3MqqW1AW6?= =?us-ascii?Q?JaLhguGdVLtynQyOh3MOdCijPI6s4sNvvVQ8jjlWkX1VFgYmSQmMs6IoD9dQ?= =?us-ascii?Q?itMWzreIeF8MaR3R8Q8b+2FgP/1Yy7fUmTm4N6yFkPbiqSXCj1BtYt7OiBbQ?= =?us-ascii?Q?Q9reJAeQFa7x51WQ8ZeiGWWePuXkJLo2tjNN3IY1JVsP7Ph8KCwvWeQRMt7W?= =?us-ascii?Q?4rdiyM/EgeoAWB3bJ9Btcq4jZcxcTpRsxgK6vgOlhwK3PRDH7MMq+H2MHrWk?= =?us-ascii?Q?FTSH9PnleTEQcHKSQrJH5rIiBVX/dRTHEQhT+SAqcUOzQj4tUj0eE8XLTQFs?= =?us-ascii?Q?nWhUQCrKvT5hG4T0RRmQSiSq5Uc3MOm0H/sU1jkj9fCtgp8pljJpiLlDORCw?= =?us-ascii?Q?/94iwFrK4bGM6/ZoYdbml3/mayM8e7IdGEE0Vx3Ng3KPYHTIqp4w/r//rd7O?= =?us-ascii?Q?VsJMYlGXdACRw7yGppkWUhreS96k5corYaCUR3wmcJVQecclGy0wGHl+HDyQ?= =?us-ascii?Q?ozbaWRG1KcRFrJPk8rqN2nwBAdbBhR28zwWe0pJF2zrbG82C+3Tth32JnJ+q?= =?us-ascii?Q?mDsGGrVShyfK2DOBMgEgBxHsHeHfEqD1YvQcp4sl4CNqUE8cEms82kgnK9Vj?= =?us-ascii?Q?SuX1ru3KHBhU6I/RDjKfTx1HgKYDIdrkRe9HAMqy/nWgF0Hj3P7cDKEfqT/s?= =?us-ascii?Q?ISDyihEuapAszdLdmAEJqAV6IKwxvQ8atbVTBPcwi+REyyXQ5YGqExXViP48?= =?us-ascii?Q?xuGCy8DNbCm6qEYeP/+PPWLkAnWihcWtRUq2ICkpbYi1yRkeUDfbUosrGifk?= =?us-ascii?Q?B+E4V3fu6tYl6TU66746BsBVNqPsOqGPCrWvyedoSppxhJGwdmLF0QK+qsxv?= =?us-ascii?Q?tzF7i4YLzrznegvmyPtQ3tK1nSqmHnPrVqz4bjcGad7tIuH2FQI2HN9XnKIN?= =?us-ascii?Q?58NhDLb2NRZHypbHnRmt1nEsoXRQM6csgAm4YulvADeNrV/BDdrP4q39UGsU?= =?us-ascii?Q?jKtmZEWF6PgO29/XHJCKd8+nRmEB66SooDfSMujdXb0WlmHtG5TQMAz1K6rq?= =?us-ascii?Q?BDJSjoPZnq5xc7uYQ70Cm1H4VDLHxlkEFx3w4ClTZP+HIdEGtOpZn8edZPN0?= =?us-ascii?Q?wnhkAHh4W3ANjgOY+2I+wHTbMfHngDRxQXtf0rArK8JB+xL/f7M1loJ3b/mZ?= =?us-ascii?Q?a7zK1GDpQiKuzAvySYmNssFr4mFwMlsQEJq/sj4K+jC/yuxVlsFOEtH41pEI?= =?us-ascii?Q?32N6otAWQaRxyWABEtepxma0cm1/Yb8dj/Wyr3fNm4fcmnMtrD/Yr2KmCGbT?= =?us-ascii?Q?qBrEA+TZtpLPWMPSEVNSMY+QXDVNr4FZrbfiEB5kgfWRUzclsfcxWQsBx7ir?= =?us-ascii?Q?ctpJl89bHQA=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Ef/KtdXrpSHP8ut5ZAet9P9QoqVOjwnk+Edx3xbLxWTPaX8noc6Q1yhAgw9Y?= =?us-ascii?Q?0lZQQuoOaR376tXvHnbzH85JdMHkTHOUjYt3TUa0/EunzDy1xz47FZ3EelMY?= =?us-ascii?Q?wikgZ349Oo+CixUwMCVJ6Hy7y1iV3bwnRypzkiOqRocMvqVTexUgs0Gd4qmZ?= =?us-ascii?Q?rQAXrLshxGJ6VnH+CmZfYLHuzm0I3PWBEOSn2PXnD6jjOYdbeBqpnfLkQGSu?= =?us-ascii?Q?Jbfqn0ogjRkMkd7zRRG/N1innlCAjUytXGIdiyAHO7445bGxth5GiAkjGNFU?= =?us-ascii?Q?6ES7+25OSLxs9oAD+DOUiJ/r0jGA9nuURkyoh317Yxya9mT8GBijcVflk3kh?= =?us-ascii?Q?GueQ26aj30XBFXtHRJZ8FiJUIO8dmW8X7JsJztBbvBspH8qBdsHr8FvtS1HX?= =?us-ascii?Q?2YJO4wMU0m6NW9Pdj2oMwdeDz66gYjuPdTKpnjoN/SInLF1eCtGWEVuwag5N?= =?us-ascii?Q?gqDNtrIwVhwAkcDjbv06CLpX8OGTnm+ylFqZxsuyod0QGB/nQ4ERGDOk2pk1?= =?us-ascii?Q?cxcT8HSJ9VzOH1odpWPjKYhjnX+E5UjNAw3xo6bP+ZzjpiHRhmh81hjWuaxS?= =?us-ascii?Q?EcufSVOw95fehDpwSMrqS98i7RMXod9UGaMWGNuV1lumifapNzemWcpk2Nv2?= =?us-ascii?Q?i0zOwPWXROG93Ma1CX00O1i3Hf6CCS8b9sb43vTSba3qqrqghXyNgM/dqlAu?= =?us-ascii?Q?FQr0cUoqi8XdveLhEN5f9cGOjJVPicY0FXbJCi8iEDkxMnWn9lmXjhVgbY+0?= =?us-ascii?Q?XZ2ssbB5lpYW7w/aVSK3qTmN+TqC2LP6kUvbaY2StHNRBc9ha5ORWQi4krcO?= =?us-ascii?Q?/UF4sJYr72lghGgQYL0E8yAa0dnW35/aSG9Uxs4PT75tyBBLYemhwEymugco?= =?us-ascii?Q?G/w3bHM15gFFzqmypULYdfjCC6svdnxSUNHch4BWE6q1tHWCERtPUthIa1vp?= =?us-ascii?Q?9K/32JBE54R6KZH5GWxMdXTWa7JOWa6i0/M46GbFLtd5xHcRXZAHCpOfU6fA?= =?us-ascii?Q?0WsEfsMzhWPfjLrPte1ywnK1oyHz11YATDHIaP5ZsRp5kI48/u93T86NCZx/?= =?us-ascii?Q?ggSUqX69VpHOuf7zJSbLDKcKL/DQDhFGoV46hTsGqR3wVv8jfse/NCvSKQyo?= =?us-ascii?Q?IM5OFN4YLZ8XsorwoKOgz2uNUZ/8oQVJZGhjrKggbDet5Qh4pao5R9rHA/8Z?= =?us-ascii?Q?IwQTMclkKmydGyXG3vgtUpYwVUzUm+VojfUlLzkqcyqNRNIWMJK0zehsONV7?= =?us-ascii?Q?Z7uSTDXQ7iKqPJ+UcEhU42htmC5+MokmOwWFV/+kklFhaS8M8ukBu0XlGM6s?= =?us-ascii?Q?f2JIyLSpr/m9SnO4d//W5Q+/mOFqqJOsx74oaaue/Jlqd6/bxvR0rYHYdvBr?= =?us-ascii?Q?Yg7VwGxVh4ucW9uqfiEL+wVPMyuwg1WDOFb21s0RLarFjOsPmAEHmNKRtxxP?= =?us-ascii?Q?9IzHI8Zy7Kduz0P0ohtbL76a58BUdMGRlpJPvif86+aXznBN9pJ+f+I2MU4O?= =?us-ascii?Q?I0fFx6LvXufPK+e3RUp8Wcq9jV2XclfkKTGfm8DYvt83/zBzd1caRbet9oda?= =?us-ascii?Q?ucBRGuA2bfEH35Zi65V/s3+ozmICfc63sudx5vsA3g1NCqwejY9aSfZsvVjf?= =?us-ascii?Q?4w=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: 3094ec94-c3e4-4587-7e37-08ddc5608237 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:05.0306 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0S7ShVZBTRRwU0X64dvPkiB2lVXUZ2cNU0Ct1QLYBFPjsM3XNBeJ6SSbuWmR8yfRc8N41zUV5nxzSIJd8GrDt733nCeiv8WmCooowqBwMQ0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" PCI/TSM, the PCI core functionality for the PCIe TEE Device Interface Security Protocol (TDISP), has a need to walk all subordinate functions of a Device Security Manager (DSM) to setup a device security context. A DSM is physical function 0 of multi-function or SRIOV device endpoint, or it is an upstream switch port. In error scenarios or when a TEE Security Manager (TSM) device is removed it needs to unwind all established DSM contexts. Introduce reverse versions of PCI device iteration helpers to mirror the setup path and ensure that dependent children are handled before parents. Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/base/bus.c | 38 +++++++++++++++++++++++ drivers/pci/bus.c | 37 ++++++++++++++++++++++ drivers/pci/search.c | 63 +++++++++++++++++++++++++++++++++----- include/linux/device/bus.h | 3 ++ include/linux/pci.h | 11 +++++++ 5 files changed, 144 insertions(+), 8 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 5e75e1bce551..d19dae8f9d1b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -334,6 +334,19 @@ static struct device *next_device(struct klist_iter *i) return dev; } =20 +static struct device *prev_device(struct klist_iter *i) +{ + struct klist_node *n =3D klist_prev(i); + struct device *dev =3D NULL; + struct device_private *dev_prv; + + if (n) { + dev_prv =3D to_device_private_bus(n); + dev =3D dev_prv->device; + } + return dev; +} + /** * bus_for_each_dev - device iterator. * @bus: bus type. @@ -414,6 +427,31 @@ struct device *bus_find_device(const struct bus_type *= bus, } EXPORT_SYMBOL_GPL(bus_find_device); =20 +struct device *bus_find_device_reverse(const struct bus_type *bus, + struct device *start, const void *data, + device_match_t match) +{ + struct subsys_private *sp =3D bus_to_subsys(bus); + struct klist_iter i; + struct device *dev; + + if (!sp) + return NULL; + + klist_iter_init_node(&sp->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)); + while ((dev =3D prev_device(&i))) { + if (match(dev, data)) { + get_device(dev); + break; + } + } + klist_iter_exit(&i); + subsys_put(sp); + return dev; +} +EXPORT_SYMBOL_GPL(bus_find_device_reverse); + static struct device_driver *next_driver(struct klist_iter *i) { struct klist_node *n =3D klist_next(i); diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 69048869ef1c..d894c87ce1fd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -428,6 +428,27 @@ static int __pci_walk_bus(struct pci_bus *top, int (*c= b)(struct pci_dev *, void return ret; } =20 +static int __pci_walk_bus_reverse(struct pci_bus *top, + int (*cb)(struct pci_dev *, void *), + void *userdata) +{ + struct pci_dev *dev; + int ret =3D 0; + + list_for_each_entry_reverse(dev, &top->devices, bus_list) { + if (dev->subordinate) { + ret =3D __pci_walk_bus_reverse(dev->subordinate, cb, + userdata); + if (ret) + break; + } + ret =3D cb(dev, userdata); + if (ret) + break; + } + return ret; +} + /** * pci_walk_bus - walk devices on/under bus, calling callback. * @top: bus whose devices should be walked @@ -449,6 +470,22 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struc= t pci_dev *, void *), void } EXPORT_SYMBOL_GPL(pci_walk_bus); =20 +/** + * pci_walk_bus_reverse - walk devices on/under bus, calling callback. + * @top: bus whose devices should be walked + * @cb: callback to be called for each device found + * @userdata: arbitrary pointer to be passed to callback + * + * Same semantics as pci_walk_bus(), but walks the bus in reverse order. + */ +void pci_walk_bus_reverse(struct pci_bus *top, + int (*cb)(struct pci_dev *, void *), void *userdata) +{ + guard(rwsem_read)(&pci_bus_sem); + __pci_walk_bus_reverse(top, cb, userdata); +} +EXPORT_SYMBOL_GPL(pci_walk_bus_reverse); + void pci_walk_bus_locked(struct pci_bus *top, int (*cb)(struct pci_dev *, = void *), void *userdata) { lockdep_assert_held(&pci_bus_sem); diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 53840634fbfc..7a4623f65256 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -282,6 +282,46 @@ static struct pci_dev *pci_get_dev_by_id(const struct = pci_device_id *id, return pdev; } =20 +static struct pci_dev *pci_get_dev_by_id_reverse(const struct pci_device_i= d *id, + struct pci_dev *from) +{ + struct device *dev; + struct device *dev_start =3D NULL; + struct pci_dev *pdev =3D NULL; + + if (from) + dev_start =3D &from->dev; + dev =3D bus_find_device_reverse(&pci_bus_type, dev_start, (void *)id, + match_pci_dev_by_id); + if (dev) + pdev =3D to_pci_dev(dev); + pci_dev_put(from); + return pdev; +} + +enum pci_search_direction { + PCI_SEARCH_FORWARD, + PCI_SEARCH_REVERSE, +}; + +static struct pci_dev *__pci_get_subsys(unsigned int vendor, unsigned int = device, + unsigned int ss_vendor, unsigned int ss_device, + struct pci_dev *from, enum pci_search_direction dir) +{ + struct pci_device_id id =3D { + .vendor =3D vendor, + .device =3D device, + .subvendor =3D ss_vendor, + .subdevice =3D ss_device, + }; + + if (dir =3D=3D PCI_SEARCH_FORWARD) + return pci_get_dev_by_id(&id, from); + else + return pci_get_dev_by_id_reverse(&id, from); +} + + /** * pci_get_subsys - begin or continue searching for a PCI device by vendor= /subvendor/device/subdevice id * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids @@ -302,14 +342,8 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, un= signed int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) { - struct pci_device_id id =3D { - .vendor =3D vendor, - .device =3D device, - .subvendor =3D ss_vendor, - .subdevice =3D ss_device, - }; - - return pci_get_dev_by_id(&id, from); + return __pci_get_subsys(vendor, device, ss_vendor, ss_device, from, + PCI_SEARCH_FORWARD); } EXPORT_SYMBOL(pci_get_subsys); =20 @@ -334,6 +368,19 @@ struct pci_dev *pci_get_device(unsigned int vendor, un= signed int device, } EXPORT_SYMBOL(pci_get_device); =20 +/* + * Same semantics as pci_get_device(), except walks the PCI device list + * in reverse discovery order. + */ +struct pci_dev *pci_get_device_reverse(unsigned int vendor, + unsigned int device, + struct pci_dev *from) +{ + return __pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from, + PCI_SEARCH_REVERSE); +} +EXPORT_SYMBOL(pci_get_device_reverse); + /** * pci_get_class - begin or continue searching for a PCI device by class * @class: search for a PCI device with this class designation diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index f5a56efd2bd6..99b1002b3e31 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -150,6 +150,9 @@ int bus_for_each_dev(const struct bus_type *bus, struct= device *start, void *data, device_iter_t fn); struct device *bus_find_device(const struct bus_type *bus, struct device *= start, const void *data, device_match_t match); +struct device *bus_find_device_reverse(const struct bus_type *bus, + struct device *start, const void *data, + device_match_t match); /** * bus_find_device_by_name - device iterator for locating a particular dev= ice * of a specific name. diff --git a/include/linux/pci.h b/include/linux/pci.h index 3fac811376b5..b8bca0711967 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -575,6 +575,8 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus); =20 #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d =3D pci_get_device(PCI_ANY_ID, PCI_A= NY_ID, d)) !=3D NULL) +#define for_each_pci_dev_reverse(d) \ + while ((d =3D pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, d)) !=3D NUL= L) =20 static inline int pci_channel_offline(struct pci_dev *pdev) { @@ -1220,6 +1222,8 @@ u64 pci_get_dsn(struct pci_dev *dev); =20 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from); +struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int d= evice, + struct pci_dev *from); struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); @@ -1639,6 +1643,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_d= ev *dev, int max, =20 void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata); +void pci_walk_bus_reverse(struct pci_bus *top, + int (*cb)(struct pci_dev *, void *), void *userdata); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); resource_size_t pcibios_window_alignment(struct pci_bus *bus, @@ -2031,6 +2037,11 @@ static inline struct pci_dev *pci_get_device(unsigne= d int vendor, struct pci_dev *from) { return NULL; } =20 +static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, + unsigned int device, + struct pci_dev *from) +{ return NULL; } + static inline struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 693D221517C; Thu, 17 Jul 2025 18:34:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777290; cv=fail; b=rWhXxjBDkyRJXIUJ4P3CAtUIvUYtGgCbu7nAPsvvWBkjYbVrB1hiYivEUJv8w5r2asSiKoB9D8U2+JcMVkVmEmSsDlak+DVg16mqO0NoFCdDKL2Ysl6RcCcnB/qR9HAIwJFn/twlmvv16yJ/g0WaJVNQZ6TPxvK0A2KVwvb0dzU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777290; c=relaxed/simple; bh=OzmZ3WVmANJ3UqcHkNzjPS0mBztfFjyvokbXohdU7es=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=uFT35GIdFSSxdUFWgx/QQSH5lViohjRlmp7qHHg30HmLVqiv85reNFYy2ICa0dJWlVulDSOadoZauXkKKS2U9hmgEqYsqId6rN9Sl7+JUdB6znh4jDPLZ0LrNovlKLUlZWOBzZnRbN4Bp8BtaM7SdssL7xHywBXbwIwHALWg0b0= ARC-Authentication-Results: i=2; 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=YxGH6kd7; arc=fail smtp.client-ip=198.175.65.19 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="YxGH6kd7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777289; x=1784313289; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=OzmZ3WVmANJ3UqcHkNzjPS0mBztfFjyvokbXohdU7es=; b=YxGH6kd7rrpE9yfzsM6VnzDvoW55PxkURFN8Wu7ZLE677RFZFaKroKYr tri5odyQsZ/Z1o8bASR3gJXYGkkxfVTDcUX8ZNUjW8HG0tAEi8fWBCOf0 CjWYvOKKXjUrnPTHb76DYOXIO/c/pptj6/2GyLJMYCFznY7ROz4/Doc3C m18gjryU58jfTV/rhheKfXSwf441kXgIIgNzLWMgijgqbjejwvtmgZtd9 ui4V2VXFxqFqchi3OBvOm/SQNiHhHQjVnVM8sGQ6JcbXmmkqf6azsCM8B fio1m7zr3Oj834mnyMo6nOX951ymvYH6LmCs8xVTbvethzbHORLLd26L1 A==; X-CSE-ConnectionGUID: QpttjgdXQTSP4K8kbs9/pw== X-CSE-MsgGUID: ROQA/e/pRCmCuRZn4YCl1A== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924225" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924225" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:48 -0700 X-CSE-ConnectionGUID: 0nRIKxt0TeCqAb3J8mkrzQ== X-CSE-MsgGUID: AAScje5YTHaPit4sAtMhDQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254744" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:48 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:47 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:47 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.59) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:45 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SZTUt38bHLolan3OVOmQM3yDs62/T+NaQmrHErKH1uyxCkIyWc1jw+0nYr1rXLrX/FTfh8/AhSzujNEjamGHGbuATTMDI488xRDEoZNDdCs4N6jKz1DY71H5a+okx5Oh8KdA7n6H/Wz0RiBZXxsLE87cjHae9GCoGqITM7ixswriOo5UOH4RnL9Xj46lako4B8QsVZrG2M+f3k5N1AGPzFTE47XT812GGnfv8DYVJCCMhzNaAUkOuq34IZbBv+K9XnyUwFUc5vQ4n4yO14+OozuqLjR2P9q6fRj80dbT0mEbcNoSyCItv8EoPIOgupSU5+Y7A3aSMPFuvHEBbXvPfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ds93xq326as/PJpfQFUperXm9g6Vb6UItCoDD8Y++LE=; b=CP+nprRn+dYgux3EFVreAy2Ai+rJnAHJh1r7zmQg+n8Zn2Fr69gh/R/UoFujnXWQgb/wMpFC+0a0ny83h/icDfkNZTZGIrA9WWnSHyPhW70r/bsY7t0AiqqwDTP1FC8LZHVlzm1WZCBnZ50Wg7UWYlJpXEfd8+VrSMLaVwIteZTxtHcymzI0RMJlVWXzu45PuXwAY0hW/+UmnivYUC9WaD+m8HZy2q0j7AQ41lvxuV3u4loVzgs2yxZ1GFheHKILlCZGfiXyoNktWJn30gIepMi2vW8WycC9El6KpgcATktxMipYi8RUj5GUmOSygJeosXPvN2Q7wTrrwu7yrFokXQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:06 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:06 +0000 From: Dan Williams To: , CC: , , , , Samuel Ortiz , Xu Yilun Subject: [PATCH v4 04/10] PCI/TSM: Authenticate devices via platform TSM Date: Thu, 17 Jul 2025 11:33:52 -0700 Message-ID: <20250717183358.1332417-5-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: c7650587-f11c-4bac-df51-08ddc56082c3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?fC32xoTSR6Iw6Cx6XyIqo50MG3RBdCZnCagfosP1VQDJkuoAymYzG8iO9hTv?= =?us-ascii?Q?9GOCfT5oy9ncS/4S9LNLdvWHXJEGvlpotl3nEZIlg4/2x59HCl/SbGS9e8lC?= =?us-ascii?Q?RUUwk5/Wy2yz7e4Jfc2Gk6zFbCJnKimRGQn+kXxqlkl6kRMwdqxXt1ijiO7w?= =?us-ascii?Q?YExWFSE62Frkp0SFC84Pz/XjYTXYtf29HZypx5mYW2MDw4Wkf8zp6rCE/F5t?= =?us-ascii?Q?tLAEgjcOWT3YUvR3+WZdc6DnFAG8zwGHX3hgcEoXhrcYfQZhEH4xKN6X8HgB?= =?us-ascii?Q?grkNUoT6YoG++ArwGZ2+Z9KtB35Kvs/7ga2D2PfXHky0mRNkusrASxDJolJ4?= =?us-ascii?Q?zv4RiBF76JRcz18nwvEpU6+0Gb7iO7j5nGNT7SdfnAxtGgxTd48eXf+6e5nJ?= =?us-ascii?Q?TtXMUJLo1cXVZ4eGZos1KrPuoMRLUooJhdf5FEYiYF+YTVZfh/DCqUVdCcal?= =?us-ascii?Q?bkdZOiHNxPh7vy2UsT4gtYIRzIM8dohm2CdXnFhBO0FRVN1XUZVkdnB7kBZW?= =?us-ascii?Q?dcPS/jagRo+YBhkcNFVAoupKAVNU1eL8jpQU/+fLQK7+RRjwXjyMs3W+ANyl?= =?us-ascii?Q?Pag2ckBitvhIQzvlEORE8qqGbbbI83xloP8ED0KnXO0X+2XOoQgYsXv2/EEQ?= =?us-ascii?Q?UowzJgKjvtZeVLyb121hMRr0P6rmoDyseKzzUcF8xrFwJZMYpdN0uHs90dXx?= =?us-ascii?Q?220sqrIdr+P3XX9TA/NPgHcne4K+F3WAjrwcWAPZyWY+hZq0yeZCgCF14iKy?= =?us-ascii?Q?yu5LFeuoeODxCaGDs1F7vl6jJtD/h3G7gkGhmzqv3wOxDMTXPrJjdXBShzpC?= =?us-ascii?Q?w1FCXIG3DJba50ZOFSAgE9HZwC3omAh+orK1QJyU9KeZ6v2nyWQvawtK6LMr?= =?us-ascii?Q?p9dWXo5YrbA5E1bZ/9Tsm59YpLWjw9R4ZmeE9vFlTqjfGBPn+TBsdyhHj/27?= =?us-ascii?Q?jZJh3myKahuYR5zDAMDLtBMsjQ0I1sbcTnruSg8mo8r8cOJY/JjGFvWD3LAP?= =?us-ascii?Q?Yn/HJiP7J9r+WevniiJy1xeV5Q9SPso/0cODSnuaSOVDbqgfbOhRYResAdS1?= =?us-ascii?Q?2Cz0XB6BqNWs261eSwj09GJZSEv1ytNYPyyVM5YtsodeOMwbNDwRbt4L6lrt?= =?us-ascii?Q?eEvOSPmyIku081m8W1ZCmNbNVDk4iijg603ZxRgGqaxirviRBalQ9/ZlrXYR?= =?us-ascii?Q?wSMmFljvYGySSBvYjx1GUteUP5qDVSywXYah2rtQUqqxm/OV1ctW1NigdIEi?= =?us-ascii?Q?bVNNUs92l9xG74XE+lHoVKsAsC5p3Skn2DHZBbT7hMgpqjWNuFIAlnEpxVWp?= =?us-ascii?Q?YX+UcppSY0qjI5F+QWsWEpTxGb2lW6Qm8kRt3ivqgfYOb4s+6BGqBGxpFHfH?= =?us-ascii?Q?Fo6/JlsACkO2cbdL1dhUir7lXNfeYO9QCaqnMvmKxwK/OA4SCVI66kuYCTKU?= =?us-ascii?Q?Q7+bs5gi1CU=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?NYMZSBdCdn/u6tlbEQoeYEuIhOc5giLE1RSbT2szrcp4wwCsVmDkTzxstOU9?= =?us-ascii?Q?4ayB1vGmKv6RVAYAlyhv5KIySblclgTWfjiMNw/76QT7xLJyJJF4gf9tMwlq?= =?us-ascii?Q?+/z+7jzdos1s1KzniFVD0exUajbmvehj8Qh00JKzA1czDwtK37z/FP1KpR9I?= =?us-ascii?Q?+OCnA6RXKTuJF6lNfgbMnt5/RSrjpV6v4uHR0F5uQemaCabFzAjbFIzRR2L5?= =?us-ascii?Q?7gYevCKzb7l+qZg9Yy0+MJRrLgX6t9g0cLDKWEJwM3uPU6e6JuQlY+UjR9Fj?= =?us-ascii?Q?wO+F0qM51ebR/XbpO1Iz7gQKl5Hj+32C5JcGHR5nTF0JAxHGY57scYPsVJf+?= =?us-ascii?Q?Vx64orh+KMeK9tM2SNoil3rP6toZnwpTV4uG9C0ZMubSlijdRL6d3Drwek9t?= =?us-ascii?Q?hVhFEeMaPQfXV47nGQaf95p/iBNAi0ST3Z/bNhSAE+DXrEurbjRLZtdqtOMK?= =?us-ascii?Q?dyYeIYwSbwpjkMBCm5aBjGLAzTIoHkPO0pXma7yFReKLqTrPsodV0MyMuD8k?= =?us-ascii?Q?yhHxtODRAfJkJf3uacHRiHGUmUGVeyJUBWB/8nRKgPZRaSUZ9li/7Nly3RIF?= =?us-ascii?Q?H67j+PyksxEYqc0Tfa4vx93rjurB3r+ivejtMtzwiN3j8cWbT5o95oRGNZIw?= =?us-ascii?Q?RwBVJ+n2P/J5zvq+b6oCOxKkvfsEU13Etl+YvtHHOiMQIlu9eus1DMnhNGR1?= =?us-ascii?Q?9v745p0QLKHblkm9mlPmXEDzWDfztltSR7p7+SkC2RHZLM1mV0klG/IgKDDd?= =?us-ascii?Q?qpy2W9Z02EPkbPJhOLkoNJWVfeeBSTvY1IocOmjp4FoAfu5ep8GD6eYvrVzw?= =?us-ascii?Q?kM2qYWXR0A2zlK6i0moVanS5F2KY/D10vR8bsyX3RopJKxSPUIKkvbw8yWQE?= =?us-ascii?Q?swjsUireavlyCfyWV9CAsM6UhyfUqO0Gy3a69vREV5Vs6qLTPPwC8FetAwL0?= =?us-ascii?Q?aDuYzWiYp3cQZSUUcdkmYe7pUBeVQ4X/GqHskXZlMDrBfvfPgB7Op+42gG06?= =?us-ascii?Q?PGN30sUTK/xsAH9zWjDm3fq31o8HXHE2HEm0aH6AtEmclXp484KPNyh7z7rX?= =?us-ascii?Q?Gg1SHT+uU63cM90KToHOj2d3mBQJUBwq7s8huYc/pOvKmW8iUqKwPyQV1F02?= =?us-ascii?Q?TvaP6a4l4FnFvoz59ou+C3IkPC4/bZKnxSBAIBM3tfW0a1NauKmFJAgmS5mS?= =?us-ascii?Q?ERxwelB4RaDe7CJ2S6k2lx/WpW2BbI2foY8LL0qnW5kAiV508HSECHOtg4LF?= =?us-ascii?Q?bNdmajtKx1p5i04gS5TrkdQHWmmEulkYU3sjaqSWMmQgsR5rTENAcUxMNx7/?= =?us-ascii?Q?OfhhKLK8/1vDay2/s7MqzTSghBmEHboGpL/CWjrfcweaa+Katky8JjcxZPn7?= =?us-ascii?Q?DQaSDXFWINAmUGTbkQpAKU70WBTeHezNik0sL+chwGYlAysmKdr/TymiDqY5?= =?us-ascii?Q?rulIjseNrl7GhdeII5FKKMYMUM+hHFMU3ItKGZIWLReRPeKar0OSpKBaTCwg?= =?us-ascii?Q?e8TG7ih8D9OPIQMUEflChj+WJA+1QzqtcmRuJc4SinD0LWuc5N96W21Y4I3K?= =?us-ascii?Q?4QVky7KI8EhGwQuUTB1f1r0CAFgcgyrBVuCld5t5H8M28kU//L4J9LrMJqDL?= =?us-ascii?Q?qg=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: c7650587-f11c-4bac-df51-08ddc56082c3 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:05.9643 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TbbPsBm5pQmFe3Qvlrd8mgkU3sAhu1AQcETSIdBFuku9C7o/FyHU0u0krXoX9i4W+ixkTBTQLCTDN+tlzOcBnj8N2jsMkK7FpbnuN+7G1WI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" The PCIe 6.1 specification, section 11, introduces the Trusted Execution Environment (TEE) Device Interface Security Protocol (TDISP). This protocol definition builds upon Component Measurement and Authentication (CMA), and link Integrity and Data Encryption (IDE). It adds support for assigning devices (PCI physical or virtual function) to a confidential VM such that the assigned device is enabled to access guest private memory protected by technologies like Intel TDX, AMD SEV-SNP, RISCV COVE, or ARM CCA. The "TSM" (TEE Security Manager) is a concept in the TDISP specification of an agent that mediates between a "DSM" (Device Security Manager) and system software in both a VMM and a confidential VM. A VMM uses TSM ABIs to setup link security and assign devices. A confidential VM uses TSM ABIs to transition an assigned device into the TDISP "RUN" state and validate its configuration. From a Linux perspective the TSM abstracts many of the details of TDISP, IDE, and CMA. Some of those details leak through at times, but for the most part TDISP is an internal implementation detail of the TSM. CONFIG_PCI_TSM adds an "authenticated" attribute and "tsm/" subdirectory to pci-sysfs. Consider that the TSM driver may itself be a PCI driver. Userspace can watch for the arrival of a "TSM" device, /sys/class/tsm/tsm0/uevent KOBJ_CHANGE, to know when the PCI core has initialized TSM services. The operations that can be executed against a PCI device are split into 2 mutually exclusive operation sets, "Link" and "Security" (struct pci_tsm_{link,security}_ops). The "Link" operations manage physical link security properties and communication with the device's Device Security Manager firmware. These are the host side operations in TDISP. The "Security" operations coordinate the security state of the assigned virtual device (TDI). These are the guest side operations in TDISP. Only link management operations are defined at this stage and placeholders provided for the security operations. The locking allows for multiple devices to be executing commands simultaneously, one outstanding command per-device and an rwsem synchronizes the implementation relative to TSM registration/unregistration events. Thanks to Wu Hao for his work on an early draft of this support. Cc: Lukas Wunner Cc: Samuel Ortiz Cc: Alexey Kardashevskiy Acked-by: Bjorn Helgaas Co-developed-by: Xu Yilun Signed-off-by: Xu Yilun Signed-off-by: Dan Williams --- Documentation/ABI/testing/sysfs-bus-pci | 51 +++ Documentation/driver-api/pci/index.rst | 1 + Documentation/driver-api/pci/tsm.rst | 12 + MAINTAINERS | 4 +- drivers/pci/Kconfig | 14 + drivers/pci/Makefile | 1 + drivers/pci/pci-sysfs.c | 4 + drivers/pci/pci.h | 8 + drivers/pci/remove.c | 3 + drivers/pci/tsm.c | 554 ++++++++++++++++++++++++ drivers/virt/coco/tsm-core.c | 61 ++- include/linux/pci-tsm.h | 158 +++++++ include/linux/pci.h | 3 + include/linux/tsm.h | 8 +- include/uapi/linux/pci_regs.h | 1 + 15 files changed, 879 insertions(+), 4 deletions(-) create mode 100644 Documentation/driver-api/pci/tsm.rst create mode 100644 drivers/pci/tsm.c create mode 100644 include/linux/pci-tsm.h diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/te= sting/sysfs-bus-pci index 69f952fffec7..99315fbfbe10 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -612,3 +612,54 @@ Description: =20 # ls doe_features 0001:01 0001:02 doe_discovery + +What: /sys/bus/pci/devices/.../tsm/ +Contact: linux-coco@lists.linux.dev +Description: + This directory only appears if a physical device function + supports authentication (PCIe CMA-SPDM), interface security + (PCIe TDISP), and is accepted for secure operation by the + platform TSM driver. This attribute directory appears + dynamically after the platform TSM driver loads. So, only after + the /sys/class/tsm/tsm0 device arrives can tools assume that + devices without a tsm/ attribute directory will never have one, + before that, the security capabilities of the device relative to + the platform TSM are unknown. See + Documentation/ABI/testing/sysfs-class-tsm. + +What: /sys/bus/pci/devices/.../tsm/connect +Contact: linux-coco@lists.linux.dev +Description: + (RW) Write the name of a TSM (TEE Security Manager) device from + /sys/class/tsm to this file to establish a connection with the + device. This typically includes an SPDM (DMTF Security + Protocols and Data Models) session over PCIe DOE (Data Object + Exchange) and may also include PCIe IDE (Integrity and Data + Encryption) establishment. Reads from this attribute return the + name of the connected TSM or the empty string if not + connected. A TSM device signals its readiness to accept PCI + connection via a KOBJ_CHANGE event. + +What: /sys/bus/pci/devices/.../tsm/disconnect +Contact: linux-coco@lists.linux.dev +Description: + (WO) Write '1' or 'true' to this attribute to disconnect it from + a previous TSM connection. + +What: /sys/bus/pci/devices/.../authenticated +Contact: linux-pci@vger.kernel.org +Description: + When the device's tsm/ directory is present device + authentication (PCIe CMA-SPDM) and link encryption (PCIe IDE) + are handled by the platform TSM (TEE Security Manager). When the + tsm/ directory is not present this attribute reflects only the + native CMA-SPDM authentication state with the kernel's + certificate store. + + If the attribute is not present, it indicates that + authentication is unsupported by the device, or the TSM has no + available authentication methods for the device. + + When present and the tsm/ attribute directory is present, the + authenticated attribute is an alias for the device 'connect' + state. See the 'tsm/connect' attribute for more details. diff --git a/Documentation/driver-api/pci/index.rst b/Documentation/driver-= api/pci/index.rst index a38e475cdbe3..9e1b801d0f74 100644 --- a/Documentation/driver-api/pci/index.rst +++ b/Documentation/driver-api/pci/index.rst @@ -10,6 +10,7 @@ The Linux PCI driver implementer's API guide =20 pci p2pdma + tsm =20 .. only:: subproject and html =20 diff --git a/Documentation/driver-api/pci/tsm.rst b/Documentation/driver-ap= i/pci/tsm.rst new file mode 100644 index 000000000000..59b94d79a4f2 --- /dev/null +++ b/Documentation/driver-api/pci/tsm.rst @@ -0,0 +1,12 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D +PCI Trusted Execution Environment Security Manager (TSM) +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D + +.. kernel-doc:: include/linux/pci-tsm.h + :internal: + +.. kernel-doc:: drivers/pci/tsm.c + :export: diff --git a/MAINTAINERS b/MAINTAINERS index cfa3fb8772d2..8cb7ee9270d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25247,8 +25247,10 @@ L: linux-coco@lists.linux.dev S: Maintained F: Documentation/ABI/testing/configfs-tsm-report F: Documentation/driver-api/coco/ +F: Documentation/driver-api/pci/tsm.rst +F: drivers/pci/tsm.c F: drivers/virt/coco/guest/ -F: include/linux/tsm*.h +F: include/linux/*tsm*.h F: samples/tsm-mr/ =20 TRUSTED SERVICES TEE DRIVER diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 4bd75d8b9b86..700addee8f62 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,20 @@ config PCI_IDE_STREAM_MAX platform capability for the foreseeable future is 4 to 8 streams. Bump this value up if you have an expert testing need. =20 +config PCI_TSM + bool "PCI TSM: Device security protocol support" + select PCI_IDE + select PCI_DOE + help + The TEE (Trusted Execution Environment) Device Interface + Security Protocol (TDISP) defines a "TSM" as a platform agent + that manages device authentication, link encryption, link + integrity protection, and assignment of PCI device functions + (virtual or physical) to confidential computing VMs that can + access (DMA) guest private memory. + + Enable a platform TSM driver to use this capability. + config PCI_DOE bool "Enable PCI Data Object Exchange (DOE) support" help diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 6612256fd37d..2c545f877062 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_XEN_PCIDEV_FRONTEND) +=3D xen-pcifront.o obj-$(CONFIG_VGA_ARB) +=3D vgaarb.o obj-$(CONFIG_PCI_DOE) +=3D doe.o obj-$(CONFIG_PCI_IDE) +=3D ide.o +obj-$(CONFIG_PCI_TSM) +=3D tsm.o obj-$(CONFIG_PCI_DYNAMIC_OF_NODES) +=3D of_property.o obj-$(CONFIG_PCI_NPEM) +=3D npem.o obj-$(CONFIG_PCIE_TPH) +=3D tph.o diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 268c69daa4d5..23cbf6c8796a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1815,6 +1815,10 @@ const struct attribute_group *pci_dev_attr_groups[] = =3D { #endif #ifdef CONFIG_PCI_DOE &pci_doe_sysfs_group, +#endif +#ifdef CONFIG_PCI_TSM + &pci_tsm_auth_attr_group, + &pci_tsm_pf0_attr_group, #endif NULL, }; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1c223c79634f..3b282c24dde8 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -521,6 +521,14 @@ void pci_ide_init(struct pci_dev *dev); static inline void pci_ide_init(struct pci_dev *dev) { } #endif =20 +#ifdef CONFIG_PCI_TSM +void pci_tsm_destroy(struct pci_dev *pdev); +extern const struct attribute_group pci_tsm_pf0_attr_group; +extern const struct attribute_group pci_tsm_auth_attr_group; +#else +static inline void pci_tsm_destroy(struct pci_dev *pdev) { } +#endif + /** * pci_dev_set_io_state - Set the new error state if possible. * diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 445afdfa6498..21851c13becd 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -55,6 +55,9 @@ static void pci_destroy_dev(struct pci_dev *dev) pci_doe_sysfs_teardown(dev); pci_npem_remove(dev); =20 + /* before device_del() to keep config cycle access */ + pci_tsm_destroy(dev); + device_del(&dev->dev); =20 down_write(&pci_bus_sem); diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c new file mode 100644 index 000000000000..0784cc436dd3 --- /dev/null +++ b/drivers/pci/tsm.c @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TEE Security Manager for the TEE Device Interface Security Protocol + * (TDISP, PCIe r6.1 sec 11) + * + * Copyright(c) 2024 Intel Corporation. All rights reserved. + */ + +#define dev_fmt(fmt) "TSM: " fmt + +#include +#include +#include + +#include +#include +#include +#include +#include "pci.h" + +/* + * Provide a read/write lock against the init / exit of pdev tsm + * capabilities and arrival/departure of a tsm instance + */ +static DECLARE_RWSEM(pci_tsm_rwsem); +static int pci_tsm_count; + +static inline bool is_dsm(struct pci_dev *pdev) +{ + return pdev->tsm && pdev->tsm->dsm =3D=3D pdev; +} + +static struct pci_tsm_pf0 *to_pci_tsm_pf0(struct pci_tsm *pci_tsm) +{ + struct pci_dev *pdev =3D pci_tsm->pdev; + + if (!is_pci_tsm_pf0(pdev) || !is_dsm(pdev)) { + dev_WARN_ONCE(&pdev->dev, 1, "invalid context object\n"); + return NULL; + } + + return container_of(pci_tsm, struct pci_tsm_pf0, tsm); +} + +static void tsm_remove(struct pci_tsm *tsm) +{ + struct pci_dev *pdev; + + if (!tsm) + return; + + pdev =3D tsm->pdev; + tsm->ops->remove(tsm); + pdev->tsm =3D NULL; +} +DEFINE_FREE(tsm_remove, struct pci_tsm *, if (_T) tsm_remove(_T)) + +static int call_cb_put(struct pci_dev *pdev, void *data, + int (*cb)(struct pci_dev *pdev, void *data)) +{ + int rc; + + if (!pdev) + return 0; + rc =3D cb(pdev, data); + pci_dev_put(pdev); + return rc; +} + +static void pci_tsm_walk_fns(struct pci_dev *pdev, + int (*cb)(struct pci_dev *pdev, void *data), + void *data) +{ + struct pci_dev *fn; + int i; + + /* walk virtual functions */ + for (i =3D 0; i < pci_num_vf(pdev); i++) { + fn =3D pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), + pci_iov_virtfn_bus(pdev, i), + pci_iov_virtfn_devfn(pdev, i)); + if (call_cb_put(fn, data, cb)) + return; + } + + /* walk subordinate physical functions */ + for (i =3D 1; i < 8; i++) { + fn =3D pci_get_slot(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), i)); + if (call_cb_put(fn, data, cb)) + return; + } + + /* walk downstream devices */ + if (pci_pcie_type(pdev) !=3D PCI_EXP_TYPE_UPSTREAM) + return; + + if (!is_dsm(pdev)) + return; + + pci_walk_bus(pdev->subordinate, cb, data); +} + +static void pci_tsm_walk_fns_reverse(struct pci_dev *pdev, + int (*cb)(struct pci_dev *pdev, + void *data), + void *data) +{ + struct pci_dev *fn; + int i; + + /* reverse walk virtual functions */ + for (i =3D pci_num_vf(pdev) - 1; i >=3D 0; i--) { + fn =3D pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), + pci_iov_virtfn_bus(pdev, i), + pci_iov_virtfn_devfn(pdev, i)); + if (call_cb_put(fn, data, cb)) + return; + } + + /* reverse walk subordinate physical functions */ + for (i =3D 7; i >=3D 1; i--) { + fn =3D pci_get_slot(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), i)); + if (call_cb_put(fn, data, cb)) + return; + } + + /* reverse walk downstream devices */ + if (pci_pcie_type(pdev) !=3D PCI_EXP_TYPE_UPSTREAM) + return; + + if (!is_dsm(pdev)) + return; + + pci_walk_bus_reverse(pdev->subordinate, cb, data); +} + +static int probe_fn(struct pci_dev *pdev, void *dsm) +{ + struct pci_dev *dsm_dev =3D dsm; + const struct pci_tsm_ops *ops =3D dsm_dev->tsm->ops; + + pdev->tsm =3D ops->probe(pdev); + pci_dbg(pdev, "setup tsm context: dsm: %s status: %s\n", + pci_name(dsm_dev), pdev->tsm ? "success" : "failed"); + return 0; +} + +static void pci_tsm_probe_fns(struct pci_dev *dsm) +{ + pci_tsm_walk_fns(dsm, probe_fn, dsm); +} + +static int pci_tsm_connect(struct pci_dev *pdev, struct tsm_dev *tsm_dev) +{ + int rc; + struct pci_tsm_pf0 *tsm_pf0; + const struct pci_tsm_ops *ops =3D tsm_pci_ops(tsm_dev); + struct pci_tsm *pci_tsm __free(tsm_remove) =3D ops->probe(pdev); + + if (!pci_tsm) + return -ENXIO; + + pdev->tsm =3D pci_tsm; + tsm_pf0 =3D to_pci_tsm_pf0(pdev->tsm); + + ACQUIRE(mutex_intr, lock)(&tsm_pf0->lock); + if ((rc =3D ACQUIRE_ERR(mutex_intr, &lock))) + return rc; + + rc =3D ops->connect(pdev); + if (rc) + return rc; + + pdev->tsm =3D no_free_ptr(pci_tsm); + + /* + * Now that the DSM is established, probe() all the potential + * dependent functions. Failure to probe a function is not fatal + * to connect(), it just disables subsequent security operations + * for that function. + */ + pci_tsm_probe_fns(pdev); + return 0; +} + +static ssize_t connect_show(struct device *dev, struct device_attribute *a= ttr, + char *buf) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + int rc; + + ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); + if ((rc =3D ACQUIRE_ERR(rwsem_read_intr, &lock))) + return rc; + + if (!pdev->tsm) + return sysfs_emit(buf, "\n"); + + return sysfs_emit(buf, "%s\n", tsm_name(pdev->tsm->ops->owner)); +} + +static ssize_t connect_store(struct device *dev, struct device_attribute *= attr, + const char *buf, size_t len) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + const struct pci_tsm_ops *ops; + struct tsm_dev *tsm_dev; + int rc, id; + + rc =3D sscanf(buf, "tsm%d\n", &id); + if (rc !=3D 1) + return -EINVAL; + + ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); + if ((rc =3D ACQUIRE_ERR(rwsem_read_intr, &lock))) + return rc; + + if (pdev->tsm) + return -EBUSY; + + tsm_dev =3D find_tsm_dev(id); + if (!tsm_dev) + return -ENXIO; + + ops =3D tsm_pci_ops(tsm_dev); + if (!ops || !ops->connect || !ops->probe) + return -ENXIO; + + rc =3D pci_tsm_connect(pdev, tsm_dev); + if (rc) + return rc; + return len; +} +static DEVICE_ATTR_RW(connect); + +static int remove_fn(struct pci_dev *pdev, void *data) +{ + tsm_remove(pdev->tsm); + return 0; +} + +static void pci_tsm_remove_fns(struct pci_dev *dsm) +{ + pci_tsm_walk_fns_reverse(dsm, remove_fn, NULL); +} + +static void __pci_tsm_disconnect(struct pci_dev *pdev) +{ + struct pci_tsm_pf0 *tsm_pf0 =3D to_pci_tsm_pf0(pdev->tsm); + const struct pci_tsm_ops *ops =3D pdev->tsm->ops; + + /* disconnect is not interruptible */ + guard(mutex)(&tsm_pf0->lock); + pci_tsm_remove_fns(pdev); + ops->disconnect(pdev); +} + +static void pci_tsm_disconnect(struct pci_dev *pdev) +{ + __pci_tsm_disconnect(pdev); + tsm_remove(pdev->tsm); +} + +static ssize_t disconnect_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t len) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + bool disconnect; + int rc; + + rc =3D kstrtobool(buf, &disconnect); + if (rc) + return rc; + if (!disconnect) + return -EINVAL; + + ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); + if ((rc =3D ACQUIRE_ERR(rwsem_read_intr, &lock))) + return rc; + + if (!pdev->tsm) + return -ENXIO; + + pci_tsm_disconnect(pdev); + return len; +} +static DEVICE_ATTR_WO(disconnect); + +static bool pci_tsm_pf0_group_visible(struct kobject *kobj) +{ + struct device *dev =3D kobj_to_dev(kobj); + struct pci_dev *pdev =3D to_pci_dev(dev); + + return pci_tsm_count && is_pci_tsm_pf0(pdev); +} +DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(pci_tsm_pf0); + +static struct attribute *pci_tsm_pf0_attrs[] =3D { + &dev_attr_connect.attr, + &dev_attr_disconnect.attr, + NULL +}; + +const struct attribute_group pci_tsm_pf0_attr_group =3D { + .name =3D "tsm", + .attrs =3D pci_tsm_pf0_attrs, + .is_visible =3D SYSFS_GROUP_VISIBLE(pci_tsm_pf0), +}; + +static ssize_t authenticated_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + /* + * When device authentication is TSM owned, 'authenticated' is + * identical to the connect state. + */ + return connect_show(dev, attr, buf); +} +static DEVICE_ATTR_RO(authenticated); + +static struct attribute *pci_tsm_auth_attrs[] =3D { + &dev_attr_authenticated.attr, + NULL +}; + +const struct attribute_group pci_tsm_auth_attr_group =3D { + .attrs =3D pci_tsm_auth_attrs, + .is_visible =3D SYSFS_GROUP_VISIBLE(pci_tsm_pf0), +}; + +/* + * Retrieve physical function0 device whether it has TEE capability or not + */ +static struct pci_dev *pf0_dev_get(struct pci_dev *pdev) +{ + struct pci_dev *pf_dev =3D pci_physfn(pdev); + + if (PCI_FUNC(pf_dev->devfn) =3D=3D 0) + return pci_dev_get(pf_dev); + + return pci_get_slot(pf_dev->bus, + pf_dev->devfn - PCI_FUNC(pf_dev->devfn)); +} + +/* + * Find the PCI Device instance that serves as the Device Security + * Manger (DSM) for @pdev. Note that no additional reference is held for + * the resulting device because @pdev always has a longer registered + * lifetime than its DSM by virtue of being a child of or identical to + * its DSM. + */ +static struct pci_dev *find_dsm_dev(struct pci_dev *pdev) +{ + struct pci_dev *uport_pf0; + + if (is_pci_tsm_pf0(pdev)) + return pdev; + + struct pci_dev *pf0 __free(pci_dev_put) =3D pf0_dev_get(pdev); + if (!pf0) + return NULL; + + if (is_dsm(pf0)) + return pf0; + + /* + * For cases where a switch may be hosting TDISP services on + * behalf of downstream devices, check the first usptream port + * relative to this endpoint. + */ + if (!pdev->dev.parent || !pdev->dev.parent->parent) + return NULL; + + uport_pf0 =3D to_pci_dev(pdev->dev.parent->parent); + if (is_dsm(uport_pf0)) + return uport_pf0; + return NULL; +} + +/** + * pci_tsm_constructor() - base 'struct pci_tsm' initialization + * @pdev: The PCI device + * @tsm: context to initialize + * @ops: PCI operations provided by the TSM + */ +int pci_tsm_constructor(struct pci_dev *pdev, struct pci_tsm *tsm, + const struct pci_tsm_ops *ops) +{ + tsm->pdev =3D pdev; + tsm->ops =3D ops; + tsm->dsm =3D find_dsm_dev(pdev); + if (!tsm->dsm) { + pci_warn(pdev, "failed to find Device Security Manager\n"); + return -ENXIO; + } + return 0; +} +EXPORT_SYMBOL_GPL(pci_tsm_constructor); + +/** + * pci_tsm_pf0_constructor() - common 'struct pci_tsm_pf0' initialization + * @pdev: Physical Function 0 PCI device (as indicated by is_pci_tsm_pf0()) + * @tsm: context to initialize + */ +int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm, + const struct pci_tsm_ops *ops) +{ + struct tsm_dev *tsm_dev =3D ops->owner; + + mutex_init(&tsm->lock); + tsm->doe_mb =3D pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG, + PCI_DOE_PROTO_CMA); + if (!tsm->doe_mb) { + pci_warn(pdev, "TSM init failure, no CMA mailbox\n"); + return -ENODEV; + } + + if (tsm_pci_group(tsm_dev)) + sysfs_merge_group(&pdev->dev.kobj, tsm_pci_group(tsm_dev)); + + return pci_tsm_constructor(pdev, &tsm->tsm, ops); +} +EXPORT_SYMBOL_GPL(pci_tsm_pf0_constructor); + +void pci_tsm_pf0_destructor(struct pci_tsm_pf0 *pf0_tsm) +{ + struct pci_tsm *tsm =3D &pf0_tsm->tsm; + struct pci_dev *pdev =3D tsm->pdev; + struct tsm_dev *tsm_dev =3D tsm->ops->owner; + + if (tsm_pci_group(tsm_dev)) + sysfs_unmerge_group(&pdev->dev.kobj, tsm_pci_group(tsm_dev)); + mutex_destroy(&pf0_tsm->lock); +} +EXPORT_SYMBOL_GPL(pci_tsm_pf0_destructor); + +static void pf0_sysfs_enable(struct pci_dev *pdev) +{ + pci_dbg(pdev, "Device Security Manager detected (%s%s )\n", + pdev->ide_cap ? " ide" : "", + pdev->devcap & PCI_EXP_DEVCAP_TEE ? " tee" : ""); + + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_pf0_attr_group); +} + +int pci_tsm_register(struct tsm_dev *tsm_dev) +{ + const struct pci_tsm_ops *ops; + struct pci_dev *pdev =3D NULL; + + if (!tsm_dev) + return -EINVAL; + + /* + * The TSM device must have pci_ops, and only implement one of link_ops + * or sec_ops. + */ + ops =3D tsm_pci_ops(tsm_dev); + if (!ops) + return -EINVAL; + + if (!ops->probe && !ops->sec_probe) + return -EINVAL; + + if (ops->probe && ops->sec_probe) + return -EINVAL; + + guard(rwsem_write)(&pci_tsm_rwsem); + + pci_tsm_count++; + + /* PCI/TSM sysfs already enabled? */ + if (pci_tsm_count > 1) + return 0; + + for_each_pci_dev(pdev) + if (is_pci_tsm_pf0(pdev)) + pf0_sysfs_enable(pdev); + return 0; +} +EXPORT_SYMBOL_GPL(pci_tsm_register); + +/** + * __pci_tsm_destroy() - destroy the TSM context for @pdev + * @pdev: device to cleanup + * @tsm_dev: TSM context if a TSM device is being removed, NULL if + * @pdev is being removed. + * + * At device removal or TSM unregistration all established context + * with the TSM is torn down. Additionally, if there are no more TSMs + * registered, the PCI tsm/ sysfs attributes are hidden. + */ +static void __pci_tsm_destroy(struct pci_dev *pdev, struct tsm_dev *tsm_de= v) +{ + struct pci_tsm *tsm =3D pdev->tsm; + + lockdep_assert_held_write(&pci_tsm_rwsem); + + if (tsm_dev && is_pci_tsm_pf0(pdev) && !pci_tsm_count) { + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_pf0_attr_group); + } + + if (!tsm) + return; + + if (!tsm_dev) + tsm_dev =3D tsm->ops->owner; + else if (tsm_dev !=3D tsm->ops->owner) + return; + + if (is_pci_tsm_pf0(pdev)) + pci_tsm_disconnect(pdev); + else + tsm_remove(pdev->tsm); +} + +void pci_tsm_destroy(struct pci_dev *pdev) +{ + guard(rwsem_write)(&pci_tsm_rwsem); + __pci_tsm_destroy(pdev, NULL); +} + +void pci_tsm_unregister(struct tsm_dev *tsm_dev) +{ + struct pci_dev *pdev =3D NULL; + + guard(rwsem_write)(&pci_tsm_rwsem); + pci_tsm_count--; + for_each_pci_dev_reverse(pdev) + __pci_tsm_destroy(pdev, tsm_dev); +} + +int pci_tsm_doe_transfer(struct pci_dev *pdev, enum pci_doe_proto type, + const void *req, size_t req_sz, void *resp, + size_t resp_sz) +{ + struct pci_tsm_pf0 *tsm; + + if (!pdev->tsm || !is_pci_tsm_pf0(pdev)) + return -ENXIO; + + tsm =3D to_pci_tsm_pf0(pdev->tsm); + if (!tsm->doe_mb) + return -ENXIO; + + return pci_doe(tsm->doe_mb, PCI_VENDOR_ID_PCI_SIG, type, req, req_sz, + resp, resp_sz); +} +EXPORT_SYMBOL_GPL(pci_tsm_doe_transfer); diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c index 1f53b9049e2d..093824dc68dd 100644 --- a/drivers/virt/coco/tsm-core.c +++ b/drivers/virt/coco/tsm-core.c @@ -9,6 +9,7 @@ #include #include #include +#include =20 static struct class *tsm_class; static DECLARE_RWSEM(tsm_rwsem); @@ -17,8 +18,39 @@ static DEFINE_IDR(tsm_idr); struct tsm_dev { struct device dev; int id; + const struct pci_tsm_ops *pci_ops; + const struct attribute_group *group; }; =20 +const char *tsm_name(const struct tsm_dev *tsm_dev) +{ + return dev_name(&tsm_dev->dev); +} + +/* + * Caller responsible for ensuring it does not race tsm_dev + * unregistration. + */ +struct tsm_dev *find_tsm_dev(int id) +{ + guard(rcu)(); + return idr_find(&tsm_idr, id); +} + +const struct pci_tsm_ops *tsm_pci_ops(const struct tsm_dev *tsm_dev) +{ + if (!tsm_dev) + return NULL; + return tsm_dev->pci_ops; +} + +const struct attribute_group *tsm_pci_group(const struct tsm_dev *tsm_dev) +{ + if (!tsm_dev) + return NULL; + return tsm_dev->group; +} + static struct tsm_dev *alloc_tsm_dev(struct device *parent, const struct attribute_group **groups) { @@ -44,6 +76,29 @@ static struct tsm_dev *alloc_tsm_dev(struct device *pare= nt, return no_free_ptr(tsm_dev); } =20 +static struct tsm_dev *tsm_register_pci_or_reset(struct tsm_dev *tsm_dev, + struct pci_tsm_ops *pci_ops) +{ + int rc; + + if (!pci_ops) + return tsm_dev; + + pci_ops->owner =3D tsm_dev; + tsm_dev->pci_ops =3D pci_ops; + rc =3D pci_tsm_register(tsm_dev); + if (rc) { + dev_err(tsm_dev->dev.parent, + "PCI/TSM registration failure: %d\n", rc); + device_unregister(&tsm_dev->dev); + return ERR_PTR(rc); + } + + /* Notify TSM userspace that PCI/TSM operations are now possible */ + kobject_uevent(&tsm_dev->dev.kobj, KOBJ_CHANGE); + return tsm_dev; +} + static void put_tsm_dev(struct tsm_dev *tsm_dev) { if (!IS_ERR_OR_NULL(tsm_dev)) @@ -54,7 +109,8 @@ DEFINE_FREE(put_tsm_dev, struct tsm_dev *, if (!IS_ERR_OR_NULL(_T)) put_tsm_dev(_T)) =20 struct tsm_dev *tsm_register(struct device *parent, - const struct attribute_group **groups) + const struct attribute_group **groups, + struct pci_tsm_ops *pci_ops) { struct tsm_dev *tsm_dev __free(put_tsm_dev) =3D alloc_tsm_dev(parent, groups); @@ -73,12 +129,13 @@ struct tsm_dev *tsm_register(struct device *parent, if (rc) return ERR_PTR(rc); =20 - return no_free_ptr(tsm_dev); + return tsm_register_pci_or_reset(no_free_ptr(tsm_dev), pci_ops); } EXPORT_SYMBOL_GPL(tsm_register); =20 void tsm_unregister(struct tsm_dev *tsm_dev) { + pci_tsm_unregister(tsm_dev); device_unregister(&tsm_dev->dev); } EXPORT_SYMBOL_GPL(tsm_unregister); diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h new file mode 100644 index 000000000000..f370c022fac4 --- /dev/null +++ b/include/linux/pci-tsm.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PCI_TSM_H +#define __PCI_TSM_H +#include +#include + +struct pci_tsm; + +/* + * struct pci_tsm_ops - manage confidential links and security state + * @link_ops: Coordinate PCIe SPDM and IDE establishment via a platform TS= M. + * Provide a secure session transport for TDISP state management + * (typically bare metal physical function operations). + * @sec_ops: Lock, unlock, and interrogate the security state of the + * function via the platform TSM (typically virtual function + * operations). + * @owner: Back reference to the TSM device that owns this instance. + * + * This operations are mutually exclusive either a tsm_dev instance + * manages phyiscal link properties or it manages function security + * states like TDISP lock/unlock. + */ +struct pci_tsm_ops { + /* + * struct pci_tsm_link_ops - Manage physical link and the TSM/DSM session + * @probe: probe device for tsm link operation readiness, setup + * DSM context + * @remove: destroy DSM context + * @connect: establish / validate a secure connection (e.g. IDE) + * with the device + * @disconnect: teardown the secure link + * + * @probe and @remove run in pci_tsm_rwsem held for write context. All + * other ops run under the @pdev->tsm->lock mutex and pci_tsm_rwsem held + * for read. + */ + struct_group_tagged(pci_tsm_link_ops, link_ops, + struct pci_tsm *(*probe)(struct pci_dev *pdev); + void (*remove)(struct pci_tsm *tsm); + int (*connect)(struct pci_dev *pdev); + void (*disconnect)(struct pci_dev *pdev); + ); + + /* + * struct pci_tsm_security_ops - Manage the security state of the function + * @sec_probe: probe device for tsm security operation + * readiness, setup security context + * @sec_remove: destroy security context + * + * @sec_probe and @sec_remove run in pci_tsm_rwsem held for + * write context. All other ops run under the @pdev->tsm->lock + * mutex and pci_tsm_rwsem held for read. + */ + struct_group_tagged(pci_tsm_security_ops, ops, + struct pci_tsm *(*sec_probe)(struct pci_dev *pdev); + void (*sec_remove)(struct pci_tsm *tsm); + ); + struct tsm_dev *owner; +}; + +/** + * struct pci_tsm - Core TSM context for a given PCIe endpoint + * @pdev: Back ref to device function, distinguishes type of pci_tsm conte= xt + * @dsm: PCI Device Security Manager for link operations on @pdev. + * @ops: Link Confidentiality or Device Function Security operations + * + * This structure is wrapped by low level TSM driver data and returned + * by probe()/sec_probe(), it is freed by the corresponding + * remove()/sec_remove(). + * + * For link operations it serves to cache the association between a + * Device Security Manager (DSM) and the functions that manager can + * assign to a TVM. That can be "self", for assigning function0 of a + * TEE I/O device, a sub-function (SR-IOV virtual function, or + * non-function0 multifunction-device), or a downstream endpoint (PCIe + * upstream switch-port as DSM). + */ +struct pci_tsm { + struct pci_dev *pdev; + struct pci_dev *dsm; + const struct pci_tsm_ops *ops; +}; + +/** + * struct pci_tsm_pf0 - Physical Function 0 TDISP link context + * @tsm: generic core "tsm" context + * @lock: protect @state vs pci_tsm_ops invocation + * @doe_mb: PCIe Data Object Exchange mailbox + */ +struct pci_tsm_pf0 { + struct pci_tsm tsm; + struct mutex lock; + struct pci_doe_mb *doe_mb; +}; + +/* physical function0 and capable of 'connect' */ +static inline bool is_pci_tsm_pf0(struct pci_dev *pdev) +{ + if (!pci_is_pcie(pdev)) + return false; + + if (pdev->is_virtfn) + return false; + + /* + * Allow for a Device Security Manager (DSM) associated with function0 + * of an Endpoint to coordinate TDISP requests for other functions + * (physical or virtual) of the device, or allow for an Upstream Port + * DSM to accept TDISP requests for switch Downstream Endpoints. + */ + switch (pci_pcie_type(pdev)) { + case PCI_EXP_TYPE_ENDPOINT: + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_RC_END: + if (pdev->ide_cap || (pdev->devcap & PCI_EXP_DEVCAP_TEE)) + break; + fallthrough; + default: + return false; + } + + return PCI_FUNC(pdev->devfn) =3D=3D 0; +} + +enum pci_doe_proto { + PCI_DOE_PROTO_CMA =3D 1, + PCI_DOE_PROTO_SSESSION =3D 2, +}; + +#ifdef CONFIG_PCI_TSM +struct tsm_dev; +int pci_tsm_register(struct tsm_dev *tsm_dev); +void pci_tsm_unregister(struct tsm_dev *tsm_dev); +int pci_tsm_doe_transfer(struct pci_dev *pdev, enum pci_doe_proto type, + const void *req, size_t req_sz, void *resp, + size_t resp_sz); +int pci_tsm_constructor(struct pci_dev *pdev, struct pci_tsm *tsm, + const struct pci_tsm_ops *ops); +int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm, + const struct pci_tsm_ops *ops); +void pci_tsm_pf0_destructor(struct pci_tsm_pf0 *tsm); +#else +static inline int pci_tsm_register(struct tsm_dev *tsm_dev) +{ + return 0; +} +static inline void pci_tsm_unregister(struct tsm_dev *tsm_dev) +{ +} +static inline int pci_tsm_doe_transfer(struct pci_dev *pdev, + enum pci_doe_proto type, const void *req, + size_t req_sz, void *resp, + size_t resp_sz) +{ + return -ENOENT; +} +#endif +#endif /*__PCI_TSM_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index b8bca0711967..0e5703fad0f6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -539,6 +539,9 @@ struct pci_dev { u8 nr_link_ide; /* Link Stream count (Selective Stream offset) */ unsigned int ide_cfg:1; /* Config cycles over IDE */ unsigned int ide_tee_limit:1; /* Disallow T=3D0 traffic over IDE */ +#endif +#ifdef CONFIG_PCI_TSM + struct pci_tsm *tsm; /* TSM operation state */ #endif u16 acs_cap; /* ACS Capability offset */ u8 supported_speeds; /* Supported Link Speeds Vector */ diff --git a/include/linux/tsm.h b/include/linux/tsm.h index a90b40b1b13c..ce95589a5d5b 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -111,7 +111,13 @@ struct tsm_report_ops { int tsm_report_register(const struct tsm_report_ops *ops, void *priv); int tsm_report_unregister(const struct tsm_report_ops *ops); struct tsm_dev; +struct pci_tsm_ops; struct tsm_dev *tsm_register(struct device *parent, - const struct attribute_group **groups); + const struct attribute_group **groups, + struct pci_tsm_ops *ops); void tsm_unregister(struct tsm_dev *tsm_dev); +const char *tsm_name(const struct tsm_dev *tsm_dev); +struct tsm_dev *find_tsm_dev(int id); +const struct pci_tsm_ops *tsm_pci_ops(const struct tsm_dev *tsm_dev); +const struct attribute_group *tsm_pci_group(const struct tsm_dev *tsm_dev); #endif /* __TSM_H */ diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index ab4ebf0f8a46..1b991a88c19c 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -500,6 +500,7 @@ #define PCI_EXP_DEVCAP_PWR_VAL 0x03fc0000 /* Slot Power Limit Value */ #define PCI_EXP_DEVCAP_PWR_SCL 0x0c000000 /* Slot Power Limit Scale */ #define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ +#define PCI_EXP_DEVCAP_TEE 0x40000000 /* TEE I/O (TDISP) Support */ #define PCI_EXP_DEVCTL 0x08 /* Device Control */ #define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ #define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 53E322139C9; Thu, 17 Jul 2025 18:34:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777262; cv=fail; b=QF7mxX0OoF3/XGdKvdh1bfaxX55b68dGLon81M0Mb3fIDce03OllD3JER+T3YZs1zCoW61VjR3fvGagmu+C6kB9hxViLR8zyxzn6++CA8hwUtuQ7UHoBuNQtjxHBDzcANWgYK7RlwOK1UbrJPZBzDZW2q/SH0ISe4jgyjPBkbsI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777262; c=relaxed/simple; bh=oWv/puRk/razr/eLj8/IPv/kRsiMlPvZikayf8gMH90=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=CqDulO6Per43RGXlfTm5LrRTL4r5xoDAbMM1JQP2fzRgBHbmE+X+B/Q/p8vP2vRjJEAuDGs+1ryuUthLAbu6xwEktrH+/3sYtBYQtwVQ2FKwb+9XzgRTvu7DtATSJOEDUBVSHZyyBKbtRg4oYvHyXZGgpVeX+NHyWygxggu1iRI= ARC-Authentication-Results: i=2; 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=DFXWnea1; arc=fail smtp.client-ip=198.175.65.19 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="DFXWnea1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777259; x=1784313259; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=oWv/puRk/razr/eLj8/IPv/kRsiMlPvZikayf8gMH90=; b=DFXWnea1uBDtdeaX0kWboMNMuCmmKl/+MheQC0bzksjmR3+/jxdSoBg3 KS5XG1nDXiLm4fhRRDeWrRkwRSq7XXlown89NXp1O9w6rzVQsVKHHc88y PxyCkQ60W94l2Uy4L9Rzp2qAtITQa7mqYyqle0Sy/y6cwn4kiiPJXvQii x2LZ04lADKQbS5JcSc3oZ1YNCU870dWc0pSazPcqcUqnLW6YRVowhzxqH eyjZo61mYSCu6IdR4iu+e60rN/0nYAY5EuAxvwtQlmTH5LabaTjCLaMJ6 vLMjv68+2WLEuiMfkQbu9cSbHzMoRlavhKhfqBZPKcyhMSHRzjwojHFdT Q==; X-CSE-ConnectionGUID: 0K27JUGMR+iQoBWllU0q0g== X-CSE-MsgGUID: tnjyY6p5SSCJIjnDoLm90g== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924096" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924096" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:16 -0700 X-CSE-ConnectionGUID: hmV9fQ1bQ8ePstLzXmjFtw== X-CSE-MsgGUID: zym7m0IuSEOPNcvoezLn6g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254642" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:16 -0700 Received: from ORSMSX903.amr.corp.intel.com (10.22.229.25) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:15 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:15 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:13 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IoaPDGl5I1HJxEbWEMYNGWE1rqObnXo83uZh0AB7gYETkSWvMmPGmTAfj5KemCzXdPuq/lEKj1qtulIuK7vbqkUkkT7ES3w8QNvEV7d8dbVoygK6sppCVfbPdx0VbBoa1FaBwcU2c7XgHP46N0FvaV9v/n8yLny4pW2RK37d7MYLgWSQxQSRqZ0g9kJ0RtNMuUxGTllpadIjVNxaq/FltVeDQv61N1ieuefhc0wc/1yIk/2dRUHOw+F7KjVW3jWFQq8zZG808FOmat7z9ehfmj3EtNl0N05fcdGe16EmKcqjx1O0D/vzBENSv9Gt0fZrHT1igSvR0zsg9KY9BEOcVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4kjSXqWNTtWqnxY47CiaHjaa57S9oudA1scXnqhSbgQ=; b=kQ/WTKC6mLUFSQIueIWZVTLSQQcSIklIO80Sgpdo3+Aqjj0MIXakQChYkcb3Ed4HbZLH2LVt9o8YLRBVuyqep7wDo4dyl0xTLvChtLH2tC3APNX0ZQMQLLeacxNgtmdnklJj3m4y4Nkhr8RIi8yjm+Js7l7bAR5Kq4ZEwi0SeO85FM9ekCrUBFNKPSmg+pQ4ITvvT59BYynIkwIM4mwvKxu85a9vwXQHPW1YIVnFza8+KdCyeILkgPVE6ZzGQyRZZO5U57AVOZsgAjXgO21tR27hDheeiFwrk7Mc2A+FP7TmnOhOXzWNAiRsjmtW+KoKAHkMUtkTIInFCPTAn58xYQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:07 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:06 +0000 From: Dan Williams To: , CC: , , , , Samuel Ortiz , Xu Yilun Subject: [PATCH v4 05/10] samples/devsec: Introduce a PCI device-security bus + endpoint sample Date: Thu, 17 Jul 2025 11:33:53 -0700 Message-ID: <20250717183358.1332417-6-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: 30aa76c6-5db6-45c9-2220-08ddc560834e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?45h7GHkB4vawisn8Ydi3HfuZSELrWj49A3pUInXDTpglM6Gkn2lN4yLKxuG+?= =?us-ascii?Q?tgSHyJazIOsogEJdwFhLtqEWLlTsAGustqqL9sPjyM9ZXXxeT2m+EAhbGreL?= =?us-ascii?Q?wLF29/lUaprzJcDuuPOlJLiC/grn8EN66vy4DB5mUdLr09KrfzUzz43bghJo?= =?us-ascii?Q?or7uZYoX2p+DzCSahxsGwDmJBO/UL37qhB/o2i3ytJGKa63wb8sBlXC6zlcV?= =?us-ascii?Q?HDAP84zDs9q2vloQtOQqw+l8VxNFVA8iiCoatDxPTQbbR+obzvdJwSj8C7Iy?= =?us-ascii?Q?Buur8ReveUKHz/gsdFL7PXB98ZVdHFY0mBzQU2pivVfDTe91MCluR1dns4UG?= =?us-ascii?Q?t7EGZgCU+PnACxFWkz+E4oVmOgwc8cjzQc2tM46RE/ZgQuM5eAQvK1sbOOD7?= =?us-ascii?Q?wYHsuqY3ZRbqSrg1YuX7esa5JJNKSxSCnbSw3apGMuoDACLtu1l4bP3F/FTg?= =?us-ascii?Q?gFWdTU4Z7HDdrd/UI0A/ga4lvzZDpWQuyjj7FE2gdy/EX/LdYDKnAu8o4H9g?= =?us-ascii?Q?lqBoQfjC4n6EDPB3GXIHbG6ZFeavL0kcCgg653guQTewXTMjb1uBXj0FNFlP?= =?us-ascii?Q?WTZlUsvSNOGwgdOzz3coL8rFJ5OkHiK6TXsEQgHbjN1TMAXkgBsrxxlEtbkB?= =?us-ascii?Q?nxztrnPhkC3KSgBMGHiSLbAXNjfu0zVdFgPjpKAkBLoj7+9v38Mw/749be2E?= =?us-ascii?Q?b3pPrmr8CZOB95IUI2SJR7QQ1RTgIMqrQk15EEvwzkxcmLHNAsT1x87OoBdf?= =?us-ascii?Q?gK7ZiwdLwNdWY74mUFbcubfPJIdy3oN21UwN9XK5C2RQN5P/Yql027QwTaCx?= =?us-ascii?Q?w0T60E9DLXyNkM0al5tb4dGFBjulMWqV485RjKz8RxOUIVMEUVoY35Qx315e?= =?us-ascii?Q?noBD/5fwlDMR0/SgqWIvu2Gy04CwnNA0onRfEY/yeUB/hv+3vJVj65gzc2uE?= =?us-ascii?Q?O/qlApmlfMfQBXB6eanH0nmFFJKEjFoqmssarYKvwyh6FniTtA8C3Ae2A9L3?= =?us-ascii?Q?cSSbue06+shM1skW01zyEhkP8o/hUGu98ETlrmv/c6e3XyYJbAk0EsW5gcRq?= =?us-ascii?Q?kezpxSXfrfU8szgClNZOC0LXRvOql9llwmwzYWZ0CoL+3zgsvu2y8ixSqpIL?= =?us-ascii?Q?J1w9jsg7LW6UGXCI6q8ElHVfuSJayS+LJC0CSm0tpKpwS6NLORi2lpVaUuhg?= =?us-ascii?Q?3jBXzpDvxXPqL8wrXGIliHk6KTAyPgSh3TERKCx82DthfzvANiLl4qWyiw1g?= =?us-ascii?Q?ja4qiZ6hvvSjjRQjUI0weEPY3wLuVb3ZdPjyxFoRYO0ca6ACQ97e2VeSYi+T?= =?us-ascii?Q?4JjzC7TA1mlnCfqCzpQtE4/7pFkhYvftapbQqpMMwNLFnXhkPcJqQ89YC4gV?= =?us-ascii?Q?MwkHKYZHjWvRKpJ1+zXLPu648ZpcgM0QbHcuCj0+ZJgrsLC70sA2j1qN0rZG?= =?us-ascii?Q?CPoaZWJT8Ok=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ayNkD0Arnd8VrUIXpqr7mm+3xvhXp0OdmF5gcYBjOkb6UUjLuBO4XSYgJMYU?= =?us-ascii?Q?N6dXBpx9v8nX1gFKEzcH6EvKwIG4HSeeXlqsqesNaKOxfsoRBwXdudkk2Zkg?= =?us-ascii?Q?s3MT6PW1LhRX+ucbIn2RgQcFp+cp/OYdYvyFUwokWVBrl70J+HXZt/8eBufB?= =?us-ascii?Q?YazNI8RNq1Lx0FQvXIhmuDmgOcS5KA2hsiof3z4N+9wM4tfoz6PQfWiRzpY7?= =?us-ascii?Q?890dgVSb+UhPlIwc3nMN16r3naNhowXNdN00weJXx/OYWevz+XSJVOTV44mC?= =?us-ascii?Q?cycQaFCA3sKblu5E4fHnI9TbSr3crwNCHnZbgy8EaGQ62Cg6zKSPQZXqUHAH?= =?us-ascii?Q?uKn0AR3DclvjN8fzt4JCXUn3aWSiDwG4h1VLzfKT83fSuw7FtdV2QQEtWgl9?= =?us-ascii?Q?ax/EYkvHoFaSVIXNLXs5rwKeaHhz/+unQK5bSuK5tPbA355Rsyu3uFv6Ug2W?= =?us-ascii?Q?CeRzcL8FfDDFmLYiSZgtejQVYN50Ww7rC8BxsiQm6Ah6achwQs5gZijX1eTT?= =?us-ascii?Q?4jk4PNDV0U+EZtXABUxdSAuFr1JFmuJUJvl0QTA76J/3oC6f8zae4wrriT30?= =?us-ascii?Q?NciyQmbzAZuQ6YAEW9c+vEyveMorsV6TKN6lBx6XUxqjBq37tzR2fLd87NO0?= =?us-ascii?Q?gHtAiKZ52AI+eSSn6ObK5P8ofKfb9pCuPNjUR/mJEUJrWEZ2FOLp5ghwHdx1?= =?us-ascii?Q?SGeO27+1RiqVsQ900qZkHa5ejEyw6CZCHtv7R4BFkTVBuagfxEYNgU8KhZ1u?= =?us-ascii?Q?NLTJqbJ2TRQLEnbwRfEwbhNCCHE31BJXE7B9ppuaMa3Q4VNzEm31lK8wGmDM?= =?us-ascii?Q?/z6UEDA5QY4vDGRJWBX/WiLL+bEdr0WvqbhN7eXldPwtmMmD3eIfN+XkG9fz?= =?us-ascii?Q?52n5GctMbXcTLSXUueyqI1sUG8xPnZPwqm1XRLXnolKpURgF9RkSF/Qa5dGN?= =?us-ascii?Q?McaaFXbYHCfKv16OowmC3Jh9Du7kt6cVD8wvqCPTi9PmO8t/4tM9v0sEe6kn?= =?us-ascii?Q?77RyCmMMpLMaIFf0Zmr8K4W3z1BG5K4Fop+2xNhvBMt23NuAKuRcVh/XWWGv?= =?us-ascii?Q?ZH8grDnssvvI7CphvFx18Nm44xBj3Wsl7g1gJDSD4mruuhdBg9uQQRCGhyRZ?= =?us-ascii?Q?k0fx+hngy68kFnPpljFzM2jhY+w1lE3rshsriEoXLFWiNvyJurKTWJ4bSlBh?= =?us-ascii?Q?kdHk6JzP9A/w02eutv0NJcikV3lQoIAE4RCXEl8YchPsFfXINDWtbLDboE0o?= =?us-ascii?Q?w6cB3OUZT7LWHhiSnyWZGJ9REGyf1zS7XEAb7bEP5ea9/GI7yAKt23HFrcwm?= =?us-ascii?Q?yFusc/ipE8T+x4HYxG8jsU/CGBexkWoEw/RPrMeHAJhuH8bbdOzFor80KHua?= =?us-ascii?Q?zQguuzuDzHgN1ulqPvzhVPE/kUPPSpxxDyExYdvcqYJUSz6SFePUxz4SjJYl?= =?us-ascii?Q?X+b+6fa8hVYVRMMT/kICVl75qVTAAKyETQK9SILNylMpDs1SZa6l1l98t28E?= =?us-ascii?Q?oqJH7Jt/kCK6NKHOg0JLH3u9Z5EGznsEuvJpMeF/ERFOA/4olS05EwZRx6Ek?= =?us-ascii?Q?axPImuLYgktTwFnS+vpT6Jff9M4gm0sIp6Hgu9tgvWryIVpOoyv4Invo1XiL?= =?us-ascii?Q?9Q=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: 30aa76c6-5db6-45c9-2220-08ddc560834e X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:06.9216 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ubfc7xZ1mFJzzVFyZ5qko0IbnlRngR8iO02ANKbV/fXmNON0nKhh9MhQEgZiJC+An5XTW5iuzVGXLqTzYUGRLTHXwl4jJWKGvU6M9P3jkZI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" Establish just enough emulated PCI infrastructure to register a sample TSM (platform security manager) driver and have it discover an IDE + TEE (link encryption + device-interface security protocol (TDISP)) capable device. Use the existing a CONFIG_PCI_BRIDGE_EMUL to emulate an IDE capable root port, and open code the emulation of an endpoint device via simulated configuration cycle responses. The devsec_tsm driver responds to the PCI core TSM operations as if it successfully exercised the given interface security protocol message. The devsec_bus and devsec_tsm drivers can be loaded in either order to reflect cases like SEV-TIO where the TSM is PCI-device firmware, and cases like TDX Connect where the TSM is a software agent running on the host CPU. Follow-on patches add common code for TSM managed IDE establishment. For now, just successfully complete setup and teardown of the DSM (device security manager) context as a building block for management of TDI (trusted device interface) instances. # modprobe devsec_bus devsec_bus devsec_bus: PCI host bridge to bus 10000:00 pci_bus 10000:00: root bus resource [bus 00-01] pci_bus 10000:00: root bus resource [mem 0xf000000000-0xffffffffff 64bi= t] pci 10000:00:00.0: [8086:7075] type 01 class 0x060400 PCIe Root Port pci 10000:00:00.0: PCI bridge to [bus 00] pci 10000:00:00.0: bridge window [io 0x0000-0x0fff] pci 10000:00:00.0: bridge window [mem 0x00000000-0x000fffff] pci 10000:00:00.0: bridge window [mem 0x00000000-0x000fffff 64bit pre= f] pci 10000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfig= uring pci 10000:01:00.0: [8086:ffff] type 00 class 0x000000 PCIe Endpoint pci 10000:01:00.0: BAR 0 [mem 0xf000000000-0xf0001fffff 64bit pref] pci_doe_abort: pci 10000:01:00.0: DOE: [100] Issuing Abort pci_doe_cache_protocols: pci 10000:01:00.0: DOE: [100] Found protocol 0= vid: 1 prot: 1 pci 10000:01:00.0: disabling ASPM on pre-1.1 PCIe device. You can enab= le it with 'pcie_aspm=3Dforce' pci 10000:00:00.0: PCI bridge to [bus 01] pci_bus 10000:01: busn_res: [bus 01] end is updated to 01 # modprobe devsec_tsm devsec_tsm_pci_probe: pci 10000:01:00.0: devsec: tsm enabled __pci_tsm_init: pci 10000:01:00.0: TSM: Device security capabilities de= tected ( ide tee ), TSM attach Cc: Bjorn Helgaas Cc: Lukas Wunner Cc: Samuel Ortiz Cc: Alexey Kardashevskiy Cc: Xu Yilun Signed-off-by: Dan Williams --- MAINTAINERS | 1 + samples/Kconfig | 16 + samples/Makefile | 1 + samples/devsec/Makefile | 10 + samples/devsec/bus.c | 708 ++++++++++++++++++++++++++++++++++++++++ samples/devsec/common.c | 26 ++ samples/devsec/devsec.h | 40 +++ samples/devsec/tsm.c | 173 ++++++++++ 8 files changed, 975 insertions(+) create mode 100644 samples/devsec/Makefile create mode 100644 samples/devsec/bus.c create mode 100644 samples/devsec/common.c create mode 100644 samples/devsec/devsec.h create mode 100644 samples/devsec/tsm.c diff --git a/MAINTAINERS b/MAINTAINERS index 8cb7ee9270d2..97494511da0c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25251,6 +25251,7 @@ F: Documentation/driver-api/pci/tsm.rst F: drivers/pci/tsm.c F: drivers/virt/coco/guest/ F: include/linux/*tsm*.h +F: samples/devsec/ F: samples/tsm-mr/ =20 TRUSTED SERVICES TEE DRIVER diff --git a/samples/Kconfig b/samples/Kconfig index ffef99950206..8441593fb654 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -325,6 +325,22 @@ source "samples/rust/Kconfig" =20 source "samples/damon/Kconfig" =20 +config SAMPLE_DEVSEC + tristate "Build a sample TEE Security Manager with an emulated PCI endpoi= nt" + depends on PCI + depends on VIRT_DRIVERS + depends on PCI_DOMAINS_GENERIC || X86 + select PCI_BRIDGE_EMUL + select PCI_TSM + select TSM + help + Build a sample platform TEE Security Manager (TSM) driver with a + corresponding emulated PCIe topology. The resulting sample modules, + devsec_bus and devsec_tsm, exercise device-security enumeration, PCI + subsystem use ABIs, device security flows. For example, exercise IDE + (link encryption) establishment and TDISP state transitions via a + Device Security Manager (DSM). + endif # SAMPLES =20 config HAVE_SAMPLE_FTRACE_DIRECT diff --git a/samples/Makefile b/samples/Makefile index 07641e177bd8..59b510ace9b2 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -45,3 +45,4 @@ obj-$(CONFIG_SAMPLE_DAMON_PRCL) +=3D damon/ obj-$(CONFIG_SAMPLE_DAMON_MTIER) +=3D damon/ obj-$(CONFIG_SAMPLE_HUNG_TASK) +=3D hung_task/ obj-$(CONFIG_SAMPLE_TSM_MR) +=3D tsm-mr/ +obj-y +=3D devsec/ diff --git a/samples/devsec/Makefile b/samples/devsec/Makefile new file mode 100644 index 000000000000..c8cb5c0cceb8 --- /dev/null +++ b/samples/devsec/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SAMPLE_DEVSEC) +=3D devsec_common.o +devsec_common-y :=3D common.o + +obj-$(CONFIG_SAMPLE_DEVSEC) +=3D devsec_bus.o +devsec_bus-y :=3D bus.o + +obj-$(CONFIG_SAMPLE_DEVSEC) +=3D devsec_tsm.o +devsec_tsm-y :=3D tsm.o diff --git a/samples/devsec/bus.c b/samples/devsec/bus.c new file mode 100644 index 000000000000..675e185fcf79 --- /dev/null +++ b/samples/devsec/bus.c @@ -0,0 +1,708 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright(c) 2024 - 2025 Intel Corporation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../drivers/pci/pci-bridge-emul.h" +#include "devsec.h" + +#define NR_DEVSEC_BUSES 1 +#define NR_DEVSEC_ROOT_PORTS 1 +#define NR_PORT_STREAMS 1 +#define NR_ADDR_ASSOC 1 +#define NR_DEVSEC_DEVS 1 + +struct devsec { + struct pci_host_bridge hb; + struct devsec_sysdata sysdata; + struct gen_pool *iomem_pool; + struct resource resource[2]; + struct pci_bus *bus; + struct device *dev; + struct devsec_port { + union { + struct devsec_ide { + u32 cap; + u32 ctl; + struct devsec_stream { + u32 cap; + u32 ctl; + u32 status; + u32 rid1; + u32 rid2; + struct devsec_addr_assoc { + u32 assoc1; + u32 assoc2; + u32 assoc3; + } assoc[NR_ADDR_ASSOC]; + } stream[NR_PORT_STREAMS]; + } ide __packed; + char ide_regs[sizeof(struct devsec_ide)]; + }; + struct pci_bridge_emul bridge; + } *devsec_ports[NR_DEVSEC_ROOT_PORTS]; + struct devsec_dev { + struct devsec *devsec; + struct range mmio_range; + u8 __cfg[SZ_4K]; + struct devsec_dev_doe { + int cap; + u32 req[SZ_4K / sizeof(u32)]; + u32 rsp[SZ_4K / sizeof(u32)]; + int write, read, read_ttl; + } doe; + u16 ide_pos; + union { + struct devsec_ide ide __packed; + char ide_regs[sizeof(struct devsec_ide)]; + }; + } *devsec_devs[NR_DEVSEC_DEVS]; +}; + +#define devsec_base(x) ((void __force __iomem *) &(x)->__cfg[0]) + +static struct devsec *bus_to_devsec(struct pci_bus *bus) +{ + return container_of(bus->sysdata, struct devsec, sysdata); +} + +static int devsec_dev_config_read(struct devsec *devsec, struct pci_bus *b= us, + unsigned int devfn, int pos, int size, + u32 *val) +{ + struct devsec_dev *devsec_dev; + struct devsec_dev_doe *doe; + void __iomem *base; + + if (PCI_FUNC(devfn) !=3D 0 || + PCI_SLOT(devfn) >=3D ARRAY_SIZE(devsec->devsec_devs)) + return PCIBIOS_DEVICE_NOT_FOUND; + + devsec_dev =3D devsec->devsec_devs[PCI_SLOT(devfn)]; + base =3D devsec_base(devsec_dev); + doe =3D &devsec_dev->doe; + + if (pos =3D=3D doe->cap + PCI_DOE_READ) { + if (doe->read_ttl > 0) { + *val =3D doe->rsp[doe->read]; + dev_dbg(&bus->dev, "devfn: %#x doe read[%d]\n", devfn, + doe->read); + } else { + *val =3D 0; + dev_dbg(&bus->dev, "devfn: %#x doe no data\n", devfn); + } + return PCIBIOS_SUCCESSFUL; + } else if (pos =3D=3D doe->cap + PCI_DOE_STATUS) { + if (doe->read_ttl > 0) { + *val =3D PCI_DOE_STATUS_DATA_OBJECT_READY; + dev_dbg(&bus->dev, "devfn: %#x object ready\n", devfn); + } else if (doe->read_ttl < 0) { + *val =3D PCI_DOE_STATUS_ERROR; + dev_dbg(&bus->dev, "devfn: %#x error\n", devfn); + } else { + *val =3D 0; + dev_dbg(&bus->dev, "devfn: %#x idle\n", devfn); + } + return PCIBIOS_SUCCESSFUL; + } else if (pos >=3D devsec_dev->ide_pos && + pos < devsec_dev->ide_pos + sizeof(struct devsec_ide)) { + *val =3D *(u32 *) &devsec_dev->ide_regs[pos - devsec_dev->ide_pos]; + return PCIBIOS_SUCCESSFUL; + } + + switch (size) { + case 1: + *val =3D readb(base + pos); + break; + case 2: + *val =3D readw(base + pos); + break; + case 4: + *val =3D readl(base + pos); + break; + default: + PCI_SET_ERROR_RESPONSE(val); + return PCIBIOS_BAD_REGISTER_NUMBER; + } + return PCIBIOS_SUCCESSFUL; +} + +static int devsec_port_config_read(struct devsec *devsec, unsigned int dev= fn, + int pos, int size, u32 *val) +{ + struct devsec_port *devsec_port; + + if (PCI_FUNC(devfn) !=3D 0 || + PCI_SLOT(devfn) >=3D ARRAY_SIZE(devsec->devsec_ports)) + return PCIBIOS_DEVICE_NOT_FOUND; + + devsec_port =3D devsec->devsec_ports[PCI_SLOT(devfn)]; + return pci_bridge_emul_conf_read(&devsec_port->bridge, pos, size, val); +} + +static int devsec_pci_read(struct pci_bus *bus, unsigned int devfn, int po= s, + int size, u32 *val) +{ + struct devsec *devsec =3D bus_to_devsec(bus); + + dev_vdbg(&bus->dev, "devfn: %#x pos: %#x size: %d\n", devfn, pos, size); + + if (bus =3D=3D devsec->hb.bus) + return devsec_port_config_read(devsec, devfn, pos, size, val); + else if (bus->parent =3D=3D devsec->hb.bus) + return devsec_dev_config_read(devsec, bus, devfn, pos, size, + val); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +#ifndef PCI_DOE_PROTOCOL_DISCOVERY +#define PCI_DOE_PROTOCOL_DISCOVERY 0 +#define PCI_DOE_FEATURE_CMA 1 +#endif + +/* just indicate support for CMA */ +static void doe_process(struct devsec_dev_doe *doe) +{ + u8 type; + u16 vid; + + vid =3D FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_1_VID, doe->req[0]); + type =3D FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_1_TYPE, doe->req[0]); + + if (vid !=3D PCI_VENDOR_ID_PCI_SIG) { + doe->read_ttl =3D -1; + return; + } + + if (type !=3D PCI_DOE_PROTOCOL_DISCOVERY) { + doe->read_ttl =3D -1; + return; + } + + doe->rsp[0] =3D doe->req[0]; + doe->rsp[1] =3D FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, 3); + doe->read_ttl =3D 3; + doe->rsp[2] =3D FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID, + PCI_VENDOR_ID_PCI_SIG) | + FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL, + PCI_DOE_FEATURE_CMA) | + FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX, 0); +} + +static int devsec_dev_config_write(struct devsec *devsec, struct pci_bus *= bus, + unsigned int devfn, int pos, int size, + u32 val) +{ + struct devsec_dev *devsec_dev; + struct devsec_dev_doe *doe; + struct devsec_ide *ide; + void __iomem *base; + + dev_vdbg(&bus->dev, "devfn: %#x pos: %#x size: %d\n", devfn, pos, size); + + if (PCI_FUNC(devfn) !=3D 0 || + PCI_SLOT(devfn) >=3D ARRAY_SIZE(devsec->devsec_devs)) + return PCIBIOS_DEVICE_NOT_FOUND; + + devsec_dev =3D devsec->devsec_devs[PCI_SLOT(devfn)]; + base =3D devsec_base(devsec_dev); + doe =3D &devsec_dev->doe; + ide =3D &devsec_dev->ide; + + if (pos >=3D PCI_BASE_ADDRESS_0 && pos <=3D PCI_BASE_ADDRESS_5) { + if (size !=3D 4) + return PCIBIOS_BAD_REGISTER_NUMBER; + /* only one 64-bit mmio bar emulated for now */ + if (pos =3D=3D PCI_BASE_ADDRESS_0) + val &=3D ~lower_32_bits(range_len(&devsec_dev->mmio_range) - 1); + else if (pos =3D=3D PCI_BASE_ADDRESS_1) + val &=3D ~upper_32_bits(range_len(&devsec_dev->mmio_range) - 1); + else + val =3D 0; + } else if (pos =3D=3D PCI_ROM_ADDRESS) { + val =3D 0; + } else if (pos =3D=3D doe->cap + PCI_DOE_CTRL) { + if (val & PCI_DOE_CTRL_GO) { + dev_dbg(&bus->dev, "devfn: %#x doe go\n", devfn); + doe_process(doe); + } + if (val & PCI_DOE_CTRL_ABORT) { + dev_dbg(&bus->dev, "devfn: %#x doe abort\n", devfn); + doe->write =3D 0; + doe->read =3D 0; + doe->read_ttl =3D 0; + } + return PCIBIOS_SUCCESSFUL; + } else if (pos =3D=3D doe->cap + PCI_DOE_WRITE) { + if (doe->write < ARRAY_SIZE(doe->req)) + doe->req[doe->write++] =3D val; + dev_dbg(&bus->dev, "devfn: %#x doe write[%d]\n", devfn, + doe->write - 1); + return PCIBIOS_SUCCESSFUL; + } else if (pos =3D=3D doe->cap + PCI_DOE_READ) { + if (doe->read_ttl > 0) { + doe->read_ttl--; + doe->read++; + dev_dbg(&bus->dev, "devfn: %#x doe ack[%d]\n", devfn, + doe->read - 1); + } + return PCIBIOS_SUCCESSFUL; + } else if (pos >=3D devsec_dev->ide_pos && + pos < devsec_dev->ide_pos + sizeof(struct devsec_ide)) { + u16 ide_off =3D pos - devsec_dev->ide_pos; + + for (int i =3D 0; i < NR_PORT_STREAMS; i++) { + struct devsec_stream *stream =3D &ide->stream[i]; + + if (ide_off !=3D offsetof(typeof(*ide), stream[i].ctl)) + continue; + + stream->ctl =3D val; + stream->status &=3D ~PCI_IDE_SEL_STS_STATE_MASK; + if (val & PCI_IDE_SEL_CTL_EN) + stream->status |=3D FIELD_PREP( + PCI_IDE_SEL_STS_STATE_MASK, + PCI_IDE_SEL_STS_STATE_SECURE); + else + stream->status |=3D FIELD_PREP( + PCI_IDE_SEL_STS_STATE_MASK, + PCI_IDE_SEL_STS_STATE_INSECURE); + return PCIBIOS_SUCCESSFUL; + } + } + + switch (size) { + case 1: + writeb(val, base + pos); + break; + case 2: + writew(val, base + pos); + break; + case 4: + writel(val, base + pos); + break; + default: + return PCIBIOS_BAD_REGISTER_NUMBER; + } + return PCIBIOS_SUCCESSFUL; +} + +static int devsec_port_config_write(struct devsec *devsec, struct pci_bus = *bus, + unsigned int devfn, int pos, int size, + u32 val) +{ + struct devsec_port *devsec_port; + + dev_vdbg(&bus->dev, "devfn: %#x pos: %#x size: %d\n", devfn, pos, size); + + if (PCI_FUNC(devfn) !=3D 0 || + PCI_SLOT(devfn) >=3D ARRAY_SIZE(devsec->devsec_ports)) + return PCIBIOS_DEVICE_NOT_FOUND; + + devsec_port =3D devsec->devsec_ports[PCI_SLOT(devfn)]; + return pci_bridge_emul_conf_write(&devsec_port->bridge, pos, size, val); +} + +static int devsec_pci_write(struct pci_bus *bus, unsigned int devfn, int p= os, + int size, u32 val) +{ + struct devsec *devsec =3D bus_to_devsec(bus); + + dev_vdbg(&bus->dev, "devfn: %#x pos: %#x size: %d\n", devfn, pos, size); + + if (bus =3D=3D devsec->hb.bus) + return devsec_port_config_write(devsec, bus, devfn, pos, size, + val); + else if (bus->parent =3D=3D devsec->hb.bus) + return devsec_dev_config_write(devsec, bus, devfn, pos, size, + val); + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static struct pci_ops devsec_ops =3D { + .read =3D devsec_pci_read, + .write =3D devsec_pci_write, +}; + +static void destroy_bus(void *data) +{ + struct pci_host_bridge *hb =3D data; + + pci_stop_root_bus(hb->bus); + pci_remove_root_bus(hb->bus); +} + +static u32 build_ext_cap_header(u32 id, u32 ver, u32 next) +{ + return FIELD_PREP(GENMASK(15, 0), id) | + FIELD_PREP(GENMASK(19, 16), ver) | + FIELD_PREP(GENMASK(31, 20), next); +} + +static void init_ide(struct devsec_ide *ide) +{ + ide->cap =3D PCI_IDE_CAP_SELECTIVE | PCI_IDE_CAP_IDE_KM | + PCI_IDE_CAP_TEE_LIMITED | + FIELD_PREP(PCI_IDE_CAP_SEL_NUM_MASK, NR_PORT_STREAMS - 1); + + for (int i =3D 0; i < NR_PORT_STREAMS; i++) + ide->stream[i].cap =3D + FIELD_PREP(PCI_IDE_SEL_CAP_ASSOC_NUM_MASK, NR_ADDR_ASSOC); +} + +static void init_dev_cfg(struct devsec_dev *devsec_dev) +{ + void __iomem *base =3D devsec_base(devsec_dev), *cap_base; + int pos, next; + + /* BAR space */ + writew(0x8086, base + PCI_VENDOR_ID); + writew(0xffff, base + PCI_DEVICE_ID); + writel(lower_32_bits(devsec_dev->mmio_range.start) | + PCI_BASE_ADDRESS_MEM_TYPE_64 | + PCI_BASE_ADDRESS_MEM_PREFETCH, + base + PCI_BASE_ADDRESS_0); + writel(upper_32_bits(devsec_dev->mmio_range.start), + base + PCI_BASE_ADDRESS_1); + + /* Capability init */ + writeb(PCI_HEADER_TYPE_NORMAL, base + PCI_HEADER_TYPE); + writew(PCI_STATUS_CAP_LIST, base + PCI_STATUS); + pos =3D 0x40; + writew(pos, base + PCI_CAPABILITY_LIST); + + /* PCI-E Capability */ + cap_base =3D base + pos; + writeb(PCI_CAP_ID_EXP, cap_base); + writew(PCI_EXP_TYPE_ENDPOINT, cap_base + PCI_EXP_FLAGS); + writew(PCI_EXP_LNKSTA_CLS_2_5GB | PCI_EXP_LNKSTA_NLW_X1, cap_base + PCI_E= XP_LNKSTA); + writel(PCI_EXP_DEVCAP_FLR | PCI_EXP_DEVCAP_TEE, cap_base + PCI_EXP_DEVCAP= ); + + /* DOE Extended Capability */ + pos =3D PCI_CFG_SPACE_SIZE; + next =3D pos + PCI_DOE_CAP_SIZEOF; + cap_base =3D base + pos; + devsec_dev->doe.cap =3D pos; + writel(build_ext_cap_header(PCI_EXT_CAP_ID_DOE, 2, next), cap_base); + + /* IDE Extended Capability */ + pos =3D next; + cap_base =3D base + pos; + writel(build_ext_cap_header(PCI_EXT_CAP_ID_IDE, 1, 0), cap_base); + devsec_dev->ide_pos =3D pos + 4; + init_ide(&devsec_dev->ide); +} + +#define MMIO_SIZE SZ_2M + +static void destroy_devsec_dev(void *data) +{ + struct devsec_dev *devsec_dev =3D data; + struct devsec *devsec =3D devsec_dev->devsec; + + gen_pool_free(devsec->iomem_pool, devsec_dev->mmio_range.start, + range_len(&devsec_dev->mmio_range)); + kfree(devsec_dev); +} + +static struct devsec_dev *devsec_dev_alloc(struct devsec *devsec) +{ + struct devsec_dev *devsec_dev __free(kfree) =3D + kzalloc(sizeof(*devsec_dev), GFP_KERNEL); + struct genpool_data_align data =3D { + .align =3D MMIO_SIZE, + }; + u64 phys; + + if (!devsec_dev) + return ERR_PTR(-ENOMEM); + + phys =3D gen_pool_alloc_algo(devsec->iomem_pool, MMIO_SIZE, + gen_pool_first_fit_align, &data); + if (!phys) + return ERR_PTR(-ENOMEM); + + *devsec_dev =3D (struct devsec_dev) { + .mmio_range =3D { + .start =3D phys, + .end =3D phys + MMIO_SIZE - 1, + }, + .devsec =3D devsec, + }; + init_dev_cfg(devsec_dev); + + return_ptr(devsec_dev); +} + +static int alloc_devs(struct devsec *devsec) +{ + struct device *dev =3D devsec->dev; + + for (int i =3D 0; i < ARRAY_SIZE(devsec->devsec_devs); i++) { + struct devsec_dev *devsec_dev =3D devsec_dev_alloc(devsec); + int rc; + + if (IS_ERR(devsec_dev)) + return PTR_ERR(devsec_dev); + rc =3D devm_add_action_or_reset(dev, destroy_devsec_dev, + devsec_dev); + if (rc) + return rc; + devsec->devsec_devs[i] =3D devsec_dev; + } + + return 0; +} + +static pci_bridge_emul_read_status_t +devsec_bridge_read_base(struct pci_bridge_emul *bridge, int pos, u32 *val) +{ + return PCI_BRIDGE_EMUL_NOT_HANDLED; +} + +static pci_bridge_emul_read_status_t +devsec_bridge_read_pcie(struct pci_bridge_emul *bridge, int pos, u32 *val) +{ + return PCI_BRIDGE_EMUL_NOT_HANDLED; +} + +static pci_bridge_emul_read_status_t +devsec_bridge_read_ext(struct pci_bridge_emul *bridge, int pos, u32 *val) +{ + struct devsec_port *devsec_port =3D bridge->data; + + /* only one extended capability, IDE... */ + if (pos =3D=3D 0) { + *val =3D build_ext_cap_header(PCI_EXT_CAP_ID_IDE, 1, 0); + return PCI_BRIDGE_EMUL_HANDLED; + } + + if (pos < 4) + return PCI_BRIDGE_EMUL_NOT_HANDLED; + + pos -=3D 4; + if (pos < sizeof(struct devsec_ide)) { + *val =3D *(u32 *)(&devsec_port->ide_regs[pos]); + return PCI_BRIDGE_EMUL_HANDLED; + } + + return PCI_BRIDGE_EMUL_NOT_HANDLED; +} + +static void devsec_bridge_write_base(struct pci_bridge_emul *bridge, int p= os, + u32 old, u32 new, u32 mask) +{ +} + +static void devsec_bridge_write_pcie(struct pci_bridge_emul *bridge, int p= os, + u32 old, u32 new, u32 mask) +{ +} + +static void devsec_bridge_write_ext(struct pci_bridge_emul *bridge, int po= s, + u32 old, u32 new, u32 mask) +{ + struct devsec_port *devsec_port =3D bridge->data; + + if (pos < sizeof(struct devsec_ide)) + *(u32 *)(&devsec_port->ide_regs[pos]) =3D new; +} + +static const struct pci_bridge_emul_ops devsec_bridge_ops =3D { + .read_base =3D devsec_bridge_read_base, + .write_base =3D devsec_bridge_write_base, + .read_pcie =3D devsec_bridge_read_pcie, + .write_pcie =3D devsec_bridge_write_pcie, + .read_ext =3D devsec_bridge_read_ext, + .write_ext =3D devsec_bridge_write_ext, +}; + +static int init_port(struct devsec_port *devsec_port) +{ + struct pci_bridge_emul *bridge =3D &devsec_port->bridge; + + *bridge =3D (struct pci_bridge_emul) { + .conf =3D { + .vendor =3D cpu_to_le16(0x8086), + .device =3D cpu_to_le16(0x7075), + .class_revision =3D cpu_to_le32(0x1), + .pref_mem_base =3D cpu_to_le16(PCI_PREF_RANGE_TYPE_64), + .pref_mem_limit =3D cpu_to_le16(PCI_PREF_RANGE_TYPE_64), + }, + .pcie_conf =3D { + .devcap =3D cpu_to_le16(PCI_EXP_DEVCAP_FLR), + .lnksta =3D cpu_to_le16(PCI_EXP_LNKSTA_CLS_2_5GB), + }, + .subsystem_vendor_id =3D cpu_to_le16(0x8086), + .has_pcie =3D true, + .data =3D devsec_port, + .ops =3D &devsec_bridge_ops, + }; + + init_ide(&devsec_port->ide); + + return pci_bridge_emul_init(bridge, 0); +} + +static void destroy_port(void *data) +{ + struct devsec_port *devsec_port =3D data; + + pci_bridge_emul_cleanup(&devsec_port->bridge); + kfree(devsec_port); +} + +static struct devsec_port *devsec_port_alloc(void) +{ + int rc; + + struct devsec_port *devsec_port __free(kfree) =3D + kzalloc(sizeof(*devsec_port), GFP_KERNEL); + + if (!devsec_port) + return ERR_PTR(-ENOMEM); + + rc =3D init_port(devsec_port); + if (rc) + return ERR_PTR(rc); + + return_ptr(devsec_port); +} + +static int alloc_ports(struct devsec *devsec) +{ + struct device *dev =3D devsec->dev; + + for (int i =3D 0; i < ARRAY_SIZE(devsec->devsec_ports); i++) { + struct devsec_port *devsec_port =3D devsec_port_alloc(); + int rc; + + if (IS_ERR(devsec_port)) + return PTR_ERR(devsec_port); + rc =3D devm_add_action_or_reset(dev, destroy_port, devsec_port); + if (rc) + return rc; + devsec->devsec_ports[i] =3D devsec_port; + } + + return 0; +} + +static int __init devsec_bus_probe(struct platform_device *pdev) +{ + int rc; + struct devsec *devsec; + u64 mmio_size =3D SZ_64G; + struct devsec_sysdata *sd; + struct pci_host_bridge *hb; + struct device *dev =3D &pdev->dev; + u64 mmio_start =3D iomem_resource.end + 1 - SZ_64G; + + hb =3D devm_pci_alloc_host_bridge( + dev, sizeof(*devsec) - sizeof(struct pci_host_bridge)); + if (!hb) + return -ENOMEM; + + devsec =3D container_of(hb, struct devsec, hb); + devsec->dev =3D dev; + devsec->iomem_pool =3D devm_gen_pool_create(dev, ilog2(SZ_2M), + NUMA_NO_NODE, "devsec iomem"); + if (!devsec->iomem_pool) + return -ENOMEM; + + rc =3D gen_pool_add(devsec->iomem_pool, mmio_start, mmio_size, + NUMA_NO_NODE); + if (rc) + return rc; + + rc =3D alloc_ports(devsec); + if (rc) + return rc; + + rc =3D alloc_devs(devsec); + if (rc) + return rc; + + devsec->resource[0] =3D (struct resource) { + .name =3D "DEVSEC BUSES", + .start =3D 0, + .end =3D NR_DEVSEC_BUSES + NR_DEVSEC_ROOT_PORTS - 1, + .flags =3D IORESOURCE_BUS | IORESOURCE_PCI_FIXED, + }; + pci_add_resource(&hb->windows, &devsec->resource[0]); + + devsec->resource[1] =3D (struct resource) { + .name =3D "DEVSEC MMIO", + .start =3D mmio_start, + .end =3D mmio_start + mmio_size - 1, + .flags =3D IORESOURCE_MEM | IORESOURCE_MEM_64, + }; + pci_add_resource(&hb->windows, &devsec->resource[1]); + + sd =3D &devsec->sysdata; + devsec_sysdata =3D sd; + hb->domain_nr =3D pci_bus_find_emul_domain_nr(PCI_DOMAIN_NR_NOT_SET); + if (hb->domain_nr < 0) + return hb->domain_nr; + + /* + * Note, domain_nr is set in devsec_sysdata for + * !CONFIG_PCI_DOMAINS_GENERIC platforms + */ + devsec_set_domain_nr(sd, hb->domain_nr); + + hb->dev.parent =3D dev; + hb->sysdata =3D sd; + hb->ops =3D &devsec_ops; + + rc =3D pci_scan_root_bus_bridge(hb); + if (rc) + return rc; + + return devm_add_action_or_reset(dev, destroy_bus, no_free_ptr(hb)); +} + +static struct platform_driver devsec_bus_driver =3D { + .driver =3D { + .name =3D "devsec_bus", + }, +}; + +static struct platform_device *devsec_bus; + +static int __init devsec_bus_init(void) +{ + struct platform_device_info devsec_bus_info =3D { + .name =3D "devsec_bus", + .id =3D -1, + }; + int rc; + + devsec_bus =3D platform_device_register_full(&devsec_bus_info); + if (IS_ERR(devsec_bus)) + return PTR_ERR(devsec_bus); + + rc =3D platform_driver_probe(&devsec_bus_driver, devsec_bus_probe); + if (rc) + platform_device_unregister(devsec_bus); + return 0; +} +module_init(devsec_bus_init); + +static void __exit devsec_bus_exit(void) +{ + platform_driver_unregister(&devsec_bus_driver); + platform_device_unregister(devsec_bus); +} +module_exit(devsec_bus_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Device Security Sample Infrastructure: TDISP Device Em= ulation"); diff --git a/samples/devsec/common.c b/samples/devsec/common.c new file mode 100644 index 000000000000..de0078e4d614 --- /dev/null +++ b/samples/devsec/common.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright(c) 2024 - 2025 Intel Corporation. All rights reserved. + +#include +#include + +/* + * devsec_bus and devsec_tsm need a common location for this data to + * avoid depending on each other. Enables load order testing + */ +struct pci_sysdata *devsec_sysdata; +EXPORT_SYMBOL_GPL(devsec_sysdata); + +static int __init common_init(void) +{ + return 0; +} +module_init(common_init); + +static void __exit common_exit(void) +{ +} +module_exit(common_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Device Security Sample Infrastructure: Shared data"); diff --git a/samples/devsec/devsec.h b/samples/devsec/devsec.h new file mode 100644 index 000000000000..ae4274c86244 --- /dev/null +++ b/samples/devsec/devsec.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +// Copyright(c) 2024 - 2025 Intel Corporation. All rights reserved. + +#ifndef __DEVSEC_H__ +#define __DEVSEC_H__ +struct devsec_sysdata { +#ifdef CONFIG_X86 + /* + * Must be first member to that x86::pci_domain_nr() can type + * pun devsec_sysdata and pci_sysdata. + */ + struct pci_sysdata sd; +#else + int domain_nr; +#endif +}; + +#ifdef CONFIG_X86 +static inline void devsec_set_domain_nr(struct devsec_sysdata *sd, + int domain_nr) +{ + sd->sd.domain =3D domain_nr; +} +static inline int devsec_get_domain_nr(struct devsec_sysdata *sd) +{ + return sd->sd.domain; +} +#else +static inline void devsec_set_domain_nr(struct devsec_sysdata *sd, + int domain_nr) +{ + sd->domain_nr =3D domain_nr; +} +static inline int devsec_get_domain_nr(struct devsec_sysdata *sd) +{ + return sd->domain_nr; +} +#endif +extern struct devsec_sysdata *devsec_sysdata; +#endif /* __DEVSEC_H__ */ diff --git a/samples/devsec/tsm.c b/samples/devsec/tsm.c new file mode 100644 index 000000000000..a4705212a7e4 --- /dev/null +++ b/samples/devsec/tsm.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2024 - 2025 Intel Corporation. All rights reserved. */ + +#define dev_fmt(fmt) "devsec: " fmt +#include +#include +#include +#include +#include +#include "devsec.h" + +struct devsec_tsm_pf0 { + struct pci_tsm_pf0 pci; +#define NR_TSM_STREAMS 4 +}; + +struct devsec_tsm_fn { + struct pci_tsm pci; +}; + +static struct devsec_tsm_pf0 *to_devsec_tsm_pf0(struct pci_tsm *tsm) +{ + return container_of(tsm, struct devsec_tsm_pf0, pci.tsm); +} + +static struct devsec_tsm_fn *to_devsec_tsm_fn(struct pci_tsm *tsm) +{ + return container_of(tsm, struct devsec_tsm_fn, pci); +} + +static const struct pci_tsm_ops *__devsec_pci_ops; + +static struct pci_tsm *devsec_tsm_pf0_probe(struct pci_dev *pdev) +{ + int rc; + + struct devsec_tsm_pf0 *devsec_tsm __free(kfree) =3D + kzalloc(sizeof(*devsec_tsm), GFP_KERNEL); + if (!devsec_tsm) + return NULL; + + rc =3D pci_tsm_pf0_constructor(pdev, &devsec_tsm->pci, __devsec_pci_ops); + if (rc) + return NULL; + + pci_dbg(pdev, "tsm enabled\n"); + return &no_free_ptr(devsec_tsm)->pci.tsm; +} + +static struct pci_tsm *devsec_tsm_fn_probe(struct pci_dev *pdev) +{ + int rc; + + struct devsec_tsm_fn *devsec_tsm __free(kfree) =3D + kzalloc(sizeof(*devsec_tsm), GFP_KERNEL); + if (!devsec_tsm) + return NULL; + + rc =3D pci_tsm_constructor(pdev, &devsec_tsm->pci, __devsec_pci_ops); + if (rc) + return NULL; + + pci_dbg(pdev, "tsm (sub-function) enabled\n"); + return &no_free_ptr(devsec_tsm)->pci; +} + +static struct pci_tsm *devsec_tsm_pci_probe(struct pci_dev *pdev) +{ + if (pdev->sysdata !=3D devsec_sysdata) + return NULL; + + if (is_pci_tsm_pf0(pdev)) + return devsec_tsm_pf0_probe(pdev); + return devsec_tsm_fn_probe(pdev); +} + +static void devsec_tsm_pci_remove(struct pci_tsm *tsm) +{ + struct pci_dev *pdev =3D tsm->pdev; + + pci_dbg(pdev, "tsm disabled\n"); + + if (is_pci_tsm_pf0(pdev)) { + struct devsec_tsm_pf0 *devsec_tsm =3D to_devsec_tsm_pf0(tsm); + + pci_tsm_pf0_destructor(&devsec_tsm->pci); + kfree(devsec_tsm); + } else { + struct devsec_tsm_fn *devsec_tsm =3D to_devsec_tsm_fn(tsm); + + kfree(devsec_tsm); + } +} + +/* + * Reference consumer for a TSM driver "connect" operation callback. The + * low-level TSM driver understands details about the platform the PCI + * core does not, like number of available streams that can be + * established per host bridge. The expected flow is: + * + * 1/ Allocate platform specific Stream resource (TSM specific) + * 2/ Allocate Stream Ids in the endpoint and Root Port (PCI TSM helper) + * 3/ Register Stream Ids for the consumed resources from the last 2 + * steps to be accountable (via sysfs) to the admin (PCI TSM helper) + * 4/ Register the Stream with the TSM core so that either PCI sysfs or + * TSM core sysfs can list the in-use resources (TSM core helper) + * 5/ Configure IDE settings in the endpoint and Root Port (PCI TSM helper) + * 6/ RPC call to TSM to perform IDE_KM and optionally enable the stream + * (TSM Specific) + * 7/ Enable the stream in the endpoint, and root port if TSM call did + * not already handle that (PCI TSM helper) + * + * The expectation is the helpers referenceed are convenience "library" + * APIs for common operations, not a "midlayer" that enforces a specific + * or use model sequencing. + */ +static int devsec_tsm_connect(struct pci_dev *pdev) +{ + return -ENXIO; +} + +static void devsec_tsm_disconnect(struct pci_dev *pdev) +{ +} + +static struct pci_tsm_ops devsec_pci_ops =3D { + .probe =3D devsec_tsm_pci_probe, + .remove =3D devsec_tsm_pci_remove, + .connect =3D devsec_tsm_connect, + .disconnect =3D devsec_tsm_disconnect, +}; + +static void devsec_tsm_remove(void *tsm_dev) +{ + tsm_unregister(tsm_dev); +} + +static int devsec_tsm_probe(struct faux_device *fdev) +{ + struct tsm_dev *tsm_dev; + + tsm_dev =3D tsm_register(&fdev->dev, NULL, &devsec_pci_ops); + if (IS_ERR(tsm_dev)) + return PTR_ERR(tsm_dev); + + return devm_add_action_or_reset(&fdev->dev, devsec_tsm_remove, + tsm_dev); +} + +static struct faux_device *devsec_tsm; + +static const struct faux_device_ops devsec_device_ops =3D { + .probe =3D devsec_tsm_probe, +}; + +static int __init devsec_tsm_init(void) +{ + __devsec_pci_ops =3D &devsec_pci_ops; + devsec_tsm =3D faux_device_create("devsec_tsm", NULL, &devsec_device_ops); + if (!devsec_tsm) + return -ENOMEM; + return 0; +} +module_init(devsec_tsm_init); + +static void __exit devsec_tsm_exit(void) +{ + faux_device_destroy(devsec_tsm); +} +module_exit(devsec_tsm_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Device Security Sample Infrastructure: Platform TSM Dr= iver"); --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 BF8C72116E7; Thu, 17 Jul 2025 18:34:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777259; cv=fail; b=fjY7XMO2gzCNqrRZBPViV7uBo6DIrUfjR1rcLBsGinxRGzN7VRYE0D5hdA4EEmXCQdxJbqYZymJlzkCfglLgNnZ+9uIegIiP/G1CyPJ5Knjs9vg98nX8vAV+8tXmcYodZtIJZRcAfOO0gh8pmN/VSHA+nwEJOpPzO3a+DiF8pRY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777259; c=relaxed/simple; bh=trR2GOy/pmhq4mHhUyJWH4mxBtOMyY6ruUdG839o0wk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=FRx/D6q+f1y02uLNswmpeBBYQq+R81SgVlFouB5Jxa5gsBIFo6kwAFmGL+8zSOzd4FS4f51nX0DK6oCrtu4pAXqv3nC+puPlECjfqwPv5v6fFkrJYOU6PjwhNvJBxyPtUylPWFfnKKnALU4+RZqcDH0HgvXWS098+0tE0F+sVgg= ARC-Authentication-Results: i=2; 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=ih4iq7ES; arc=fail smtp.client-ip=198.175.65.19 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="ih4iq7ES" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777258; x=1784313258; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=trR2GOy/pmhq4mHhUyJWH4mxBtOMyY6ruUdG839o0wk=; b=ih4iq7ESkxfaHVtIKw0kkAFhzAYKiHtQN8Xs/rcQlIWet/OSfQnImr9E PO/vt7LWa9GVgCpZX7wTza2U9rdFeiZyYBtC3rjHK+7ft3Mdle90F6d0m dcPx9Xjfm28CaG3RY3UuaINGhxYnLjtm/+J4SfCh26SvBfTZA1AYZ+f5/ mJ6TNHk5JHzPw6QS8PHafyZLJ/Hp6VlXvDuaXCFXDmzqidKpxQvWvrY2y moiZA/u2CmP0H7ZvAji5GnJ+qeziPOsy0/65RkdOc8j7kenxQhrHZ9KE7 uPbLGnA5od6mzBSQZpAVYNPApWRCyqIU42VSTBs72ggD7PkQEdy/ZE+u+ w==; X-CSE-ConnectionGUID: eEtQWxA3QeCUVuLM+jYpTg== X-CSE-MsgGUID: Pm8+Ff+LROWUYtXQNSsGww== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924077" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924077" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:14 -0700 X-CSE-ConnectionGUID: uDHajVnsSxKPSqEFOFMzOg== X-CSE-MsgGUID: dI6HiZASSOOxHHUWefDNcQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254626" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:14 -0700 Received: from ORSMSX903.amr.corp.intel.com (10.22.229.25) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:13 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:13 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:13 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=H+5/IEWrQyFwUSfe+CY+I9P3X2AMhOAys8EXDmvKwzbwSiKygnWZo3QUVecSZB/PDz+l5KJKebu+pD6AIy9UAa3FzLXjWA5YC8JzRjCA3To3mxH+TbwfxuFyu6/gArVBswGfKd4UWSERPt86MvpR6ayja6hssGCZuLSrYQO+Fl4z12fmsVRxPJJM67XMvCEKRq1tSILsVlCnjgUzI+VCTiWQTwxSv5LHT3gLMEICgNAozcIP4IuCDkejCpofPNGHPXjET6Tro3RXiVTvdAJL3LVzn4g7RGkEdx8KY5aEMWaJrcymbkpeFsR0aLrU+0iDImJ6aSiETOuMASX6/z+18Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OpsU/aPLBls6dfV/Q9e9bz0DU7CQmn1Y1fldfyfQCsI=; b=p2fj9GkvI9WKzYYLF1jCZXG5qBIZIaAWrQQarZetbkg/miIbtyKCPp8W/sPeSEoofGgXVJHgUbmw2OJjoZKSBOOp9QAJpLYmWj3YMbxj6hcCpykAqc9WK4V4EHg6ohvnGjq3sLbsUmTT+1mfuspHq9/bOT/c51ASlH2Ej/XF5l8QVoB99rsp9bq3rthi6v0PXTOfO/l+r/hExKzWoq5yQF6oZoGwWCyzWIeDfa8Ots48cjOMDae6ayxCN7HzSpFFP3pSW7+9ngl9Z/j7c/uvaiQDw5dl/2g/WGdcrCM8a8Rog+Eidysb5JjZZItAFfizBhv3GWlUNXHzGP5RtovgCw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:07 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:07 +0000 From: Dan Williams To: , CC: , , , , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Samuel Ortiz , Xu Yilun Subject: [PATCH v4 06/10] PCI: Add PCIe Device 3 Extended Capability enumeration Date: Thu, 17 Jul 2025 11:33:54 -0700 Message-ID: <20250717183358.1332417-7-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: 1980d680-2877-4661-55bc-08ddc56083e8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?utf-8?B?Yk42OFc2ai9iTVVVNWVBNFBZNXI1KzhJbEdhYWhuN003RnhIWjVvZXdrVSt1?= =?utf-8?B?bGpaWTlDOTQ0TStqRk93bTlCM2YyN2N6UHdjMTN2c0pka1g5aGlybGE5bHp0?= =?utf-8?B?T3k3eXJBOVp5RDd5TkI5MGQ1c0dXekVwN2JRbTNLdFRpZzRjRjhaT01RVmRz?= =?utf-8?B?enRmdUUzQjRMN1lrek8vZTRFVzZoek95bDVFeHpaOGhFejI1bU5GSU5id1dL?= =?utf-8?B?bHhneHJTWllnYnZNT0xzemVGVEszUC9pVnZaNU9Bc1Z1ZlZFQ0xROE1BZnU2?= =?utf-8?B?SGJYTVRhMTgwSmJoOWhJOHcvVm9vNS9BK1pOZXlGbEUvRkVvSEtKMDByMmlV?= =?utf-8?B?S21lclB3eHFZRmNZT0pwRHUrWDUzZTNmUUtWV0ZzRjF4aFlXR2U3QTRhSTIw?= =?utf-8?B?UmFQWmxDREpDOU5pakFDNThRTng4RHhtQnk0V0JnMmMxQlZXZmtnQTY5c3lv?= =?utf-8?B?d29HOEJIUllQY2ExZjlDUDBtRDlXMkN3aTdwckFacnc4Vm9Eb3RSM3lxOWMr?= =?utf-8?B?Tm1VMDVvbE96eDN2bGdMdUwyelV4MytxSGRIY0hCWWppQkM2VE1LOUt3Qkow?= =?utf-8?B?SS90MHBJMWROejFKN01WSGIvMVNITGhycmxEamE5VlRQQStOZ3dTL1lhN3cw?= =?utf-8?B?dytTOHRFS1hGcVVMNjN6cUI4UzZZYXIyYU5qNHJmZ1R5NHFiME1FeVNIZE96?= =?utf-8?B?cVdpUFd5NHpvczJvM0lSeENidWxOWGswRkpCQVhvOFZITXowblZhS3ZtTURj?= =?utf-8?B?djFFdzR0MTVoN3FTOTlMUlRBK1pkdUtLNGlpcDRIcFZoanQ5a0RhMXpnOHh2?= =?utf-8?B?YUdlZDZ0anJ4c3FhWGtmaDl3ZUFxZ2hLOHc4VUVvT1lock54T3RLOEZsWW5x?= =?utf-8?B?YWNnSUJFd0wvbTU4RjJwWUF0WWd5MXpTWjhrWUJML01sZVM2RUlWaDdJS2JL?= =?utf-8?B?SjUwQlpDYi9XRkVXZHZUclk3SkVtQUl0aW5WTTNMMnFtc3VsOExzdXR3M054?= =?utf-8?B?UkhRTS9pZ050Nll5R3plQTNvV09vMEo2MTJWTktFUVNnenJsM3VUSFJ3djB4?= =?utf-8?B?VnlpYXh5elNEL1ptTHJLbUlvOTNmMEM1QTlpSDEvRjE3T3N0Zm1HcDJHVWth?= =?utf-8?B?R1FYS3ZPNnRidDlIR1MyWld2K1RtZHZtSC80aWlocXFrMlhsdGRzZnRFS1ZL?= =?utf-8?B?SUtQSnloSWF2NWZQMUp6UnIrbVFNaFJQazhZY2pPUFo1UnAzNGt4d2tRVlBB?= =?utf-8?B?RDlDL2huMmFtOVBpQkNGeUFPc3NNNUZZUk9qalByV1lYb05zUExEZWNaK0Zj?= =?utf-8?B?UVRnUzRVTjFTNnQwaVVqY1lzNXJwUjBLV2lGT29kSEhCNC9nWkdBRk9JVWVE?= =?utf-8?B?bUdNamlYQXRjdUdrUHFPUWN6Z0U1Rzk1RFRQcDNLVWFWaXZQSVpJb1JsSWRr?= =?utf-8?B?V1lBTGwrYXR4ZHQvd0wzYlFKMHRpelJlaCtXUWZoRTdPZDVWOHJiZ1VLODJ4?= =?utf-8?B?cEQ2QVIzSTZPanplOFpwREU4ZHJSNVVhbmw3K29FdXhhd3FYbHpwMnlxQWpS?= =?utf-8?B?QkpQVEJueWdlTVgzb2NjQjhadnc4WGczU0RNZ2ZGNHRibXhSb09FeXU3c0lK?= =?utf-8?B?U29NTGxCVVplWHRJKzJGWEt6SVEzTlpCTWY5ek5VV0xTWUhvd3JRS05QbnRz?= =?utf-8?B?U3IvbnFoZVVHVnZWTmd0TkpKN0VhOThqY1ZnaUR3NVB1ejRncVJ3WVJjRi9r?= =?utf-8?B?SndKWEdYczIxSzErQURtZGMrWmlPVi9qZjY1ODBFSFcvMGgrSW1Yc2puYXcz?= =?utf-8?B?V01raExTTmJOOEhCeHNSR3VPc243bjFVN1ZFc29Ca1daN2tsTFFVTVdOSUR2?= =?utf-8?B?aGYwMUVaUU90VDRFQXZMR2kwbkpTakJ0d3ExZ0lFemg2RWxaaEVGaENqeGQ4?= =?utf-8?Q?TM4xT3ydMNo=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?SXFJTktXZSs2OUNBQ0lOR1M3c0hYaXBVVE43THFKeWpvS2twSVV1WnMrdGdm?= =?utf-8?B?cTFKVjJrY09LTEFnazNFNGF0NEFvUlB6d3pWdzA1dFpNQ2FPNW9YbmlOYnlw?= =?utf-8?B?UnN4U0M3bXQrbGtuajhCTFFXYVlFQmxqUDgvdzhQdmtsT3poTmN6MFN2ZXBk?= =?utf-8?B?YjNzaEY0VFppckFGamlyVFIvQ3QvTUFJeklPQlFpWjBxb2JMazY0czhSaXhn?= =?utf-8?B?UUlUMmxEdWdpQVorQXRuZnNxWVl0Y1dOcWlzU3FMRURoNUdCVnpoM2xtRDY1?= =?utf-8?B?Y3o1c05rTjFsY296RmE2SDZNQUNBd21MK1NGbExObDhKUUpJRFpVVzVnZzg1?= =?utf-8?B?bnE5UGdOdnVpNHphakpqQWJZZ1pXQVRPMFE0cXY5S01sakJFY3FBTm5QMk5B?= =?utf-8?B?TFBuQ3I5SEppOWJRYlBUUUJ3bXZPTnlKb3dxZkhBdVU4WGVXc2tuN0JycVpG?= =?utf-8?B?NnJROWZFOHIzNTAxUDljazFHRW5SZktvd0psN2R3Qi9TVVh4MTlWZGcvS3hV?= =?utf-8?B?VjRqbmxXRHk4TVh1QzAwS3QwY3BTelJsSUZ1Z2pBWEJSemJCVkordDIvOWNm?= =?utf-8?B?T2p6ckZXWUdydEg3MWdVM2V5bUVheFBDMkFLcWhFOUVSS3dObnE0SXphVUQz?= =?utf-8?B?Q3JKdmdZbVNLUWN4a1lSdkZLSmgxYitSUTR2emdsWVdjd25zeERLL3oxWmRG?= =?utf-8?B?cjhHYkg2b1hlbnNDcHhRZUtWQlZpOUt6NlI1d05pVFFDNXBFU3ZTbnpVY0VN?= =?utf-8?B?eE1HZGNBcVAvK01wWTFUMGJCdEU2QVhvdEhyVmJjWnUvMGpEeTJISG1RRHoz?= =?utf-8?B?UUE2b0xFUDEvZTJRbTc1Tkk2MVRwZEw3Y2ZibHhoM3pDL1p6NDczZXUwOTdk?= =?utf-8?B?UUd5ZXY3Qk9jSXIvL3BocmU2NXBTR0ZVcTVBT2dSSmg4QTdBUFFJazlFWU1s?= =?utf-8?B?WERLd2pBOU9FNEdIeUlDdmtyZk9vQ2pTa01nN0pmV1RncnlhU0hXMytkMGVV?= =?utf-8?B?KzZ3U1pBb2lKVWMvVkF3VTRTazh2Y0RVQUtHem1aNnFmeU5QVFNvZmgyVnE1?= =?utf-8?B?TXBpTmZZcUx0WVZYUmNYbm1SL1lKTjVpenFIOXM2QkFVSW5uNko4dW1ZdEk2?= =?utf-8?B?aG01WU9hOVpuS1E1Z3daUVpKZW5qUkVOSUZYeUtVUE83SVgvMVVpMy9VbmIw?= =?utf-8?B?bjZNQkJJMzBRTDd3Uzh2dXJ3RWtYVi82U0M1L0RFdTNLUDNLbU5rbWR4Uzhi?= =?utf-8?B?SlFpMlVqRzZOWUJKSy95Y1FlTHZxaGxsclhRY0Qwd1gxNkpUckJHRUpjVFVR?= =?utf-8?B?MVJjRVBXQnNlbVBkZHRSR2s5Mk03czVlQlBKWmFZSk5DaHMxR3phb1U3Uk9U?= =?utf-8?B?c3JVczcydmxSQVZEZEpXWGJhbVRxR0pLbGd0aVZNdk5EbkJuY0FuRTdtZ05C?= =?utf-8?B?L1huelJtcmRkUUVTUmZDMCtMQndhRmJBenVWRzhBZUJoZXMzeGRua2cxbVZI?= =?utf-8?B?VGh1Nk9vWXZBa2ZYL0pkN0I4cWpKZkpOL0FsWDRucDZJbWNXTTB3KzB1S1p1?= =?utf-8?B?QWExcXloclhSbUYxZlBCZm1PaEFBZTk1a3I5Z0FDYnBwdzRDaExOR09JbFZX?= =?utf-8?B?VFd5YXRLWWJRRFZpMjUwZmlKWGZFcjR3SnpUM2NiYzN2UnBRdTFvdTFFVGJJ?= =?utf-8?B?ZkZCR1o2TkpPbzFwdXJRTlhYdStxbXBkU0owUFcxV2ZNV0NrLzQ4WkdIbXc3?= =?utf-8?B?Wnk0ZU1FV3JSRVBKNFo2aGhXRjVsNjhWMHc1eG5xcVhndktrSk5hejFlbEZD?= =?utf-8?B?ZVhKWXlnVzhmdkxyUE1hdzkrOHhoZFVmU3d3WWVaUWluUlgxalBobURlc3Va?= =?utf-8?B?Z0t6bnIyOEx1QjRZSmIyMmhzcVJnTHMxeWZPSjZubnhDR1VSOUV2bitueDNZ?= =?utf-8?B?dmlHcGl4d3ZjVncwbnNHUFgrbTBpZzJZUHVIUlNRbms0OG91UnlkOEpPeWVP?= =?utf-8?B?NFFLK2lwekdmbFlHMmRBRHNEMG5RN2VJQ0ROb21IditDcHJxclBSZWFVQWJq?= =?utf-8?B?TVJCVDFiRzd0Szl0T1kvOEQ1dUlhZGg4OWpTK0o0Mk4wcTRrQ1pzWkxUNmlO?= =?utf-8?B?QkZIczR4UFZSa0lscEkwaUMvRHE4RVZXMVB5ZlB4LzlaTVJBamd6SVlwSnAr?= =?utf-8?B?bGc9PQ==?= X-MS-Exchange-CrossTenant-Network-Message-Id: 1980d680-2877-4661-55bc-08ddc56083e8 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:07.8518 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: CScgvOWcS+mEDddvEu7Np84QSUydHO6/J1SSyYHMhVnGpWGFN3pZYvSGhF+q9u1Tmp+0x/ZoPNxlIBPpu7gNoZ8WvBcRuRIDkdHv4BYlCWs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com PCIe 6.2 Section 7.7.9 Device 3 Extended Capability Structure, enumerates new link capabilities and status added for Gen 6 devices. One of the link details enumerated in that register block is the "Segment Captured" status in the Device Status 3 register. That status is relevant for enabling IDE (Integrity & Data Encryption) whereby Selective IDE streams can be limited to a given Requester ID range within a given segment. If a device has captured its Segment value then it knows that PCIe Flit Mode is enabled via all links in the path that a configuration write traversed. IDE establishment requires that "Segment Base" in IDE RID Association Register 2 (PCIe 6.2 Section 7.9.26.5.4.2) be programmed if the RID association mechanism is in effect. When / if IDE + Flit Mode capable devices arrive, the PCI core needs to setup the segment base when using the RID association facility, but no known deployments today depend on this. Cc: Lukas Wunner Cc: Ilpo J=C3=A4rvinen Cc: Bjorn Helgaas Cc: Samuel Ortiz Cc: Alexey Kardashevskiy Cc: Xu Yilun Signed-off-by: Dan Williams Acked-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron --- drivers/pci/probe.c | 12 ++++++++++++ include/linux/pci.h | 1 + include/uapi/linux/pci_regs.h | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e19e7a926423..9ed25035a06d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2271,6 +2271,17 @@ int pci_configure_extended_tags(struct pci_dev *dev,= void *ign) return 0; } =20 +static void pci_dev3_init(struct pci_dev *pdev) +{ + u16 cap =3D pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DEV3); + u32 val =3D 0; + + if (!cap) + return; + pci_read_config_dword(pdev, cap + PCI_DEV3_STA, &val); + pdev->fm_enabled =3D !!(val & PCI_DEV3_STA_SEGMENT); +} + /** * pcie_relaxed_ordering_enabled - Probe for PCIe relaxed ordering enable * @dev: PCI device to query @@ -2625,6 +2636,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_doe_init(dev); /* Data Object Exchange */ pci_tph_init(dev); /* TLP Processing Hints */ pci_rebar_init(dev); /* Resizable BAR */ + pci_dev3_init(dev); /* Device 3 capabilities */ pci_ide_init(dev); /* Link Integrity and Data Encryption */ =20 pcie_report_downtraining(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 0e5703fad0f6..a7353df51fea 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -444,6 +444,7 @@ struct pci_dev { unsigned int pasid_enabled:1; /* Process Address Space ID */ unsigned int pri_enabled:1; /* Page Request Interface */ unsigned int tph_enabled:1; /* TLP Processing Hints */ + unsigned int fm_enabled:1; /* Flit Mode (segment captured) */ unsigned int is_managed:1; /* Managed via devres */ unsigned int is_msi_managed:1; /* MSI release via devres installed */ unsigned int needs_freset:1; /* Requires fundamental reset */ diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 1b991a88c19c..2d49a4786a9f 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -751,6 +751,7 @@ #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ +#define PCI_EXT_CAP_ID_DEV3 0x2F /* Device 3 Capability/Control/Status */ #define PCI_EXT_CAP_ID_IDE 0x30 /* Integrity and Data Encryption */ #define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT @@ -1227,6 +1228,12 @@ /* Deprecated old name, replaced with PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE = */ #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL PCI_DOE_DATA_OBJECT_DISC_= RSP_3_TYPE =20 +/* Device 3 Extended Capability */ +#define PCI_DEV3_CAP 0x4 /* Device 3 Capabilities Register */ +#define PCI_DEV3_CTL 0x8 /* Device 3 Control Register */ +#define PCI_DEV3_STA 0xc /* Device 3 Status Register */ +#define PCI_DEV3_STA_SEGMENT 0x8 /* Segment Captured (end-to-end flit-mod= e detected) */ + /* Compute Express Link (CXL r3.1, sec 8.1.5) */ #define PCI_DVSEC_CXL_PORT 3 #define PCI_DVSEC_CXL_PORT_CTL 0x0c --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 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 329EC2D3A7D; Thu, 17 Jul 2025 18:34:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.21 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777261; cv=fail; b=Jsdqk+4OiszbwWMw2ckEvq2A/NEfnnL8y5jqyJuuBl8TmZmLbbHsEwUwE8WIDu4e5R3HPW7to/p/3HGhrzSRhOJi1tvUGHYbrnXP8SDnMAQvJL24xCbvolnLYfEHdBPmGWRqq5h2vrpaA2nMml7Uo21MIFtrgNv4QEEhz2HA0Is= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777261; c=relaxed/simple; bh=RmlKBLnyHSkiq5ywj2Yen2jx0miqzBOXBfHeELn/D1A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=M0YxxDA4qoxGaXmgKTzqQsvdR0+0azox4pnELGhF3ACB5xkEG5n4liigQ5pdXxTZOlfLu7H3pWBXKa27iMydMG2NEJcRsMwTBK56dhcpk+JYdUcSKzQy+Hw35bgeKxQyjPDDwki+hPRddxgiWNplvvkKop6pFvJ8GT4FNZEYNGo= ARC-Authentication-Results: i=2; 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=bzmsLiA7; arc=fail smtp.client-ip=198.175.65.21 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="bzmsLiA7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777260; x=1784313260; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=RmlKBLnyHSkiq5ywj2Yen2jx0miqzBOXBfHeELn/D1A=; b=bzmsLiA74CtYZt6WuYHhPufVJcIlRiRpiD4W5zBgY9NPYh4ZbDT0wIHS 3u/WF2KUwfLat5n+chreZPEFdPVdeJDlkca1CWdbpLmZ8Tx/P0VW0eo63 zfgLZIvOUlmkhr1vTyFO5RDCLNTIihzmi+x/qEuqU8pGNnpd9KbShTI5O Zudv3Bx5tk3LJqE0sYLzSEJbDYCCDmDmNcwPzeffwmOK58DOUTqB3/d/U JZ6lbniuvazj9pQPxjE+rNRDm9MR9gxSaqzolty18foohvk2UGN2V+TPQ lCZe7YuMXrIOdRPDwAYij2YVCUnA/YXCn0H8gx1gck9ba05x5CvAKrJd+ w==; X-CSE-ConnectionGUID: mhwKXQ3bQlyCzIrbG5mZsQ== X-CSE-MsgGUID: ZnCx8GOmR32tYqfpb6vCbA== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54945690" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54945690" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:19 -0700 X-CSE-ConnectionGUID: fbK0pCkTQoacquvYWDbsmg== X-CSE-MsgGUID: CQ+7JuYiSw6ik7xguOfVEQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="158222621" Received: from orsmsx903.amr.corp.intel.com ([10.22.229.25]) by fmviesa009.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:18 -0700 Received: from ORSMSX903.amr.corp.intel.com (10.22.229.25) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:17 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:17 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:15 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=r08JE/uZPSlAt5STxrp/pnjTCVSZjgd8uQfLZlucAOg/2xP6VHpMK1v9b4HnmEWRRM1ofA8+ti7UUu9EMjHQ0YjZXFbAlEig/b3abKKFykp6TzwZwQV66y/JSK/GJWioJqIkr3DGyV4zBgM2tb1Zc1cQnmybFtg3Ej/E7D5+bX44QsbTLIkj09Er1yDwpRh63JvboAfxXtyfCZ2MNnpWDV4omSA86hKaZYBsc9hNbPPnTNmvlw7zclAyYQ66U9wXbVKGGFNUHsmSyGRga0YUZmNg+MPwUo6sagArfz0K5YDB/7I1cgTxL7rnTYx4Lo9pmiPKIWXHQNctlCAKg2LSQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=98fRjYcUyxK9V+wwrIxheJ/QlM7URMtMJYC+++WkqFw=; b=azCOezFmxZtjz9N4SI+RI+1xD84USNe+znhkEOqJ5e7O7GR7qfwkPyZM2ZKeuRuCo1c7NWnHNtvRRrM7WugD8LtEOt4wZiJocYDnPFp+DGPUckIOr5As2ryyW5hamnsPxRxrpN2dOapVV8qZNBwL5gC21jFxtesyPYol4g1lEZ0O7ICKa79c3m7Wu6pikn1nrct/O6d6wt7jmT9R05pw263dIoaRpckfpqhI1XHDGG9HyTl74b+5VYvE4kOvlNutciQX1hC/8lNCN1gYW9ixWdZY8NRHRCc1CYZLwnyghenOV+kGTb+Z/G+nB1LOWAsCOdgsz2txz2CRM6ff5xftgQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:08 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:08 +0000 From: Dan Williams To: , CC: , , , , Samuel Ortiz , Yilun Xu Subject: [PATCH v4 07/10] PCI/IDE: Add IDE establishment helpers Date: Thu, 17 Jul 2025 11:33:55 -0700 Message-ID: <20250717183358.1332417-8-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: cd72ea6d-7ee3-472b-6f3a-08ddc5608479 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?DdVp63487oF2hl5OgCcrsmKlsh7usurw5Bz6Gg4HVUJk0LrUs5acupTjumK9?= =?us-ascii?Q?2m1YpyGChgoGKalzK5fTXtA5ypGXKu04pLbux7EJATF/b4yahi5VglHlx/jN?= =?us-ascii?Q?N8DZspR/IAtMh46fgrXJczr4dufKiGp9SWc/w+JP3HYkpzllmj8MTtwuwsRF?= =?us-ascii?Q?UDEaH2N5oXYDxEXeZIIALjwX5Q3/YCMpVGhDU0zf1qhMEjLmhGNJa2veaUkJ?= =?us-ascii?Q?BB2zAs01BjR6If8bPFzu6IJltfPz9NqI2b+KDu9OxagmwkCOOuxiTEGFdrDy?= =?us-ascii?Q?LHfziL+XbaekqyX00MYTFHmyCwELGkkcrFUdulinfueiS3OhSsLOqwzjPShq?= =?us-ascii?Q?tU/EOmF4Q5P3GAHPVo/kv0h3aPT5m0Av5f8bvErhRlDWpfFuvdYUbY3EuTGv?= =?us-ascii?Q?aWZiWaGnBX5qAAEvoAvtxAuQ+GeCebWb8NkkNcWO+ZLKetngR1Ycdr3LB3og?= =?us-ascii?Q?Q9KMoEyqXerK6MuzSpqk2a6ZWt1HkUAqPzLVNlusvHLfnd510/EH/h1jpR+L?= =?us-ascii?Q?Sz6JHWeZRkS18JvyY6WzfvLZyG4wBPhpDQF4H288a90bQelXK1+r861THDVX?= =?us-ascii?Q?wfdtV03dIexcGHIwj4TJNFvNZWgsBd2s4VDjaGakspYjFLcFDLz4sHpLu78f?= =?us-ascii?Q?ZPI1V9Hn8vb1zKPHAAB2nk5ZhGwqA3n4h0Vf+S0U95hUJYas6INjh6dtTHDG?= =?us-ascii?Q?5LwvpZhG6r5L9/bRtsb/Htx0U1+sokVy9V+aeGXpyhZtMs4wALfy+Rgz4Xwj?= =?us-ascii?Q?PvAtlwsJv/IlGgR/8DHmEeFQ4HI3EB7iaIYmvhltClsH0bz0eODnMPVqbNDe?= =?us-ascii?Q?L/qDZMLr30uYrYxxu0VJhiX3zSAjMRm+Mx3MLYAvCpVh+Jt26IXNBYdWREAU?= =?us-ascii?Q?Qe5Ni6GV+LgIURxNRN7lI0kDzM1dK/chGxTVLCP6C4loY6581IsEZw9aWm74?= =?us-ascii?Q?8SyxofLVvQzjI8/UBh3o4Dxabzk6AIsA76sALq9udIqPdT2Ln3E7mQGFZqKD?= =?us-ascii?Q?+EkCmIipL4Xf2/PwYp0BTJ/BkpHm6796zNAIjHN2D6PSF+tp19atWW2RoboC?= =?us-ascii?Q?sujOH4F2nYbDfk68sAFWZsRiB1CoRd/B4NFWYWrIM/7/OfgJtT1j5e+3zVjm?= =?us-ascii?Q?fRCnFTY9SYYPCLqakLIV+Ds+KMio9Sv8cucV3HwglcCQeQee+fPIewb5IOTQ?= =?us-ascii?Q?HNhTS2RwG7SJ4F6CDnwg7y6GFBbDj0GsGPW19/AekYwpwfZVKURB8tknVyBw?= =?us-ascii?Q?rXngzDVamb9LIwUpXkl8TMordQ/TWhJyMBoAbYN5Wb5r+vkrimhCqZZzdrs4?= =?us-ascii?Q?GfRPaLjH4P9JA/uqaPe4YP79230icJN3UYmwzrw3IS+4oBcgP4BjCdnjmLEM?= =?us-ascii?Q?JESRikDdCsBUirg7hZGq5i4Ql/FeYTE89l/UnF3hux0FE8J7jaat1Gc1TU+u?= =?us-ascii?Q?Ln+nUvCwHQM=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?c24lNdAK5qJxd7plSae7IsT9gxKKx1ZfOySSNvt3n48/hX9FLdIj22z+iLp5?= =?us-ascii?Q?7KYPvAMnlv9KXgoymotugCau+yvLBXTpWMnQHiQfPGU/aSTibzJMbJgGJ66t?= =?us-ascii?Q?qRp5lThzh9IDUeF/xgT5FLTSvqr8XyU3Atuw3/x01RSXqgGXbyRDRh2JtXId?= =?us-ascii?Q?U6gZ9K1PhOaCuf45FsCkRYVyJnf1z0DS812NLc1yMe6908ENaGHM8Fk1CQiA?= =?us-ascii?Q?ji+Y31oCZ8yq16rd20eX6sPkxMnsxs940iC65unU4GIEvGJQm812Sm7tnUvk?= =?us-ascii?Q?XJRA/IDEjzfFyaNRuiIsVhID8P4GISVRMHrzmpETIvY7X8k4/hyJkUcG3ZZg?= =?us-ascii?Q?W4XqLMSRFs2a3K+9LAbA6741HNihJq2IN4977iUFXVELF67A0+k/b0nk6T3g?= =?us-ascii?Q?i767/nHCD2NX9ApN1hOmdDKi1Ex4EVFw5OtN80U2aKX7QhlrK0jmTJrUepHY?= =?us-ascii?Q?P2Y6TahxRgtbQdgLT3Lzytfd4PPAeJqlC6vTG982bRK7v+cJ09mnzZfywZ73?= =?us-ascii?Q?Xb/35groiOj8NFtZK5QYMTY002hCsOe89WO0O1TX0BuXMZJKntJVQS2f/tF0?= =?us-ascii?Q?qkRJ2UPQwnjwzO9Nw3WmNJXMKfJ9R95RFtfXlgzHJ860QxyEkwTHRhM2GzOR?= =?us-ascii?Q?qcxMShNEQE63NAR+LTjRCprcNv9L866Pn/ZOUwqJ/zTex5cxeSNoz6oNdgfR?= =?us-ascii?Q?QsrG2DNInIdT+y8kwNp27S2cTo7/zlEBAvLfA2LZraPzx0iHZXu18vsw+gjR?= =?us-ascii?Q?D7CYKAzS3jn3wjhvAXKpvMSySLiDTK0bhW+hX89FchxtAHla33vUm6tej3r/?= =?us-ascii?Q?rHL1m5PIA7tg6CIEb9Av5tw66vqB5FntA5OTC3Skki1Ki+ocyO8xQ++ITfre?= =?us-ascii?Q?Anxn5+Q0EK8GC9x+OXtueDX19twz/RszlunQzfTXJUy8wRcurYd/25cHqmO6?= =?us-ascii?Q?x4RDyZWD8VVZhTZnSU7rkrc46+FrcHt42Z3U8cNljuyA0dt31MFdXQQjFvaO?= =?us-ascii?Q?refDbRPIDD5NkrC2lxLbt09QbE65lV3d9ZEv5nvP7DgxE1SStPP1Wk7l/2Sf?= =?us-ascii?Q?Hb+HIunACWVuG7DkqrFp7OOJfTHuVJHr4//Sl4WWt0/+IQfXCNQqSrjrIPip?= =?us-ascii?Q?RcR3sdatdGgby2IByPq2XqJ8oDplni6IsvJE2h2UaMqNa0TsBTERCqW5LiBa?= =?us-ascii?Q?QHfNw/qfrL96kF/FDLvkf/3NSvnKFhsCQWi+6Zll6KT1VB2sBuH3DVQQQCWq?= =?us-ascii?Q?LE611u1h4Y5GmsiePdfZn4g4xjMV/f7sUF+mU52v1+JfuX/3z5kXHUvVjPR9?= =?us-ascii?Q?MbYUEpeVJkBxGZTLjAXl6s3BI/x4jHhkuzEJICc2NSWe8b2ZLD7mvRkth1dx?= =?us-ascii?Q?pkxUFLPMMPGd5w+pEA+M7x2emtatrOt+bYI0xynx5igvqZAagzOoU2OgVjwu?= =?us-ascii?Q?Azf6bVjsT8rNlnlhmqxNFKFkXVxK1xbyyV8d6y1+yhAH72edNbMgtZIa8AqD?= =?us-ascii?Q?a2cyGTVIQZ68E+fLWeqdc6CKgvVzhpqk3NyMQu1WShMR/vGqCFUnlDkPrB2a?= =?us-ascii?Q?QmMO/Cp/bqrAg2MtteeXwBthJgEsCCmTv+uvL1yCwW3dQ4HLzPTL4MDxgBpS?= =?us-ascii?Q?ug=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: cd72ea6d-7ee3-472b-6f3a-08ddc5608479 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:08.7968 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 4Si5bfnG6WcuVawTjtZSNHirOT2Fw3ckvKtuFKylEn4uetMqtR0qWi3ZinUpQifKWbXDuv+7/ihDks8kYEcmPJR1aYX2nN2L+yks90Q2s3k= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" There are two components to establishing an encrypted link, provisioning the stream in Partner Port config-space, and programming the keys into the link layer via IDE_KM (IDE Key Management). This new library, drivers/pci/ide.c, enables the former. IDE_KM, via a TSM low-level driver, is saved for later. With the platform TSM implementations of SEV-TIO and TDX Connect in mind this library abstracts small differences in those implementations. For example, TDX Connect handles Root Port register setup while SEV-TIO expects System Software to update the Root Port registers. This is the rationale for fine-grained 'setup' + 'enable' verbs. The other design detail for TSM-coordinated IDE establishment is that the TSM may manage allocation of Stream IDs, this is why the Stream ID value is passed in to pci_ide_stream_setup(). The flow is: pci_ide_stream_alloc() Allocate a Selective IDE Stream Register Block in each Partner Port (Endpoint + Root Port), and reserve a host bridge / platform stream slot. Gather Partner Port specific stream settings like Requester ID. pci_ide_stream_register() Publish the stream in sysfs after allocating a Stream ID. In the TSM case the TSM allocates the Stream ID for the Partner Port pair. pci_ide_stream_setup() Program the stream settings to a Partner Port. Caller is responsible for optionally calling this for the Root Port as well if the TSM implementation requires it. pci_ide_stream_enable() Try to run the stream after IDE_KM. In support of system administrators auditing where platform, Root Port, and Endpoint IDE stream resources are being spent, the allocated stream is reflected as a symlink from the host bridge to the endpoint with the name: stream%d.%d.%d Where the tuple of integers reflects the allocated platform, Root Port, and Endpoint stream index (Selective IDE Stream Register Block) values. Thanks to Wu Hao for a draft implementation of this infrastructure. Cc: Bjorn Helgaas Cc: Lukas Wunner Cc: Samuel Ortiz Co-developed-by: Alexey Kardashevskiy Signed-off-by: Alexey Kardashevskiy Co-developed-by: Yilun Xu Signed-off-by: Yilun Xu Signed-off-by: Dan Williams Acked-by: Bjorn Helgaas --- .../ABI/testing/sysfs-devices-pci-host-bridge | 16 + drivers/pci/ide.c | 422 ++++++++++++++++++ include/linux/pci-ide.h | 70 +++ include/linux/pci.h | 6 + 4 files changed, 514 insertions(+) create mode 100644 include/linux/pci-ide.h diff --git a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge b/Docu= mentation/ABI/testing/sysfs-devices-pci-host-bridge index 8c3a652799f1..c67d7c30efa0 100644 --- a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge +++ b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge @@ -17,3 +17,19 @@ Description: PNP0A08 (/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00). See /sys/devices/pciDDDD:BB entry for details about the DDDD:BB format. + +What: pciDDDD:BB/streamH.R.E +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a platform has established a secure connection, PCIe + IDE, between two Partner Ports, this symlink appears. The + primary function is to account the stream slot / resources + consumed in each of the (H)ost bridge, (R)oot Port and + (E)ndpoint that will be freed when invoking the tsm/disconnect + flow. The link points to the endpoint PCI device in the + Selective IDE Stream. "R" and "E" represent the assigned + Selective IDE Stream Register Block in the Root Port and + Endpoint, and "H" represents a platform specific pool of stream + resources shared by the Root Ports in a host bridge. See + /sys/devices/pciDDDD:BB entry for details about the DDDD:BB + format. diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c index e15937cdb2a4..cdc773a8b381 100644 --- a/drivers/pci/ide.c +++ b/drivers/pci/ide.c @@ -5,6 +5,8 @@ =20 #define dev_fmt(fmt) "PCI/IDE: " fmt #include +#include +#include #include #include "pci.h" =20 @@ -24,6 +26,13 @@ static int __sel_ide_offset(u16 ide_cap, u8 nr_link_ide,= u8 stream_index, return offset; } =20 +static int sel_ide_offset(struct pci_dev *pdev, + struct pci_ide_partner *settings) +{ + return __sel_ide_offset(pdev->ide_cap, pdev->nr_link_ide, + settings->stream_index, pdev->nr_ide_mem); +} + void pci_ide_init(struct pci_dev *pdev) { u8 nr_link_ide, nr_ide_mem, nr_streams; @@ -89,5 +98,418 @@ void pci_ide_init(struct pci_dev *pdev) =20 pdev->ide_cap =3D ide_cap; pdev->nr_link_ide =3D nr_link_ide; + pdev->nr_sel_ide =3D nr_streams; pdev->nr_ide_mem =3D nr_ide_mem; } + +struct stream_index { + unsigned long *map; + u8 max, stream_index; +}; + +static void free_stream_index(struct stream_index *stream) +{ + clear_bit_unlock(stream->stream_index, stream->map); +} + +DEFINE_FREE(free_stream, struct stream_index *, if (_T) free_stream_index(= _T)) +static struct stream_index *alloc_stream_index(unsigned long *map, u8 max, + struct stream_index *stream) +{ + if (!max) + return NULL; + + do { + u8 stream_index =3D find_first_zero_bit(map, max); + + if (stream_index =3D=3D max) + return NULL; + if (!test_and_set_bit_lock(stream_index, map)) { + *stream =3D (struct stream_index) { + .map =3D map, + .max =3D max, + .stream_index =3D stream_index, + }; + return stream; + } + /* collided with another stream acquisition */ + } while (1); +} + +/** + * pci_ide_stream_alloc() - Reserve stream indices and probe for settings + * @pdev: IDE capable PCIe Endpoint Physical Function + * + * Retrieve the Requester ID range of @pdev for programming its Root + * Port IDE RID Association registers, and conversely retrieve the + * Requester ID of the Root Port for programming @pdev's IDE RID + * Association registers. + * + * Allocate a Selective IDE Stream Register Block instance per port. + * + * Allocate a platform stream resource from the associated host bridge. + * Retrieve stream association parameters for Requester ID range and + * address range restrictions for the stream. + */ +struct pci_ide *pci_ide_stream_alloc(struct pci_dev *pdev) +{ + /* EP, RP, + HB Stream allocation */ + struct stream_index __stream[PCI_IDE_HB + 1]; + struct pci_host_bridge *hb; + struct pci_dev *rp; + int num_vf, rid_end; + + if (!pci_is_pcie(pdev)) + return NULL; + + if (pci_pcie_type(pdev) !=3D PCI_EXP_TYPE_ENDPOINT) + return NULL; + + if (!pdev->ide_cap) + return NULL; + + /* + * Catch buggy PCI platform initialization (missing + * pci_ide_init_nr_streams()) + */ + hb =3D pci_find_host_bridge(pdev->bus); + if (WARN_ON_ONCE(!hb->nr_ide_streams)) + return NULL; + + struct pci_ide *ide __free(kfree) =3D kzalloc(sizeof(*ide), GFP_KERNEL); + if (!ide) + return NULL; + + struct stream_index *hb_stream __free(free_stream) =3D alloc_stream_index( + hb->ide_stream_map, hb->nr_ide_streams, &__stream[PCI_IDE_HB]); + if (!hb_stream) + return NULL; + + rp =3D pcie_find_root_port(pdev); + struct stream_index *rp_stream __free(free_stream) =3D alloc_stream_index( + rp->ide_stream_map, rp->nr_sel_ide, &__stream[PCI_IDE_RP]); + if (!rp_stream) + return NULL; + + struct stream_index *ep_stream __free(free_stream) =3D alloc_stream_index( + pdev->ide_stream_map, pdev->nr_sel_ide, &__stream[PCI_IDE_EP]); + if (!ep_stream) + return NULL; + + /* for SR-IOV case, cover all VFs */ + num_vf =3D pci_num_vf(pdev); + if (num_vf) + rid_end =3D PCI_DEVID(pci_iov_virtfn_bus(pdev, num_vf), + pci_iov_virtfn_devfn(pdev, num_vf)); + else + rid_end =3D pci_dev_id(pdev); + + *ide =3D (struct pci_ide) { + .pdev =3D pdev, + .partner =3D { + [PCI_IDE_EP] =3D { + .rid_start =3D pci_dev_id(rp), + .rid_end =3D pci_dev_id(rp), + .stream_index =3D no_free_ptr(ep_stream)->stream_index, + }, + [PCI_IDE_RP] =3D { + .rid_start =3D pci_dev_id(pdev), + .rid_end =3D rid_end, + .stream_index =3D no_free_ptr(rp_stream)->stream_index, + }, + }, + .host_bridge_stream =3D no_free_ptr(hb_stream)->stream_index, + .stream_id =3D -1, + }; + + return_ptr(ide); +} +EXPORT_SYMBOL_GPL(pci_ide_stream_alloc); + +/** + * pci_ide_stream_free() - unwind pci_ide_stream_alloc() + * @ide: idle IDE settings descriptor + * + * Free all of the stream index (register block) allocations acquired by + * pci_ide_stream_alloc(). The stream represented by @ide is assumed to + * be unregistered and not instantiated in any device. + */ +void pci_ide_stream_free(struct pci_ide *ide) +{ + struct pci_dev *pdev =3D ide->pdev; + struct pci_dev *rp =3D pcie_find_root_port(pdev); + struct pci_host_bridge *hb =3D pci_find_host_bridge(pdev->bus); + + clear_bit_unlock(ide->partner[PCI_IDE_EP].stream_index, + pdev->ide_stream_map); + clear_bit_unlock(ide->partner[PCI_IDE_RP].stream_index, + rp->ide_stream_map); + clear_bit_unlock(ide->host_bridge_stream, hb->ide_stream_map); + kfree(ide); +} +EXPORT_SYMBOL_GPL(pci_ide_stream_free); + +/** + * pci_ide_stream_release() - unwind and release an @ide context + * @ide: partially or fully registered IDE settings descriptor + * + * In support of automatic cleanup of IDE setup routines perform IDE + * teardown in expected reverse order of setup and with respect to which + * aspects of IDE setup have successfully completed. + * + * Be careful that setup order mirrors this shutdown order. Otherwise, + * open code releasing the IDE context. + */ +void pci_ide_stream_release(struct pci_ide *ide) +{ + struct pci_dev *pdev =3D ide->pdev; + struct pci_dev *rp =3D pcie_find_root_port(pdev); + + if (ide->partner[PCI_IDE_RP].enable) + pci_ide_stream_disable(rp, ide); + + if (ide->partner[PCI_IDE_EP].enable) + pci_ide_stream_disable(pdev, ide); + + if (ide->partner[PCI_IDE_RP].setup) + pci_ide_stream_teardown(rp, ide); + + if (ide->partner[PCI_IDE_EP].setup) + pci_ide_stream_teardown(pdev, ide); + + if (ide->name) + pci_ide_stream_unregister(ide); + + pci_ide_stream_free(ide); +} +EXPORT_SYMBOL_GPL(pci_ide_stream_release); + +/** + * pci_ide_stream_register() - Prepare to activate an IDE Stream + * @ide: IDE settings descriptor + * + * After a Stream ID has been acquired for @ide, record the presence of + * the stream in sysfs. The expectation is that @ide is immutable while + * registered. + */ +int pci_ide_stream_register(struct pci_ide *ide) +{ + struct pci_dev *pdev =3D ide->pdev; + struct pci_host_bridge *hb =3D pci_find_host_bridge(pdev->bus); + u8 ep_stream, rp_stream; + int rc; + + if (ide->stream_id < 0 || ide->stream_id > U8_MAX) { + pci_err(pdev, "Setup fail: Invalid Stream ID: %d\n", ide->stream_id); + return -ENXIO; + } + + ep_stream =3D ide->partner[PCI_IDE_EP].stream_index; + rp_stream =3D ide->partner[PCI_IDE_RP].stream_index; + const char *name __free(kfree) =3D kasprintf(GFP_KERNEL, "stream%d.%d.%d", + ide->host_bridge_stream, + rp_stream, ep_stream); + if (!name) + return -ENOMEM; + + rc =3D sysfs_create_link(&hb->dev.kobj, &pdev->dev.kobj, name); + if (rc) + return rc; + + ide->name =3D no_free_ptr(name); + + return 0; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_register); + +/** + * pci_ide_stream_unregister() - unwind pci_ide_stream_register() + * @ide: idle IDE settings descriptor + * + * In preparation for freeing @ide, remove sysfs enumeration for the + * stream. + */ +void pci_ide_stream_unregister(struct pci_ide *ide) +{ + struct pci_dev *pdev =3D ide->pdev; + struct pci_host_bridge *hb =3D pci_find_host_bridge(pdev->bus); + + sysfs_remove_link(&hb->dev.kobj, ide->name); + kfree(ide->name); + ide->name =3D NULL; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_unregister); + +int pci_ide_domain(struct pci_dev *pdev) +{ + if (pdev->fm_enabled) + return pci_domain_nr(pdev->bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_ide_domain); + +struct pci_ide_partner *pci_ide_to_settings(struct pci_dev *pdev, struct p= ci_ide *ide) +{ + if (!pci_is_pcie(pdev)) { + pci_warn_once(pdev, "not a PCIe device\n"); + return NULL; + } + + switch (pci_pcie_type(pdev)) { + case PCI_EXP_TYPE_ENDPOINT: + if (pdev !=3D ide->pdev) { + pci_warn_once(pdev, "setup expected Endpoint: %s\n", pci_name(ide->pdev= )); + return NULL; + } + return &ide->partner[PCI_IDE_EP]; + case PCI_EXP_TYPE_ROOT_PORT: { + struct pci_dev *rp =3D pcie_find_root_port(ide->pdev); + + if (pdev !=3D rp) { + pci_warn_once(pdev, "setup expected Root Port: %s\n", + pci_name(rp)); + return NULL; + } + return &ide->partner[PCI_IDE_RP]; + } + default: + pci_warn_once(pdev, "invalid device type\n"); + return NULL; + } +} +EXPORT_SYMBOL_GPL(pci_ide_to_settings); + +static void set_ide_sel_ctl(struct pci_dev *pdev, struct pci_ide *ide, int= pos, + bool enable) +{ + u32 val =3D FIELD_PREP(PCI_IDE_SEL_CTL_ID_MASK, ide->stream_id) | + FIELD_PREP(PCI_IDE_SEL_CTL_DEFAULT, 1) | + FIELD_PREP(PCI_IDE_SEL_CTL_CFG_EN, pdev->ide_cfg) | + FIELD_PREP(PCI_IDE_SEL_CTL_TEE_LIMITED, pdev->ide_tee_limit) | + FIELD_PREP(PCI_IDE_SEL_CTL_EN, enable); + + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_CTL, val); +} + +/** + * pci_ide_stream_setup() - program settings to Selective IDE Stream regis= ters + * @pdev: PCIe device object for either a Root Port or Endpoint Partner Po= rt + * @ide: registered IDE settings descriptor + * + * When @pdev is a PCI_EXP_TYPE_ENDPOINT then the PCI_IDE_EP partner + * settings are written to @pdev's Selective IDE Stream register block, + * and when @pdev is a PCI_EXP_TYPE_ROOT_PORT, the PCI_IDE_RP settings + * are selected. + */ +void pci_ide_stream_setup(struct pci_dev *pdev, struct pci_ide *ide) +{ + struct pci_ide_partner *settings =3D pci_ide_to_settings(pdev, ide); + int pos; + u32 val; + + if (!settings) + return; + + pos =3D sel_ide_offset(pdev, settings); + + val =3D FIELD_PREP(PCI_IDE_SEL_RID_1_LIMIT_MASK, settings->rid_end); + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_RID_1, val); + + val =3D FIELD_PREP(PCI_IDE_SEL_RID_2_VALID, 1) | + FIELD_PREP(PCI_IDE_SEL_RID_2_BASE_MASK, settings->rid_start) | + FIELD_PREP(PCI_IDE_SEL_RID_2_SEG_MASK, pci_ide_domain(pdev)); + + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_RID_2, val); + + /* + * Setup control register early for devices that expect + * stream_id is set during key programming. + */ + set_ide_sel_ctl(pdev, ide, pos, false); + settings->setup =3D 1; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_setup); + +/** + * pci_ide_stream_teardown() - disable the stream and clear all settings + * @pdev: PCIe device object for either a Root Port or Endpoint Partner Po= rt + * @ide: registered IDE settings descriptor + * + * For stream destruction, zero all registers that may have been written + * by pci_ide_stream_setup(). Consider pci_ide_stream_disable() to leave + * settings in place while temporarily disabling the stream. + */ +void pci_ide_stream_teardown(struct pci_dev *pdev, struct pci_ide *ide) +{ + struct pci_ide_partner *settings =3D pci_ide_to_settings(pdev, ide); + int pos; + + if (!settings) + return; + + pos =3D sel_ide_offset(pdev, settings); + + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_CTL, 0); + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_RID_2, 0); + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_RID_1, 0); + settings->setup =3D 0; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_teardown); + +/** + * pci_ide_stream_enable() - try to enable a Selective IDE Stream + * @pdev: PCIe device object for either a Root Port or Endpoint Partner Po= rt + * @ide: registered and setup IDE settings descriptor + * + * Activate the stream by writing to the Selective IDE Stream Control + * Register, report whether the state successfully transitioned to + * secure mode. Note that the state may go "insecure" at any point after + * this check, but that is handled via asynchronous error reporting. + */ +int pci_ide_stream_enable(struct pci_dev *pdev, struct pci_ide *ide) +{ + struct pci_ide_partner *settings =3D pci_ide_to_settings(pdev, ide); + int pos; + u32 val; + + if (!settings) + return -ENXIO; + + pos =3D sel_ide_offset(pdev, settings); + + set_ide_sel_ctl(pdev, ide, pos, true); + + pci_read_config_dword(pdev, pos + PCI_IDE_SEL_STS, &val); + if (FIELD_GET(PCI_IDE_SEL_STS_STATE_MASK, val) !=3D + PCI_IDE_SEL_STS_STATE_SECURE) { + set_ide_sel_ctl(pdev, ide, pos, false); + return -ENXIO; + } + + settings->enable =3D 1; + return 0; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_enable); + +/** + * pci_ide_stream_disable() - disable a Selective IDE Stream + * @pdev: PCIe device object for either a Root Port or Endpoint Partner Po= rt + * @ide: registered and setup IDE settings descriptor + * + * Clear the Selective IDE Stream Control Register, but leave all other + * registers untouched. + */ +void pci_ide_stream_disable(struct pci_dev *pdev, struct pci_ide *ide) +{ + struct pci_ide_partner *settings =3D pci_ide_to_settings(pdev, ide); + int pos; + + if (!settings) + return; + + pos =3D sel_ide_offset(pdev, settings); + + pci_write_config_dword(pdev, pos + PCI_IDE_SEL_CTL, 0); + settings->enable =3D 0; +} +EXPORT_SYMBOL_GPL(pci_ide_stream_disable); diff --git a/include/linux/pci-ide.h b/include/linux/pci-ide.h new file mode 100644 index 000000000000..89c1ef0de841 --- /dev/null +++ b/include/linux/pci-ide.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2024 Intel Corporation. All rights reserved. */ + +/* PCIe 6.2 section 6.33 Integrity & Data Encryption (IDE) */ + +#ifndef __PCI_IDE_H__ +#define __PCI_IDE_H__ + +enum pci_ide_partner_select { + PCI_IDE_EP, + PCI_IDE_RP, + PCI_IDE_PARTNER_MAX, + /* + * In addition to the resources in each partner port the + * platform / host-bridge additionally has a Stream ID pool that + * it shares across root ports. Let pci_ide_stream_alloc() use + * the alloc_stream_index() helper as endpoints and root ports. + */ + PCI_IDE_HB =3D PCI_IDE_PARTNER_MAX, +}; + +/** + * struct pci_ide_partner - Per port pair Selective IDE Stream settings + * @rid_start: Partner Port Requester ID range start + * @rid_start: Partner Port Requester ID range end + * @stream_index: Selective IDE Stream Register Block selection + * @setup: flag to track whether to run pci_ide_stream_teardown for this p= arnter slot + * @enable: flag whether to run pci_ide_stream_disable for this parnter sl= ot + */ +struct pci_ide_partner { + u16 rid_start; + u16 rid_end; + u8 stream_index; + unsigned int setup:1; + unsigned int enable:1; +}; + +/** + * struct pci_ide - PCIe Selective IDE Stream descriptor + * @pdev: PCIe Endpoint in the pci_ide_partner pair + * @partner: Per-partner settings + * @host_bridge_stream: track platform Stream ID + * @stream_id: unique Stream ID (within Partner Port pairing) + * @name: name of the established Selective IDE Stream in sysfs + * + * Negative @stream_id values indicate "uninitialized" on the + * expectation that with TSM established IDE the TSM owns the stream_id + * allocation. + */ +struct pci_ide { + struct pci_dev *pdev; + struct pci_ide_partner partner[PCI_IDE_PARTNER_MAX]; + u8 host_bridge_stream; + int stream_id; + const char *name; +}; + +int pci_ide_domain(struct pci_dev *pdev); +struct pci_ide_partner *pci_ide_to_settings(struct pci_dev *pdev, struct p= ci_ide *ide); +struct pci_ide *pci_ide_stream_alloc(struct pci_dev *pdev); +void pci_ide_stream_free(struct pci_ide *ide); +int pci_ide_stream_register(struct pci_ide *ide); +void pci_ide_stream_unregister(struct pci_ide *ide); +void pci_ide_stream_setup(struct pci_dev *pdev, struct pci_ide *ide); +void pci_ide_stream_teardown(struct pci_dev *pdev, struct pci_ide *ide); +int pci_ide_stream_enable(struct pci_dev *pdev, struct pci_ide *ide); +void pci_ide_stream_disable(struct pci_dev *pdev, struct pci_ide *ide); +void pci_ide_stream_release(struct pci_ide *ide); +DEFINE_FREE(pci_ide_stream_release, struct pci_ide *, if (_T) pci_ide_stre= am_release(_T)) +#endif /* __PCI_IDE_H__ */ diff --git a/include/linux/pci.h b/include/linux/pci.h index a7353df51fea..cc83ae274601 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -538,6 +538,8 @@ struct pci_dev { u16 ide_cap; /* Link Integrity & Data Encryption */ u8 nr_ide_mem; /* Address association resources for streams */ u8 nr_link_ide; /* Link Stream count (Selective Stream offset) */ + u8 nr_sel_ide; /* Selective Stream count (register block allocator) */ + DECLARE_BITMAP(ide_stream_map, CONFIG_PCI_IDE_STREAM_MAX); unsigned int ide_cfg:1; /* Config cycles over IDE */ unsigned int ide_tee_limit:1; /* Disallow T=3D0 traffic over IDE */ #endif @@ -607,6 +609,10 @@ struct pci_host_bridge { int domain_nr; struct list_head windows; /* resource_entry */ struct list_head dma_ranges; /* dma ranges resource list */ +#ifdef CONFIG_PCI_IDE + u8 nr_ide_streams; /* Track available vs in-use streams */ + DECLARE_BITMAP(ide_stream_map, CONFIG_PCI_IDE_STREAM_MAX); +#endif u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */ int (*map_irq)(const struct pci_dev *, u8, u8); void (*release_fn)(struct pci_host_bridge *); --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 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 E89F12FEE25; Thu, 17 Jul 2025 18:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.21 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777264; cv=fail; b=l4UcDPT0UUwxYpJRSyrYn179bLQBJ/oWlLPnMOtuTauqzZRddvW+VY76mT+W78cF2OlGSmYRi0IiqH4+OuJr2LVHZOLBE0QZ1puFk/fEDxhaiT3qMOA4Hu4bJS0aCkaILVdjeoi9e9oDMX2HdR6wcfkJP7dxvxfYx9C40aDKblA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777264; c=relaxed/simple; bh=20uN+k324oX2WcTKyzEIxdQeivvu18eCP/K99vjT1RU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=iQonNQDbwq7G1JK0UhDNodmsFIJr35OGRvqElUMKzLZldpareO3n5If9yyWFuNgGWxOgSl1nb575/L/5u9Uai0bWZhqQy8hPvtXiSaoy5SR9+vO9YD5pZFsXSgdFRusGB3d/0iMzPtYPytYe1StqVaED5VvRHA4HaRijfwAKnXc= ARC-Authentication-Results: i=2; 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=QVtPtuHw; arc=fail smtp.client-ip=198.175.65.21 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="QVtPtuHw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777262; x=1784313262; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=20uN+k324oX2WcTKyzEIxdQeivvu18eCP/K99vjT1RU=; b=QVtPtuHwuj5BMVRVI7Lt32YDqdwFwRuDWKt/RfiRU4iVsUBePwfHb/pi Jhwb68pOqq7C/+2SpigZqp61n0SGBiz0NHvvTTKDd5V9ZWQHOffuo0moN O0wk5DARYdnQUCQReIzovD08DRSyIJWUHw7ziVeAYJupArNNIYbF9OcOn e0kSt3q14iPf8cVihdZ2gpPmj1kxo7whuPF2ibxYQwWcZJUCyM8BJAS+1 qa8eXIPhMr9t76V4UATuxpe5XubqnDC1UTtrQ47fypJ1N2xAysmYBUrZ6 m3f5msDqc17LqZK+4Mbe+vnBje0nUt0Ghi0HqAroznsQVHSXTyluh3s3V w==; X-CSE-ConnectionGUID: V2F3xnzmQCugKAw7ByFflA== X-CSE-MsgGUID: aCYUXRaTTrO//cdYKaBrGQ== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54945699" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54945699" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:22 -0700 X-CSE-ConnectionGUID: cdtCdmvsTGOOgRLpvfMzHA== X-CSE-MsgGUID: n3dUXqWmS1C9NKPqeW8Rnw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="158222627" Received: from orsmsx903.amr.corp.intel.com ([10.22.229.25]) by fmviesa009.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:21 -0700 Received: from ORSMSX903.amr.corp.intel.com (10.22.229.25) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:20 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:20 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:18 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kW1x4gCVKI/LH6tBuPMoXUXJHEMdz+G/U5CLzcuGfB3CaYCV2SZ82btcO2ZoyZoCvx9O2JdaAl1o3LKCEDl7mI+UdQRBX8Aa39fuY93Gra78VhmJ2DzMmwPkWk0S5xouXtn0kMCt/BSPz9pMb5vTU2SoUCxEEBjFlAn3MbpYCwVpgCVDHodAlBvJ9troVgc2ucedx5cz4c2qXUFkQtyAV7vcpb7N+N8dpzobDRQMdH6Yswg8XeQiDfKuJNcwX1D5ARTEVyvPliPL7noYPTltfcNvaBpjzgVLvWU4533CdrVh/499P2n04YWcjflbeTx5WnMn2hI5zcnikSTcHWe0Lw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2ynw21CvL38RWYypXi23wc0VUMC8cDxrP8QRyHdlq0g=; b=o+qHuYaXspEhIwTVL9CptjfiecEPaRyrfwZtqS9XVqgOI2DUYrQ1JvHqXXe4BlOtuo9zdpa3o3ARVcE/W3nw4KfKIOZjfAMrmIGjwDjfGq64NIaV9N7HYb4ZCWXAi08hgKrY/gIzE40e7k+PEnUomfXXp4UhSxqWRsOvbsTu/MonnQXhGsYlZSashuBFiOfdm6ZGf/r48l4H6rLFIiJpPFww6AAuP2TxUSTZ+bEIpPYwZ2/V3Oz5tpuhwZFQoobN7rk8yvAz3KRWEyCkkpDpokhze+ppL+AXY4Wa4RmfA1PlCViPZVu6oO/MeESsjHzZ49A0aKRi5taQl2mEoB4V+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:09 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:09 +0000 From: Dan Williams To: , CC: , , , , Samuel Ortiz , Xu Yi lun Subject: [PATCH v4 08/10] PCI/IDE: Report available IDE streams Date: Thu, 17 Jul 2025 11:33:56 -0700 Message-ID: <20250717183358.1332417-9-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: ab068871-405b-42e7-6839-08ddc5608502 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?VLdB+kvqoW+UQOTHbOL4UDJE/TiPVCghbp9M3EGza+OcyTnQ2CDYoecL32Px?= =?us-ascii?Q?6LbmdsMHzv4ylux4EJRklJaTIjAA7Ax3h/2EJAoIVMtCSLybdwBnPelGQ+KI?= =?us-ascii?Q?FNjaECAVlxOTlaxRicILlEIMvSpKaPOtC3zMa09KMU5mxYlXW+7Lga1WMbFy?= =?us-ascii?Q?jR+KJYsatoLgaLSjitnnhAbgGbOqQxdaK5dSraCOqm4AnMiH4pkAuhcSg3xv?= =?us-ascii?Q?YBtJLXyYbbFGVvijaIyp5sq6RgeWbfpSVoDxoP2D6jOCyrKFjsLBy6xtRerq?= =?us-ascii?Q?VoFEbJWOHUWqnBg6ikf2/91Z994dt/fyf7BS/7IHXabXFansrglbU16iQ5AS?= =?us-ascii?Q?b9FBtNTou47XRWX2H8mx+iNAM2BFzDhWHf9+IVX7lfwtQCKl4QPEzr+Xzg8/?= =?us-ascii?Q?MRu/ZXtGMOXFrbkCfKxBb8C7Fo37x+dFUVu8+1K1fzpDMwHkSSUlgYZEK8uA?= =?us-ascii?Q?mbgAFJ+GOBXkypIjo9SrdMOzQJ81IAP1emj9XqBOC1W2IQupfZCsfrAY/dPh?= =?us-ascii?Q?4fUtzMSOHuEpzM+w27gAOJ+BLRnrXPOa47OF2lkH8o9X7s+QQ3Wp18LcIsBm?= =?us-ascii?Q?0PDrZ/xXngimO9oFkHZIauOIzpfY/6pghimWItNGySoFQL0lJCTzZ0j9slCx?= =?us-ascii?Q?kJG96Va5YCRB/Tv/gdMW1mZLPmqjld5SxfnegeEmKX7/3FOnQbL9ebXDPCJ9?= =?us-ascii?Q?C8+zrBm9GvC033YH+0LFbmZA+jqD/HVbiZt6tAKNpLbrbclMoblN3RzAcODz?= =?us-ascii?Q?p/XpY0VLYStgm/kqqazgEvm2AXh7+K4aPAc7bKl+M0hPniG/sHUDOJ7N7i71?= =?us-ascii?Q?2MoGEAstzEPd0uBpyYpJIKcemz5s5LQIqye00onq7FZ4jcO8MTGY1UAhop6X?= =?us-ascii?Q?xh0IfPQIglhrhonC1iwDXl1lPCQyVdP+JxLDMMlCIGq9cx5eh6sZ21JxI0Pr?= =?us-ascii?Q?aFYBkq5dgxmMawWZlTnhXa/3cdjau4frdqs8P3JyiJGFLrpyhtmdUNDTcZO0?= =?us-ascii?Q?5dphWInTACPrgohmQQ9rEFAwYJY/ob9EAvw733h91EA2ABBmH70Mj1uIfB6R?= =?us-ascii?Q?HJSPo9aB2czscVgA+u2O00WQ1HV3+eB8ZhXTJ62KFB4f+6aF4WomhS8nHIbA?= =?us-ascii?Q?onQYoibU5dt/1t724aEkwcEI6zLqVJPLt1lpnwV1OWf7ZpkxCMLby9aTVz74?= =?us-ascii?Q?bvMwuullGvXBfH34MAV/GdUj8RP3Exq5HRGhrc7hoGIrOtPo4y9vcEjsuqfy?= =?us-ascii?Q?nMtWLT0H/ZSeCaZ/tIILk5Jf0E7OFVJ/SteSGRBH6oLGulAAGz4LxPYdKkEw?= =?us-ascii?Q?UqwCVbQJ0l2adcApe2xqyqG4Nn3qScuD0Cr557pBkh8ALDuAS9QMjgBmDOTq?= =?us-ascii?Q?rzzg1/iriqq1Hu9XZLLyTsq07YBXk8LXS8ZjtzeQuR1JhBKcJvjc0VvTUNhh?= =?us-ascii?Q?YoKsrMKi5Pw=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?JUlMgL/GK3TJKHJkYBgO8hG01ib9PcjRp0h4ZMxTWOywhasSJa1nIMj2nL7b?= =?us-ascii?Q?zF+io0KxCZxMSiuCRpe6Bxjeggi+CLAHrBiKz0alcQan3opUHyILoICKnmmU?= =?us-ascii?Q?/TeXKWNBQUAedCegQGsjOPvpzim/m1sbbS0T1ljfFQffre6IiPweiBZO4zdB?= =?us-ascii?Q?Nq0Pl42fwkCm5hY2UdKTnXrXg4VwKP+qTSDR+D7lKfxMRUxOs0n1S++HNs9l?= =?us-ascii?Q?6gPUkerbNl0LTAEpKR9hhpeVJ/8vGtEz0oqeJHw28bspKTXamQ6jBikKqhn2?= =?us-ascii?Q?OswyHiLtiHz4UVDXuL200OAZ8O8ZXfjNzHIK9fAL7OBVWBWbwjjTHjU8R/u8?= =?us-ascii?Q?xdjq+HZhp/b2FmB/n5iTZTmGmGcfxmkiD9F3zAQhK24/hKBfjb6k48XvQ14B?= =?us-ascii?Q?QWvKrbo17rHR842Wl6kfFlTe0iaNcphKFa1BlSmTPVuGtstELdLfuAtge4MA?= =?us-ascii?Q?Z0tTD0YLxc+EWoBrhFCrM9kQki1+6I10OacokzjVYNvRS94f4HikViCde41D?= =?us-ascii?Q?FCgk9Txiji7fGyBC13CpK3fSxOkIEkERcwd+8MACyPzvlp2AdC9jv3E+Vo6D?= =?us-ascii?Q?fmhAIuVCSw9RFYXs12fu7swZE7DkfZrnqKe6UlLTCmhGCD5ievj1xixAcoP4?= =?us-ascii?Q?NnlU+GCuFvJYOyqzdjQdyXftP6sA24fIrUDzcTfsCeURfhf2zkJEVZoQKF7Q?= =?us-ascii?Q?XW7d01OCTujY7lqjFDX5pIryHITOiaAU3DPT6LKbIBjhtU1QSPkjqWurvZgQ?= =?us-ascii?Q?nnNPxnnmeErbW17IWiq25oUI22k+xGCl3Bt+Igdjf1TqCr/KxnAnGoQMVM0C?= =?us-ascii?Q?NbUgSenLxL4jEQnvB5mCIiiIMFE09hxORyt+rnTTqZU2MF6L7n3dHAWnBqoJ?= =?us-ascii?Q?mWqh9mNvMOJVqChjCwxB0xGp7yx/Sza5XvA33tRnJVn6SnpTmXmb5mAYBGSp?= =?us-ascii?Q?HQ2hhH3ZjfMWz8S6Ag4X52x4PRfcqrpnDwsGdX5xf3T7J2/TGBhNER3thlUt?= =?us-ascii?Q?KDxPtoQCpd4GqnBBVse67P7hUmU91fCNf5W4AWETk4iOw6SkT62BCuVmfREK?= =?us-ascii?Q?Gp2iKbSiMdiZ88BcDMp75btxteemyMCnsEw264hN4BIprC7agXrBcdohTHQt?= =?us-ascii?Q?j+1djRFxiMWV1ELmGCtewV72k/wDRKcnxGt9pN4qzeWS/XjSjQt4PUl3aSiz?= =?us-ascii?Q?uzsyaLHzjDBfoG/xOQpgyEjeHei9CmnKUEdMlX1yz6nKdJYHjV6AirscmWxp?= =?us-ascii?Q?p1T3YkYWaLFgAQ6+UWVesAa0fzRfABRBUpC9aYvd3F9rujDGPQPxx2ghTId+?= =?us-ascii?Q?craCGgvO/3ZvqHSZg5YJ/lxW/GSgPxgT0ZHJoQNyx/ZunJpVcyekZuYMxDKY?= =?us-ascii?Q?TbQPm5kBjqGfTpkYBKj/91FPf+DuED2F03KniYINuR74/bhX8Z4NryJAUxkZ?= =?us-ascii?Q?kV2gmO+GSigAZSHV+xkJyvVFJ3Ey3TDis7pD2WeD5+22pJ+bSkpPvv63cqpW?= =?us-ascii?Q?YGpy28OBigfw6/nPzLM1NFuiJCxdXKa8m+MtC+w2LlbBy2+UN82F5HJNPZMu?= =?us-ascii?Q?0O6q4Nzns/ZH3YBXi7ArtUymZIwmaGqqxq4ZRdBkx2Raqr86pH/ELPv9GOvM?= =?us-ascii?Q?kw=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: ab068871-405b-42e7-6839-08ddc5608502 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:09.7740 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2lHoRMnXLKOFvgo0/dTp1cyXvJ8GNx59AX6OrP27TEcfFiI+3BLJeEwt8LZV5XRAnZwFJjDqfPOPiLh0eVoMeNJ2N0UqRABcAKWHj0InRZo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" The limited number of link-encryption (IDE) streams that a given set of host bridges supports is a platform specific detail. Provide pci_ide_init_nr_streams() as a generic facility for either platform TSM drivers, or PCI core native IDE, to report the number available streams. After invoking pci_ide_init_nr_streams() an "available_secure_streams" attribute appears in PCI host bridge sysfs to convey that count. Introduce a device-type, @pci_host_bridge_type, now that both a release method and sysfs attribute groups are being specified for all 'struct pci_host_bridge' instances. Cc: Bjorn Helgaas Cc: Lukas Wunner Cc: Samuel Ortiz Cc: Alexey Kardashevskiy Cc: Xu Yi lun Signed-off-by: Dan Williams Acked-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron --- .../ABI/testing/sysfs-devices-pci-host-bridge | 13 ++++ drivers/pci/ide.c | 59 +++++++++++++++++++ drivers/pci/pci.h | 3 + drivers/pci/probe.c | 12 +++- include/linux/pci.h | 8 +++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge b/Docu= mentation/ABI/testing/sysfs-devices-pci-host-bridge index c67d7c30efa0..067d0879e353 100644 --- a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge +++ b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge @@ -33,3 +33,16 @@ Description: resources shared by the Root Ports in a host bridge. See /sys/devices/pciDDDD:BB entry for details about the DDDD:BB format. + +What: pciDDDD:BB/available_secure_streams +Date: December, 2024 +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a host bridge has Root Ports that support PCIe IDE + (link encryption and integrity protection) there may be a + limited number of Selective IDE Streams that can be used for + establishing new end-to-end secure links. This attribute + decrements upon secure link setup, and increments upon secure + link teardown. The in-use stream count is determined by counting + stream symlinks. See /sys/devices/pciDDDD:BB entry for details + about the DDDD:BB format. diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c index cdc773a8b381..cafbc740a9da 100644 --- a/drivers/pci/ide.c +++ b/drivers/pci/ide.c @@ -513,3 +513,62 @@ void pci_ide_stream_disable(struct pci_dev *pdev, stru= ct pci_ide *ide) settings->enable =3D 0; } EXPORT_SYMBOL_GPL(pci_ide_stream_disable); + +static ssize_t available_secure_streams_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct pci_host_bridge *hb =3D to_pci_host_bridge(dev); + int avail; + + if (!hb->nr_ide_streams) + return -ENXIO; + + avail =3D hb->nr_ide_streams - + bitmap_weight(hb->ide_stream_map, hb->nr_ide_streams); + return sysfs_emit(buf, "%d\n", avail); +} +static DEVICE_ATTR_RO(available_secure_streams); + +static struct attribute *pci_ide_attrs[] =3D { + &dev_attr_available_secure_streams.attr, + NULL +}; + +static umode_t pci_ide_attr_visible(struct kobject *kobj, struct attribute= *a, int n) +{ + struct device *dev =3D kobj_to_dev(kobj); + struct pci_host_bridge *hb =3D to_pci_host_bridge(dev); + + if (a =3D=3D &dev_attr_available_secure_streams.attr) + if (!hb->nr_ide_streams) + return 0; + + return a->mode; +} + +struct attribute_group pci_ide_attr_group =3D { + .attrs =3D pci_ide_attrs, + .is_visible =3D pci_ide_attr_visible, +}; + +/** + * pci_ide_init_nr_streams() - sets size of the pool of IDE Stream resourc= es + * @hb: host bridge boundary for the stream pool + * @nr: number of streams + * + * Platform PCI init and/or expert test module use only. Enable IDE + * Stream establishment by setting the number of stream resources + * available at the host bridge. Platform init code must set this before + * the first pci_ide_stream_alloc() call. + * + * The "PCI_IDE" symbol namespace is required because this is typically + * a detail that is settled in early PCI init. I.e. this export is not + * for endpoint drivers. + */ +void pci_ide_init_nr_streams(struct pci_host_bridge *hb, u8 nr) +{ + hb->nr_ide_streams =3D nr; + sysfs_update_group(&hb->dev.kobj, &pci_ide_attr_group); +} +EXPORT_SYMBOL_NS_GPL(pci_ide_init_nr_streams, "PCI_IDE"); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3b282c24dde8..8154f829d303 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -517,8 +517,11 @@ static inline void pci_doe_sysfs_teardown(struct pci_d= ev *pdev) { } =20 #ifdef CONFIG_PCI_IDE void pci_ide_init(struct pci_dev *dev); +extern struct attribute_group pci_ide_attr_group; +#define PCI_IDE_ATTR_GROUP (&pci_ide_attr_group) #else static inline void pci_ide_init(struct pci_dev *dev) { } +#define PCI_IDE_ATTR_GROUP NULL #endif =20 #ifdef CONFIG_PCI_TSM diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9ed25035a06d..a84aaad462ca 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -640,6 +640,16 @@ static void pci_release_host_bridge_dev(struct device = *dev) kfree(bridge); } =20 +static const struct attribute_group *pci_host_bridge_groups[] =3D { + PCI_IDE_ATTR_GROUP, + NULL +}; + +static const struct device_type pci_host_bridge_type =3D { + .groups =3D pci_host_bridge_groups, + .release =3D pci_release_host_bridge_dev, +}; + static void pci_init_host_bridge(struct pci_host_bridge *bridge) { INIT_LIST_HEAD(&bridge->windows); @@ -659,6 +669,7 @@ static void pci_init_host_bridge(struct pci_host_bridge= *bridge) bridge->native_dpc =3D 1; bridge->domain_nr =3D PCI_DOMAIN_NR_NOT_SET; bridge->native_cxl_error =3D 1; + bridge->dev.type =3D &pci_host_bridge_type; =20 device_initialize(&bridge->dev); } @@ -672,7 +683,6 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t pr= iv) return NULL; =20 pci_init_host_bridge(bridge); - bridge->dev.release =3D pci_release_host_bridge_dev; =20 return bridge; } diff --git a/include/linux/pci.h b/include/linux/pci.h index cc83ae274601..ae5f32539a91 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -664,6 +664,14 @@ void pci_set_host_bridge_release(struct pci_host_bridg= e *bridge, void (*release_fn)(struct pci_host_bridge *), void *release_data); =20 +#ifdef CONFIG_PCI_IDE +void pci_ide_init_nr_streams(struct pci_host_bridge *hb, u8 nr); +#else +static inline void pci_ide_init_nr_streams(struct pci_host_bridge *hb, u8 = nr) +{ +} +#endif + int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge); =20 #define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us= the PCI region flags */ --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (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 58E9D2FF474; Thu, 17 Jul 2025 18:34:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777265; cv=fail; b=NblJTY7klFJJSVgpUjQmkh2muFVpOI5I1HuLy8hNTKrjL15lhfciJ1aM7qw+TTVQBXZy9QdffbmE1pbtdhn8LiIhP84MrNJAaNeicagZyAjO4q2mddOt9AuI/LoGSXPa1U5UPPylwBL6pj6xCnrAmXkP0gfFJ7cLUmoZSYB/GWI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777265; c=relaxed/simple; bh=1n5uFYjVgOYuGGtfv43aAnB72guPPkN3jgRdWBfis1k=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=CXEZnYZ18IeoWXSCYea2E08MyHwcFQebbayDtZSJrAB2WKT23kcAgFPqfdJH8o12Oe/fY/qQhZHJCRPbp26kaJzD//BGpNLY58qcxk1m58RhdGmzxGEefXlFG5rba1daxNabgknKg9N0M6Iz6Ttoge6BynkhMUlTVIhRRc4Uikc= ARC-Authentication-Results: i=2; 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=Kqrg+pVT; arc=fail smtp.client-ip=198.175.65.19 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="Kqrg+pVT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777264; x=1784313264; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=1n5uFYjVgOYuGGtfv43aAnB72guPPkN3jgRdWBfis1k=; b=Kqrg+pVTZSvGTDfNymJ4nXrEhRjW3ienavMSKpOqu2PFoTt0yfY3OqkW PeysehTHd9se5RHEVyNZ/Ag9gBkv6tPZDqXXL/P26YiIW7qbIqclv477G 6Zhk6Nd5rUjaPhJRlorWviwx1Bdz2tMskH3tPDQMBLfhRV54FIWQGpfSJ Vg5vfq23I7pNkK2qdZxckN+j25009Hrel39IOC6piZLY9YMvnYN6RRJ6E BP4lje229QeGJUWylKofxe7AE7OIbQ1UTtR8SZcO2uW3M6CtsYv36Q823 qNGqAyQ6oKBRV/485+Rf4pLPCtNmiwyUFgbQJhCYeaXPzRcaQDJOhzDwo Q==; X-CSE-ConnectionGUID: ds0KVoeHR7qMfg7qURb53g== X-CSE-MsgGUID: xEumPkzVQyqBQxfQtrBEUw== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54924128" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54924128" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:23 -0700 X-CSE-ConnectionGUID: bHQV/lJmQVuVOsHgyKBHqw== X-CSE-MsgGUID: FHRQAiwKR3ep1cPaY4MSmg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="157254655" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:23 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:22 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:22 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:21 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yXkSrIogHfOwrIVWUOsDdbVmjV2hpwb4KPBKV5CkE5cVzIYNwzmIfahuAXJSUdNcYYxG3xnfhvUD0baRZcsfq/V85gcRyQ99bIw0Xv5BcH2RsizHz7p88PbVmdxRzukeL8Nk1zoRRCN7Fg504H2S5OYaGA/5ZPumsLapuPPEQOjk5f2ymlMz5JistiSGzH1ldHmPOmqf3XoDIwYuQbai2lQSsBN45OzhCF3rc3FGCnLqv92j6Xu0hY2p7k+rtsHVhZ5LxoDGoclmvLob5BygV6M1aAm+TArxKx9zdHgKU3aFt7erjNMy2w87pFMO88W7AxbuYN17YDof8Vgi4vRyag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Kz0tNETggTM5l+QerpAIDxQh8j6v+JVI+Z6R/alIh9U=; b=rAUb/wZFg91qKzIC4I5AlJS2GKtvY9KgK5pclYQubW1tMoNKoGIUEpEpaf+aMMs7YGe/RUUxFCy4sW79ApEP4qAwFWN04GZ8tyyD7BkTIvUXNE2lEmxn6d35gtbzYZpxcPSIvzPd31UdCoyjHrRg2N/52RRst4AvvwT+0fXXfTQpuj50tVL0+/MWMGm37TKrsjJRB1Qk47eAFfKU6aH/PUNWVDEiMPNMdko/aWR+4nFx2VYvDTeeRpE6wsfubJZr8DrTQUi9qi5vO+BrMo2Wf+Asf5JsHOJaf7JtuYJvn6NEqOurPHM4O0kkpdMwIsyKICNUM8C0GxTwWAancbyrUA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:10 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:10 +0000 From: Dan Williams To: , CC: , , , Subject: [PATCH v4 09/10] PCI/TSM: Report active IDE streams Date: Thu, 17 Jul 2025 11:33:57 -0700 Message-ID: <20250717183358.1332417-10-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: 7dd1b6ab-9dc6-4b63-615d-08ddc5608584 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ZrwmhKLt6Pj3mMLNbJihKzQBGpUNWcZvPwDHjLCcs7eu7hLKhCEIupyfj8uH?= =?us-ascii?Q?2TEJlrYQMXU+VdBJhtS87mgYb0MsMUQm5MbZCBCU934MnShv9tCsU7oHmnO+?= =?us-ascii?Q?BRilm1IIS8e1eup53YInOrEw7ASWRGKJW8rhakBJ7HesAhUPoeYggm027s8Y?= =?us-ascii?Q?uKENnmWvN5rsW+gcKLea1Bfjz569ciYt5m9g0mIWQzZnrK7w1VsRY5fIDlAt?= =?us-ascii?Q?P4+7kTBkZmjY8RHeD0sN5c5RNa3PDd6TA7ffMqOWEq9T76NOGUEdRBb998w4?= =?us-ascii?Q?oGicnxm7tXD/EoiBLYovZW6+ATYE01bAgGFCtKuVHQpYj4zyXCTY19ubye/+?= =?us-ascii?Q?WtTLfQhBx9ukKbF+R+1xYuVPoytTA/Yj7b+aCYLuFxM+c+Y7+87spii24SaQ?= =?us-ascii?Q?u/X6F4XnatA32B7/ktS19luA6RI3L3HZsKP9+PHVYB5ML9MJJgPvCzEumhJm?= =?us-ascii?Q?4+nMMdTNuvFgMbFJI/u1jGkcfKISsA9ZJqowcz+7/fb6L+dXsHWNlzpmBSVw?= =?us-ascii?Q?sTctNx6dQom6QlypVyD4lsNm0Y72X+ZwNkYA+DeTWwaIfgkDbSffOUCPNQg5?= =?us-ascii?Q?v8dl42HmxZjQrh1wWnZqexURLHImbjKlfMh8aBrhnryOkE8a55mqDiGlG+TC?= =?us-ascii?Q?DeqJsEtxnavG39p0peCf0OjHnuGZj4keKx/SUjhzNGvWpivzX2yjB8Eaaxz9?= =?us-ascii?Q?K5rLzOBWBrkc0tS1d/HPJRN+5/S1JKUh/UTyAsK7SFWBR0a/aWSl4wpTgoSR?= =?us-ascii?Q?kd8faYE4wf2P8wdtjT96RBWenSH5iYvrby6gmcs9Fs+OvVaaoNeuFsaXNcLC?= =?us-ascii?Q?yLBWNvRxhyxiW2Tq2i1Ep6nORmvt4M2btkR2M6wffwVyY6twOPO9rXiXmVOr?= =?us-ascii?Q?G6es3zUSJyXsTJkM+9AePX56i2XffzlEF7yrved+3A1s0RCHS73Nx+d9wMgu?= =?us-ascii?Q?89Rn37P37RIHEdDT/+VTPbhqChZ86fRLOPNmckCRjOcwmBE7sdf7hTkYG+k5?= =?us-ascii?Q?J/nXJxp97ACADs6NK47xZ7YKqyDISqx3iUO51N0FdWRkzvxkAeKqrspB/WvC?= =?us-ascii?Q?IGC5U8IBSN9SBs8onPJ9CYpplOkNLFUo7OM67QdXAPNrrm7RXbTnaGveDrY3?= =?us-ascii?Q?i8XPLnMd4ZiR7JA3aHkvqtx7alLFRxg4UerJ7n0Di+8MWkqkf6GCLQ2FL9/a?= =?us-ascii?Q?DkIRVJoWfY5u2S6yeLbdea7biVa1lMzglo65siRnaPd5lRoBxzYBah7pfWKz?= =?us-ascii?Q?lMrZgieLCOVsNR/NyTY8bs58P/YVWXJPvCCJBVJZ1YLELqTkgM35+4USMfdz?= =?us-ascii?Q?HMyOykGYcjgthq2OuOAM+6NA7zM0LmaY5j53JmmP3R0f2OuhqS0g2J07szlg?= =?us-ascii?Q?X2prlS222KqdA2XS4S3Hzxm7ChncT82YAHfEk+kWiQjWI8rdcM7a67WJbhdd?= =?us-ascii?Q?LVsQeidbrDY=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?fM5ZxGWrr00ONeBNGj61bT1vO7jV3AJjKqCdsgIWBEWiE+a2RNQwrUizSh6X?= =?us-ascii?Q?PuA0pbE1JHZEjeglexs9E/5y+sHBjiDxOwqU0XoBUHC/22mLRgAr+2JK1HZJ?= =?us-ascii?Q?dHWG2fzJYgjoSotDtXPSz49QS1I4tIxL+ermmS0zqdUkkWfjOU0EfVoTLBl7?= =?us-ascii?Q?4JcNzAWP+6GnPeOvUGetGUJykXOgHnCtdUbYTb+0dt6vqV29jLx6MtUSBPjk?= =?us-ascii?Q?ovWB9LOnhI8NcpFN/8D5H1nYeLaCmW/E/zVphcexrrSu/l/gy1zatVHlqUJ0?= =?us-ascii?Q?yjAcpDMH8gt6GHkLfWt4zN7019rm741EDGDfNSJpIDhUQsr1skUsrUTH5d0t?= =?us-ascii?Q?moeMMgxv02oOSfN3CPs5JCQg0VC6qs72Qrg3EzWcx15iOoK3KgufFqscmmxS?= =?us-ascii?Q?ogy4pc/pYC/x9GYsqxFVgh3SDTCOz/OL2+8Gfxu2WZUMtw+XB4Uz8lz3oqqj?= =?us-ascii?Q?LgeT0Ds3ViweAV0aocP0/5JYy6fMKYQLYacTw1r5CZAbeMU5R7rFHaboc1Fx?= =?us-ascii?Q?oFH33bil5RJVoUct975PFo1RAefBdnSlydf4QebxSDiCjW6lA0wrz8LQAgOs?= =?us-ascii?Q?Z+rMUZRsLr1MCGtl6Ua0YXn2QDDl83mwn8GLk1D0zjE21b7W3H55k3psiYK4?= =?us-ascii?Q?0CkLWrDK4vCvmRPcpW6UaOOhJUDN+3+xMTYi5VmetZ8Tz+g6RVlUAPmTyzch?= =?us-ascii?Q?BHUsBp5ihnnJax635OApHmgn0aqO57E3mwunrSPykvWoJ2fT6pl7bCz77Kxk?= =?us-ascii?Q?3o0YXohoYxzCXZOuWU7WQ797JEVM4gjq4uryG9xS7JVaizVXGRDqYs30+sMs?= =?us-ascii?Q?HJ1YnJquzzMBunyZwpi58ABmiqMOhx6fF0zZN2cYNNCqriewVncYQY1o8eEG?= =?us-ascii?Q?07JQIYoWMxeucHLIBkHL19ZCYnTIZf3RNBjS4qGuoF7g1HXEeTbYWkQEpaUh?= =?us-ascii?Q?/H4kNOpvMQ59PrMGOcf//PTXMTnSUhZGMk+HPZrYfc19VtR4yFlnOo6+m4fz?= =?us-ascii?Q?hHlyxrc99LMPw5T/VY+HBYGqqTqUVu+47T/3yAzX4OTtvQpAxttY+KTz5WAw?= =?us-ascii?Q?60FN0RuYlUwrnn1tv4OSPRqwrcQTnumJs49j8t3dAM6EP081OTYBnpdRaAKC?= =?us-ascii?Q?6GLRX40adAz/zI07umyMXffuqZ8SzV0D7Phlh00waQ2mlq2FVLL5GkiaFqSr?= =?us-ascii?Q?+DMKNQ5Sap3iwRLfl2ljM0RcTHEzPRPbvSYzDGzn1MpFODtVOJR8fJ3ix540?= =?us-ascii?Q?7Ainzivdcn4fMQa9PROmZWGU9SUwjNm9ZCi7WCWj3x3ehISDWLi+okMf6AkB?= =?us-ascii?Q?3uMt65bwUxa8EywPNBNgk1UA1Xh6EJ2MLwIfXgKXiJIPGHthjj/s8B3hm3Zv?= =?us-ascii?Q?bY+0F/BXVYK06K6z0JishxN5bGjac7GtQFHv8xfg7fFArKutg8KIyC0i0Wpt?= =?us-ascii?Q?ufWFNlN2ehz43RXF9JC5mXKEOB4yH6N6pYpC/LVznNt3O/ZnHqB+24r/Dt/g?= =?us-ascii?Q?3teNslahMOOLEKh7gZO53smaakl+ADRHdfBy/6Rva9eeq88jc1z1x9GFwQXB?= =?us-ascii?Q?l6D9LavKTEClAiJ9taM9u6trAyhhw5vMGnAYTBcUaZDqQJlCNcpKljzqkL6Q?= =?us-ascii?Q?Vg=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: 7dd1b6ab-9dc6-4b63-615d-08ddc5608584 X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:10.6210 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: DxNTsT719/pSw6IZ2ySj8PgExazRMPR4DL8ZNMPV21ZTGPuplO6Gtzu9ukw+I6UiA0DSXQTXYXk45V8pflw2OcMXunXqbJtxzNxIUYb1+MM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" Given that the platform TSM owns IDE Stream ID allocation, report the active streams via the TSM class device. Establish a symlink from the class device to the PCI endpoint device consuming the stream, named by the Stream ID. Signed-off-by: Dan Williams Acked-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-class-tsm | 10 ++++++++ drivers/pci/ide.c | 4 ++++ drivers/virt/coco/tsm-core.c | 28 +++++++++++++++++++++++ include/linux/pci-ide.h | 2 ++ include/linux/tsm.h | 4 ++++ 5 files changed, 48 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/= testing/sysfs-class-tsm index 2949468deaf7..6fc1a5ac6da1 100644 --- a/Documentation/ABI/testing/sysfs-class-tsm +++ b/Documentation/ABI/testing/sysfs-class-tsm @@ -7,3 +7,13 @@ Description: signals when the PCI layer is able to support establishment of link encryption and other device-security features coordinated through a platform tsm. + +What: /sys/class/tsm/tsmN/streamH.R.E +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a host bridge has established a secure connection via + the platform TSM, symlink appears. The primary function of this + is have a system global review of TSM resource consumption + across host bridges. The link points to the endpoint PCI device + and matches the same link published by the host bridge. See + Documentation/ABI/testing/sysfs-devices-pci-host-bridge. diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c index cafbc740a9da..923b0db4803c 100644 --- a/drivers/pci/ide.c +++ b/drivers/pci/ide.c @@ -5,6 +5,7 @@ =20 #define dev_fmt(fmt) "PCI/IDE: " fmt #include +#include #include #include #include @@ -271,6 +272,9 @@ void pci_ide_stream_release(struct pci_ide *ide) if (ide->partner[PCI_IDE_EP].enable) pci_ide_stream_disable(pdev, ide); =20 + if (ide->tsm_dev) + tsm_ide_stream_unregister(ide); + if (ide->partner[PCI_IDE_RP].setup) pci_ide_stream_teardown(rp, ide); =20 diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c index 093824dc68dd..b0ef9089e0f2 100644 --- a/drivers/virt/coco/tsm-core.c +++ b/drivers/virt/coco/tsm-core.c @@ -2,14 +2,17 @@ /* Copyright(c) 2024 Intel Corporation. All rights reserved. */ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt =20 #include #include +#include #include #include #include #include #include +#include =20 static struct class *tsm_class; static DECLARE_RWSEM(tsm_rwsem); @@ -140,6 +143,31 @@ void tsm_unregister(struct tsm_dev *tsm_dev) } EXPORT_SYMBOL_GPL(tsm_unregister); =20 +/* must be invoked between tsm_register / tsm_unregister */ +int tsm_ide_stream_register(struct pci_ide *ide) +{ + struct pci_dev *pdev =3D ide->pdev; + struct pci_tsm *tsm =3D pdev->tsm; + struct tsm_dev *tsm_dev =3D tsm->ops->owner; + int rc; + + rc =3D sysfs_create_link(&tsm_dev->dev.kobj, &pdev->dev.kobj, + ide->name); + if (rc =3D=3D 0) + ide->tsm_dev =3D tsm_dev; + return rc; +} +EXPORT_SYMBOL_GPL(tsm_ide_stream_register); + +void tsm_ide_stream_unregister(struct pci_ide *ide) +{ + struct tsm_dev *tsm_dev =3D ide->tsm_dev; + + sysfs_remove_link(&tsm_dev->dev.kobj, ide->name); + ide->tsm_dev =3D NULL; +} +EXPORT_SYMBOL_GPL(tsm_ide_stream_unregister); + static void tsm_release(struct device *dev) { struct tsm_dev *tsm_dev =3D container_of(dev, typeof(*tsm_dev), dev); diff --git a/include/linux/pci-ide.h b/include/linux/pci-ide.h index 89c1ef0de841..36290bdaf51f 100644 --- a/include/linux/pci-ide.h +++ b/include/linux/pci-ide.h @@ -42,6 +42,7 @@ struct pci_ide_partner { * @host_bridge_stream: track platform Stream ID * @stream_id: unique Stream ID (within Partner Port pairing) * @name: name of the established Selective IDE Stream in sysfs + * @tsm_dev: For TSM established IDE, the TSM device context * * Negative @stream_id values indicate "uninitialized" on the * expectation that with TSM established IDE the TSM owns the stream_id @@ -53,6 +54,7 @@ struct pci_ide { u8 host_bridge_stream; int stream_id; const char *name; + struct tsm_dev *tsm_dev; }; =20 int pci_ide_domain(struct pci_dev *pdev); diff --git a/include/linux/tsm.h b/include/linux/tsm.h index ce95589a5d5b..4eba45a754ec 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -120,4 +120,8 @@ const char *tsm_name(const struct tsm_dev *tsm_dev); struct tsm_dev *find_tsm_dev(int id); const struct pci_tsm_ops *tsm_pci_ops(const struct tsm_dev *tsm_dev); const struct attribute_group *tsm_pci_group(const struct tsm_dev *tsm_dev); +struct pci_dev; +struct pci_ide; +int tsm_ide_stream_register(struct pci_ide *ide); +void tsm_ide_stream_unregister(struct pci_ide *ide); #endif /* __TSM_H */ --=20 2.50.1 From nobody Mon Oct 6 18:56:27 2025 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 BFE7F209F5A; Thu, 17 Jul 2025 18:34:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.21 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777267; cv=fail; b=qNzEWmSoJIlACFqcw976QDmFECTOgwq1eG86BNECGSpA0JPz+nrQOJPgougb7nVPZjBHsEEGW3zZ1mrnBkjudNGbuOZqqnmWJ1/X8FpUIfU45kue4Iw46efrYMd56GF0dd7SctfpRsGWFwS4OZNJSLWov+nb/wrqO5U5lNEuM1c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752777267; c=relaxed/simple; bh=Vf6NT1EZ82FlGfK8b4qR0IrXS3s144AB8vhZ/6phDxY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=i0IwsKDE0c5Vqqk8vZQwkkPKPLDeG6fFt/1YdCtgCDaDMOjXEVM042FYQDnFw5UyKj6s3Oodu8smmgs6NKNwA+4KYv6Yn2Gr4OvKJg0qsethvMacOMRiBLqbqRaW3L3+oAge0zL/C+rxEnbq/A3e0GAJUf5/z4d3vewDO4HU0es= ARC-Authentication-Results: i=2; 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=OBym5bk6; arc=fail smtp.client-ip=198.175.65.21 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="OBym5bk6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1752777266; x=1784313266; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=Vf6NT1EZ82FlGfK8b4qR0IrXS3s144AB8vhZ/6phDxY=; b=OBym5bk66hI04OKiL3OZIkpy0FPKu1AlhZJhvo+dWWB3qZ84rjheq7te xCU1KyHqud/eVT/H/Mf91Y0MVaxUZr0V6Vw/06ojvtKrIflUytmh7KWyU 5/XS+Weqj6b6w9BeUwSpV7Z5E4L8i+nP+7FRPwbPn4dxKizf/nuXv8zbt BNxYU0OG9YoL/JRGp5RKF7/8p3NfTPYgPcyrgGRORP/Sz88TxgQflJyWl 0xNN82HmrvcwqyJ+XzpUzf9g+ThMsXK8wqyrDjPF6O0p5cAfVmFDPypJG Jhdph+nzEeimCaOK2y6SbkLW3K81qF80Q9BrAhNMZoXxw5ud3zNLCHR0I w==; X-CSE-ConnectionGUID: c2/IeuNXRlKcRuKsJrW0WQ== X-CSE-MsgGUID: 0kUkbPWWSQyfyYvES+1PgA== X-IronPort-AV: E=McAfee;i="6800,10657,11495"; a="54945714" X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="54945714" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:26 -0700 X-CSE-ConnectionGUID: 4HNoOzlOTmSf/vO1N4cUzQ== X-CSE-MsgGUID: iBnyZmr+QAms6OMP5Ro1uQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,319,1744095600"; d="scan'208";a="158222636" Received: from orsmsx903.amr.corp.intel.com ([10.22.229.25]) by fmviesa009.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2025 11:34:25 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX903.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:24 -0700 Received: from ORSEDG901.ED.cps.intel.com (10.7.248.11) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26 via Frontend Transport; Thu, 17 Jul 2025 11:34:24 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (40.107.243.52) by edgegateway.intel.com (134.134.137.111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.26; Thu, 17 Jul 2025 11:34:23 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pvN0D6bUfkbrvCbX5NV35c/QGUZgtCddajHZQen8i7e+TrZQ2giLos+f4DIcwY/MwujK1m5a6qcdZBUm2Dfg2w0Q1w1daoy/s1pLusccLRkK0wtX/I91IhflGWvNKKQZDSQCpKWiDvMSoiHgHhzNvL7EXwfzsc/yGOLL4W3bqr+3qlqj84r4F/NduvLXDI08wesNmVUbO1Y1m5p1lIijbKk5NEmOXNGJ/T7MJ1uTmi9POjl/Byq0T0hc9lr5PFsFL/rfW7rebD8u635zIWRYDy/MGm5o7S7o/sTXIuPjNxXHBGi8T4NX5D+69adJ6eqSdocG1vf8Ghd3ZpcfgwQFWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=V0hEOJ02+zpFahMVeXC4n8ulAZAKbn3+gQLhanJ5/ko=; b=rkFomUrOiFYWtprrTq7tnrE1O944nsZK9i71Nph2ZouoETYf0+nrYsLCJCj7mFN5c17Nt8lvCUTriJieKyDC0h/4GKTSzjT8EyfYwQYX1SbCHPh3FHiD/BN6zM/U5Hdv7bkpMlGYo+RxR1FGgi3sHgwGiJm01GfLpgtGZZHn7gQXanFuAsb6YJ5Rtdq5Wm/7brmqT4MpajNo+WSyqChJAZ0AUYJKMfIIUNeOXkWAPTRaDBRxvk7CwiSfzmQVN54wCXLDgOkyHmLBj/AaIdooE+fu+nb111tQj00Xh+cULrQ51+VpH+Z59bol67GxaKOrnxrLK/0WfPS0ZljJvl5hmw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) by SN7PR11MB7066.namprd11.prod.outlook.com (2603:10b6:806:299::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.35; Thu, 17 Jul 2025 18:34:11 +0000 Received: from PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8]) by PH8PR11MB8107.namprd11.prod.outlook.com ([fe80::6b05:74cf:a304:ecd8%6]) with mapi id 15.20.8922.028; Thu, 17 Jul 2025 18:34:11 +0000 From: Dan Williams To: , CC: , , , , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , "Aneesh Kumar K.V" Subject: [PATCH v4 10/10] samples/devsec: Add sample IDE establishment Date: Thu, 17 Jul 2025 11:33:58 -0700 Message-ID: <20250717183358.1332417-11-dan.j.williams@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250717183358.1332417-1-dan.j.williams@intel.com> References: <20250717183358.1332417-1-dan.j.williams@intel.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To PH8PR11MB8107.namprd11.prod.outlook.com (2603:10b6:510:256::6) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH8PR11MB8107:EE_|SN7PR11MB7066:EE_ X-MS-Office365-Filtering-Correlation-Id: af15a120-dfda-4824-499a-08ddc560862c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|7416014|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?hshg4qp21H88qYTsFQCBwgTjvyPWF+hBqf/r+Nf2Yew/K8KOUJfdLu4/zt7x?= =?us-ascii?Q?488asTv9M2cmIBRaU6ImrRvRiVOrxJ5R7Rg0bU2PgCVju5OUmGOlDwWp2YOh?= =?us-ascii?Q?+3lp0DagSb9tVnyJLi4mSCfFrOltmDJiciqgqiuq//jWbtuPiNqWbJ4C3B/r?= =?us-ascii?Q?O0zjBl4tCl2C8Tt986KIsyda0pfm7rwkLaK3zhdE4Uw+UaxoTT83pKBMqyaQ?= =?us-ascii?Q?JYI0v01ki9HwxD/NTtb/04AcmGqmxshsYx/O/IdCo1hs4m1uWARDEGflYavp?= =?us-ascii?Q?6kni+DKlaEiM1AhQFcfsoBW5zvz/5rqvRG0sZNVo35gyjnM5z1ZE5CHnWBlb?= =?us-ascii?Q?7lGxK+DQ+n4FJGl4R5PN5mpuD2TU9+nYrDQPR3q+QtwlEPTQGGfsPL5wu9jk?= =?us-ascii?Q?d9h3rkjEeHKgp273qtPsV4I2ZgJdQa7eLA1f5a/YNwppv70WRBoF46E6cSHa?= =?us-ascii?Q?nTH6KNnxOeOIggxTckbWRMdQ4uxHjIXWRUGuf3tjrzf0EjsF3bSmj6IYEmqX?= =?us-ascii?Q?EYVoR/p1bPAOVTc8ARXVV5+BD3gaTzA4T5knbnx4oS2AAQcQVkjridUkdPzm?= =?us-ascii?Q?krCIw/Tz1OeGlYZgljrOEY0HXjQIB4TF93AuwFH1RTlkLjnufbCTCEHiiMY5?= =?us-ascii?Q?mtA2I1/MtbJRiAwM9gfDBkIWRZ9zT/kp8wRS32YnTEtUkVRL1MppWG9JLm2T?= =?us-ascii?Q?T5zQWVlLbva2x2dDGm7HIP9d7HnGsbVdiacYR7T72NskUT7HYHIh62xTnBoa?= =?us-ascii?Q?788NX/ZDsH1oDtdh1TP46x1f4YwiE8tVgQweIEiDKkUjAdMpGo2HtwdlifX5?= =?us-ascii?Q?UhcOnFQLD5DNk2yCoJldqJgxuQxIODEsGgacIqQG8q7JlOHg1XmCCy3OP3f1?= =?us-ascii?Q?/1zuo0n/GqxbZq4Cy+VfqjiVcL0Vkf8/pXWCdB/52uKTgE4LRXO9QYzMOGaB?= =?us-ascii?Q?CjP7FvzGApswATGNMquErxnI+4eq/dLhOiXVxshaExPXExB57t4mYvhH5V0i?= =?us-ascii?Q?ck3onFGbpsT2JUhayGfkZvl/PMJ5CIbP80Lx3YdNwVbe0UiTG/uwzZOYq/bi?= =?us-ascii?Q?0rmaMb5kq0UhIp8eXY3BWV9hJWR1qet31/hBSe6C8V4sUIG2SPYYsbplx3EF?= =?us-ascii?Q?AwBeCDz7JNWdYZaGxo9j91GDwaqaXCezvIXaiFoJJveriJVYuJoVos51PuC0?= =?us-ascii?Q?tsJlNPT1Co1QZqs9oWkF4L+dQ9IEptkehHVNdFEENWTJ4sIpxVKd4r/RxZH3?= =?us-ascii?Q?xVeLQjeIP5hfikTHrHiFS7SuUVW8GcO+ceb/oQNVtSz/Ka4NHhmsJvFcubNB?= =?us-ascii?Q?q5B09zR5sgoBPJhZM6Y0TSaoPl7k+JiYhxsI00wQfMcXez5omgSmH0Mi1Tej?= =?us-ascii?Q?TdA2t2XJ9ykpA0MaqiCPfdpbgMrdSg0V5KHsTXqTRJvCR4ccgDN8FkBolXIZ?= =?us-ascii?Q?j4EuSS/Rv08=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8107.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(7416014)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ttcIKHy93YJsOyBVjy3jP9yGLOAV98Z98Y4dZtR4ezC02GaB0YeRU6s6VI06?= =?us-ascii?Q?TiLBfr7MZcgJG3EQEhTe90CA9mRa8Px6smKlAb394gt43Zv7PyQIb+mo0j8d?= =?us-ascii?Q?Aa6uSihj8ISsy3FqxYli7vA6ezeTxAyvyeNz9BYQC3L5G/JM3iQvq+Kpy17m?= =?us-ascii?Q?GpUQDIM+IjzmuHnc+b+1qedRTMfM3jWXklz6em+BMc6Kri4CBnIn1jKfH7Gl?= =?us-ascii?Q?duJ1IGkr/mp3qtpw9X6OwCvDLjh/I+RoU3+5XUiLY1ShzzUn3JK1Ys/zm08V?= =?us-ascii?Q?RbdtPsbmy5P9NjAaCc5AdzyI+UUnewJDJDPBQwbAkXBE7bLctV0YAJzlGP7N?= =?us-ascii?Q?hxj4/j663DKByDwrV/J0PWAYhNa0ze0PIsDM84ZwUN1uVyQcjUZZ4iqjCNE9?= =?us-ascii?Q?N14q4UstDVwP5cPy/HZJNVEDiFW9ft3aMi9YXC7A6ioQ0aEKRRXYgl5nrQVC?= =?us-ascii?Q?Jbktq4za6Y19bFIxQyEPTHab7Af51pqnFFzHTUFfEm9bJhFvpx1nbgggVWYs?= =?us-ascii?Q?nb1O5cUOo4p8RiIMEeVHvgBXNNPaem3QZG3BVIzX1CY/Nh/dLe9OblUyE0vq?= =?us-ascii?Q?QB2MHvXjRs7xWGbq6QMFuoCqQkK/+OLWHz8aD1mVrGlouW09OYoq5sWk5kt9?= =?us-ascii?Q?AJjJtwoDskj4y0nQ/zaOO59/eTxDuiZGDcR4TRbOCr9iFrgO8oC+Jos6u6RL?= =?us-ascii?Q?M5wrzwOfB2PLvPWFTCR/n3f1Fl6eaHXdPRIeWT0FyEhBBjvBGcDIbMiwQB1L?= =?us-ascii?Q?8kfnKQkuMWhNJpJ9Xztt2KvvJsdSoSfbTPty3XzSarPz0OgHSZOJ8Brfad+o?= =?us-ascii?Q?Si+KxMnPstY3Z9Tjcl1+ibvkDPBRWDy0A/xtxoQYErLseiC5p6jxlLD2Y5Vj?= =?us-ascii?Q?vIuuQq2iHXb6Jja1rM7CuBh+/yfipbI2t6J6MbGombjkDFUgwgW2eVuVJc/C?= =?us-ascii?Q?jaP3oxI6P58gSyViuzBj3pCXr5RxHVomBu3hHA03bsE5TZzsZlmW9iWUGjBv?= =?us-ascii?Q?X/8J0sNunjDJpl2EFWjtyZNx5fJQN980z4WqSNpFSdrbTQ7sb5frU07gTcfv?= =?us-ascii?Q?7ePCfPfclpvenDUhSzjCHBQyqUlJL8WHQXX3sZlQJYnIZWuPtx6YiFYrZsSf?= =?us-ascii?Q?3G6M/4vMPofVybTm6MEf4JBJlNv8Iy64nXgD02mfkDMhxguEuFrm3NPX+mqx?= =?us-ascii?Q?9ZXDPWpbnj+8MMsVEwOkSqahVb/7fhcAfy8vWEPWFlv7gGW+AqU/quXbdlxC?= =?us-ascii?Q?pSp5M+5W1t98Qi2YuFyL4EuFFxHGUlnyTtsYdGEfSlIT84qQ53sd6IQbc64F?= =?us-ascii?Q?2WiynleWQYSSiwk8KWw9o4Y6Jfm+h/OO/bl861KIPtG66FdsW0x4k2OCRcW9?= =?us-ascii?Q?khoKb+vby10KITo2Droe/ybLwvBdTlJ56c/aukDx0FAYkBSY467ud+L5FjPM?= =?us-ascii?Q?4SiwO7YY0BDu8Q+pXhnPlR8iqniuu4DxJnMYKNFHBeAoe1yxvnyelMrgWXxy?= =?us-ascii?Q?Hudg2LCZRzhEJq0wOJ/4xhmn6wjX4cAs3xxcVAOkDQgbfEKwD89YFQLcpLWs?= =?us-ascii?Q?4QgERxhs5KIN1cxYCKPjMMCXdOo4vTPrqWXwL4FN7yCjJsTDvrQO7pgVUsCN?= =?us-ascii?Q?gw=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: af15a120-dfda-4824-499a-08ddc560862c X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8107.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2025 18:34:11.6907 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xDPXSdqxOhJpeWkSoxtuikwZ4dxF59SIJ+JwEPsnaP3CRkuqnJ6Sw4aAC8k8CAurO858kNjSoYnvaWZ8rk/E0K5NjZxbCWyo7W1q6dzoALA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7066 X-OriginatorOrg: intel.com Content-Type: text/plain; charset="utf-8" Exercise common setup and teardown flows for a sample platform TSM driver that implements the TSM 'connect' and 'disconnect' flows. This is both a template for platform specific implementations and a simple integration test for the PCI core infrastructure + ABI. Cc: Bjorn Helgaas Cc: Lukas Wunner Cc: Samuel Ortiz Cc: Alexey Kardashevskiy Cc: Xu Yilun Cc: Suzuki K Poulose Cc: "Aneesh Kumar K.V" Signed-off-by: Dan Williams --- samples/devsec/bus.c | 3 ++ samples/devsec/tsm.c | 70 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/samples/devsec/bus.c b/samples/devsec/bus.c index 675e185fcf79..efd7a650b20d 100644 --- a/samples/devsec/bus.c +++ b/samples/devsec/bus.c @@ -15,6 +15,7 @@ =20 #define NR_DEVSEC_BUSES 1 #define NR_DEVSEC_ROOT_PORTS 1 +#define NR_PLATFORM_STREAMS 4 #define NR_PORT_STREAMS 1 #define NR_ADDR_ASSOC 1 #define NR_DEVSEC_DEVS 1 @@ -662,6 +663,7 @@ static int __init devsec_bus_probe(struct platform_devi= ce *pdev) hb->dev.parent =3D dev; hb->sysdata =3D sd; hb->ops =3D &devsec_ops; + pci_ide_init_nr_streams(hb, NR_PLATFORM_STREAMS); =20 rc =3D pci_scan_root_bus_bridge(hb); if (rc) @@ -704,5 +706,6 @@ static void __exit devsec_bus_exit(void) } module_exit(devsec_bus_exit); =20 +MODULE_IMPORT_NS("PCI_IDE"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Device Security Sample Infrastructure: TDISP Device Em= ulation"); diff --git a/samples/devsec/tsm.c b/samples/devsec/tsm.c index a4705212a7e4..b93396ca0c92 100644 --- a/samples/devsec/tsm.c +++ b/samples/devsec/tsm.c @@ -4,6 +4,7 @@ #define dev_fmt(fmt) "devsec: " fmt #include #include +#include #include #include #include @@ -92,6 +93,23 @@ static void devsec_tsm_pci_remove(struct pci_tsm *tsm) } } =20 +/* protected by tsm_ops lock */ +static DECLARE_BITMAP(devsec_stream_ids, NR_TSM_STREAMS); +static struct pci_ide *devsec_streams[NR_TSM_STREAMS]; + +static unsigned long *alloc_devsec_stream_id(unsigned long *stream_id) +{ + unsigned long id; + + id =3D find_first_zero_bit(devsec_stream_ids, NR_TSM_STREAMS); + if (id =3D=3D NR_TSM_STREAMS) + return NULL; + set_bit(id, devsec_stream_ids); + *stream_id =3D id; + return stream_id; +} +DEFINE_FREE(free_devsec_stream, unsigned long *, if (_T) clear_bit(*_T, de= vsec_stream_ids)) + /* * Reference consumer for a TSM driver "connect" operation callback. The * low-level TSM driver understands details about the platform the PCI @@ -116,11 +134,61 @@ static void devsec_tsm_pci_remove(struct pci_tsm *tsm) */ static int devsec_tsm_connect(struct pci_dev *pdev) { - return -ENXIO; + struct pci_dev *rp =3D pcie_find_root_port(pdev); + unsigned long __stream_id; + int rc; + + unsigned long *stream_id __free(free_devsec_stream) =3D + alloc_devsec_stream_id(&__stream_id); + if (!stream_id) + return -EBUSY; + + struct pci_ide *ide __free(pci_ide_stream_release) =3D + pci_ide_stream_alloc(pdev); + if (!ide) + return -ENOMEM; + + ide->stream_id =3D *stream_id; + rc =3D pci_ide_stream_register(ide); + if (rc) + return rc; + + pci_ide_stream_setup(pdev, ide); + pci_ide_stream_setup(rp, ide); + + rc =3D tsm_ide_stream_register(ide); + if (rc) + return rc; + + /* + * Model a TSM that handled enabling the stream at + * tsm_ide_stream_register() time + */ + rc =3D pci_ide_stream_enable(pdev, ide); + if (rc) + return rc; + + devsec_streams[*no_free_ptr(stream_id)] =3D no_free_ptr(ide); + + return 0; } =20 static void devsec_tsm_disconnect(struct pci_dev *pdev) { + struct pci_ide *ide; + unsigned long i; + + for_each_set_bit(i, devsec_stream_ids, NR_TSM_STREAMS) + if (devsec_streams[i]->pdev =3D=3D pdev) + break; + + if (i >=3D NR_TSM_STREAMS) + return; + + ide =3D devsec_streams[i]; + devsec_streams[i] =3D NULL; + pci_ide_stream_release(ide); + clear_bit(i, devsec_stream_ids); } =20 static struct pci_tsm_ops devsec_pci_ops =3D { --=20 2.50.1