From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010060.outbound.protection.outlook.com [52.101.201.60]) (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 2DB533E9C1A for ; Tue, 7 Jul 2026 10:52:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.60 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783421541; cv=fail; b=dXrF4qXLuO1RGCOeYNBPdTo4+C0NmTJiTVFdWEvKxsKulVpzuI3MiyIgC7kANdCv93rGip66eR1SRXbUqtJ0mwLqDkmGoWJ3z2CYgEsclNQeQ+nhWUUCE9FEVl58o4KoZFxknbTZ1l1z+GFMp8VWvtvP8jPxYEpFDXbyDqiG/hU= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783421541; c=relaxed/simple; bh=3iViNPzcl62P5PiLOIgR9uzXedVAgIXd9slMAYQtfjA=; h=Message-ID:Date:Subject:To:Cc:References:From:In-Reply-To: Content-Type:MIME-Version; b=r4xsmKZE8EO8oMvEl4c6gc0sj1cJwM+1z1QvbopkLtymP4saQtKKLW/dZKDDT5FfjTpcHX8pZKzY7KY1EZ/14iMi2lcZEUfqyDmsGHXRK/hlqIMpYA7gEq2t7g/t17iz9wYKRdgwloHws2pRZma3zFKZV0VPDsqV7Q2KqGOuG9s= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=hz2zadOc; arc=fail smtp.client-ip=52.101.201.60 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="hz2zadOc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IkI2H6S+BADJGZ1EiIzLWI5tcokNjuestRVJUEvKzPg+YkhSLIWRXd3T7IYy15+VfZz8SXe9Aoe0lS5kUi4uNwaC2WG1TFRLlhiJKPGk88BTvSnvN7QoB+XZgh7JEz9wYWp2AQz4aF4JkSewOAREnSNnGJ31cVmXnMtrsXoF7Ftnj13vpr8Iv0+RDK8Do9W0WIWKCnsQU4XA7mlVrB1W9vEK+PqCuggdULjW0/6/Ew3w+s9B5e85O4PMcx4F2dG9KaIfCziPyN72MMxMGg9lsJtaSX0FGUwvf0VATDxS1A94XZ2keoTMPberAmqkbUgwYEvppvouy7Ee5cHduhwzeQ== 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=juueln1VjnKA+eWZp0P+hXQc32z380xanIn8HIv/E2A=; b=Q+RT3Wc5Zm35N4wPoz4osTTYnNZeQLZ/E8/kUIpZgdruWpTET6WzeMGWrKk+ZMQarL5ZSVIue9zgGS04klpy62kmPU1O4PXP4GfqDKsORvndblrhDpWde59gi3jO+R5YqnYInRNVGFrhm450Cx//SBEBXSexMq/W3T8d1xG3Ha+cg5A2kknZqMrYnmd5z5WzZhBf7SV4x3PvoAlOeTcvbJy4je8kj1vCO8Qpu1p1xZPu6AJNlbJxKH2wfbIa1Khb0Qps6a7MFHlWJDVGwCzxLWcRZuV2M9sQOST883Ib4VqgDzH/mJ/6/l1026//V7rQL21obgxD9pLbrsQIWavmgw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=juueln1VjnKA+eWZp0P+hXQc32z380xanIn8HIv/E2A=; b=hz2zadOcaPxmZvZvLInzkI0gkuRFKoJquvDokoRl8NkhYW1tlRiv9mkvOiPA9yOx+zv8TFo0bRfezCvkFnq1LAQA9G1B/COXflW9TUbxX/EOB5jY6U3llq7ouoTONNrK8tJpxQCL31fAeQ5vul/HEoA1KiYz6broYfU+O+Noch4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com; Received: from DS7PR12MB9549.namprd12.prod.outlook.com (2603:10b6:8:24e::7) by MW3PR12MB4377.namprd12.prod.outlook.com (2603:10b6:303:55::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.181.13; Tue, 7 Jul 2026 10:52:15 +0000 Received: from DS7PR12MB9549.namprd12.prod.outlook.com ([fe80::bace:1330:9ab2:acc6]) by DS7PR12MB9549.namprd12.prod.outlook.com ([fe80::bace:1330:9ab2:acc6%6]) with mapi id 15.21.0181.009; Tue, 7 Jul 2026 10:52:14 +0000 Message-ID: <715d72b7-c568-4295-963a-d2d361d373f3@amd.com> Date: Tue, 7 Jul 2026 16:22:08 +0530 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 2/2] misc: Add Xilinx PUF driver To: Greg KH Cc: arnd@arndb.de, michal.simek@amd.com, linux-kernel@vger.kernel.org, sarat.chand.savitala@amd.com, nkowlaku@amd.com References: <20260707095620.2795456-1-h.jain@amd.com> <20260707095620.2795456-3-h.jain@amd.com> <2026070704-encrypt-pavilion-0549@gregkh> Content-Language: en-US From: "Jain, Harsh (AECG-SSW)" In-Reply-To: <2026070704-encrypt-pavilion-0549@gregkh> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-ClientProxiedBy: MA5PR01CA0138.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:1d5::10) To DS7PR12MB9549.namprd12.prod.outlook.com (2603:10b6:8:24e::7) 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: DS7PR12MB9549:EE_|MW3PR12MB4377:EE_ X-MS-Office365-Filtering-Correlation-Id: 97c21c75-46a2-4529-aaf8-08dedc15ce10 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014|23010399003|22082099003|18002099003|6133799003|3023799007|5023799004|56012099006|4143699003|11063799006; X-Microsoft-Antispam-Message-Info: n9jv91j45jz4Fef58A+1DPfx6T3EOB4ZdJY3PQF1NDPjMaNE+NnJ9MiE3Gr4dGwEVrMl7ZwjAmntHq3AV2orHsHxGOrsQgqJGLM07G2ZDZIKZf5Dfy/CLlPug5yAN9kZrlhSmZcLVYdHUA2p0p/GimNnHMy1cYFbHLtREYFBjaD4xynOFdWQ7BdXAMyO1p4gdXbQZOwGMCTgyOV688jpanELDWzNHPxYr9EV2QzHh7gseRv2jXhem4kd2zAJv6caqK15P1oqf3cTeH0dYzY5rm5PsrroIJQVRUXg9a4ICbVfdB3NfOgWoEVem4AeVdScFAbke2dhZOCm+OuAC8wv/GKun2EV6ohn1lzAQLh4vaKY05BrLSvsrY3x72T4G+EaxOPkuTtJwCKrX+XT0uiFI6TBUJWuyQwJ7UcunBkEE5XxL4/a1M4AfDSXmAXpB4PoKz03QcZ3ycGTOOTlqBrY1jraZSLT8Rt33RDWF+Qk8NPC/cyF0fqDlRpWrEQS3F9VWf7pIdhESRmQd141m2IILvh7/0PPKsRogKUdtJ5QCQAbmnTwFuc/5RkTnOE4Bhm7azlxGR+cpOaJH409dVJTjxezVVb0HrMXfRLXaHhWrlh8ADhw5GyhKls4ebmjhpdm3qmxwVxZQOQmed2zAXaAMMPd/QR1UaUJY1MzxhhyAQQ= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB9549.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(1800799024)(376014)(23010399003)(22082099003)(18002099003)(6133799003)(3023799007)(5023799004)(56012099006)(4143699003)(11063799006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?S2FKWmVsSjYra1JrZDN2RzBBVzM3SHN5TlJ3RXpDYnQ1ODVRaWh3TXlmSURq?= =?utf-8?B?ZHorNzkxeWdDWGJTaXo4VEQ4RFFiSHFWNFhrUjdGZHNJMVN1TUMrNGo3WXo0?= =?utf-8?B?R2ZRTzdPcmZUWFRTRnZBYTJ0clNCL0dQaGYrMk5XZ0hxZFJ5WWwzQ0lKK0J5?= =?utf-8?B?SzFmbTN5RDFPaGNGL09Oa3A5emxSM1I5QVYxeTdlQ2ZWMjR6Rnh2aTMzS0M4?= =?utf-8?B?SEluVXNDZytwanA3Ymo1cmQ1VGxBZ09WcVNKQnRpVnhIenppeHM5ZWFpRjlk?= =?utf-8?B?cW5CWGtmZW1MUXdJVjFvNG83SHNCVnBCVGZoNDFKWnpxb1NwR2ViUThLUGhw?= =?utf-8?B?MWFDR2dkWldYY1FMQVBSYXhSUys4aHpKM0JZV2JVUG41b0VhWGt1TThrbXU4?= =?utf-8?B?OG1Lb0lwNitnRGtlREIvWmRXL25vVlh4SUROc01XZ2wwMnZISTJIWkx1b0lU?= =?utf-8?B?YWlrcU1hMVBmeElmRFQxblFTQmtYU3RRMVYraXI1L3pmUXVCeGVtSkZKbi9i?= =?utf-8?B?NGVsRng4THB0QnMwcWNrd1lTVmt0ZTVhekxZWlJDVFRUNWduT2lTRGw2eFpG?= =?utf-8?B?Tk04Zkc5OFdFdlAzNTArSnZaRmV2YmFOU3hnRkRSY0JoSzJrRlZORS9yWERG?= =?utf-8?B?WHJaVS91QkRYU2dJSHArdDdoMU1vSnVVYXluQVdqWG9LdVZuUGxtYzU3dHBs?= =?utf-8?B?TURuWnJSbWRYVklmRDlvYzNCQUFHa0RVRGw5VXEvRFQ0WUlNaW9sWG1SckZq?= =?utf-8?B?ZkJOUlBjdE5pL2VQSVU5VHZvdmY2eEdCYmN6SnlybHJjZnZQdVVRL1RhcDdW?= =?utf-8?B?eWFCUUhVS1M5WTY5bDN4U2Z0VExWbTMyVFRGK3NZUGJwY3pucyszcTJQYis0?= =?utf-8?B?cWZ6cmsxMTk1bEFpZTJFdHVTUStJaVVuc3FmcTZBdjEwdHA4Zi9jNS9mTmpi?= =?utf-8?B?S1k5L0VOZEFNUDhJOFVpZVZWVU94V3E4STczMWZWYUlETDlISkxWb2F2b0Yr?= =?utf-8?B?VTZwT0JIQVNjVGcranc2RENjVlBpT2hadURSekRaU0dyaGV6V0dQUFZhZUZP?= =?utf-8?B?OGhuemZFTGNaU3dJZ0lyS3BqczJueEdwZDIxbFJOcU9aanhvaDlkc0JJM0dk?= =?utf-8?B?SXFwUVh1NU5WcUFGUE9wZnNTc1JKK1RnbENuR3dIMnA1bGhBNytDNTZxRmtB?= =?utf-8?B?NHhuOXBnTjZKZnJBQ2hrWWlUSXpUYm1WVEozcDJ6N2dqRGN5K1V0aE5zd2pn?= =?utf-8?B?VGhFd2dmaHF2cXIvQlZQM1EyL1JkWi9oOHF4Y3NuU3lYWVZZMHN6SzN5NzJh?= =?utf-8?B?bTdnSTVCNzFWM0lWOEVFT1pES2NiOTdVbFFjdzBEWlFSWk9hV1VzV0NpWlFx?= =?utf-8?B?bDRvNGNLRTJraU1PZXREaDhVc3pkMldRK1BQMGtpbGRMejczTlJlbDVnMDd2?= =?utf-8?B?SWRTR09oR2ZSOFJnZFNsVjhNcGpVcWt4Lys4UzhjQUhDeHViZWs4YThWeG44?= =?utf-8?B?ZHNOYko0aS95ckFlK216UWMzR2RFeVZsdUdzalkyaHA5U29KQ1liQUF0R3VB?= =?utf-8?B?MXgwZHY1Zi8rODJvbVJ1Sld5dGxRenorYWFtK3luVHFuMEJjRW1nSVJqNmNN?= =?utf-8?B?MXVPeGVBZ0pWVkNpU3RrZXFhWHBGU2pGcUhiT0w4cGhqZHcyY2xjS2YrZXFF?= =?utf-8?B?WGVjWkRIV0tyTWFoazZqaDR3MWNPUm5RZHJWbzR3WDJqa1dnQ1YwT2NHcVdp?= =?utf-8?B?VFo3UjRTUis2TzMyeFFFcmVJcld0SkpDWkVrYUZrSVZNRGNYTHo3VDVIZDEw?= =?utf-8?B?Ky8wd0lQS2dzWExubUo3Z0pNbkFuenQyM2hKTVdYZkVJVVdCdk8zcjVseEVs?= =?utf-8?B?dFBTY20wTytsT1ZBMEt5ZGVKbjNhY2pQTlo1STRXSTNRODVGYUpCZ1VUNllH?= =?utf-8?B?NnpZOW5QT0NjOEN4czZweFEzTDc1L28vV1VOKzV5THNRUFlRYnpsdmhVYVJn?= =?utf-8?B?T2R4bUh1bnBTN3U4SzB3Y0cvNC9SQ0xWaTg3cnpEVkJNNG5CQkg1Z2luUmhy?= =?utf-8?B?ZDhVOWY2Qi9JZS9PTkd6NHhMckMzMzNPaFdhKzhGN2hrZFlQMmxVZzRGZzYz?= =?utf-8?B?dzk5YmhDdFVwc0ZBQm0yOEpKWGlGL2pjR1VxR1A1SWJIRWUxYWZUYU9Fb2sr?= =?utf-8?B?cFhXN3BVMmYwa0tWZExRTDVwOWc5amFUSWw4SXhNdWN2RnFldW1Yd085Mm1N?= =?utf-8?B?OERkRXVhTU9TVk94bi9JMHo0V3NHQTQyRGtDYVlHTUV2dFVKeUtRR2hWYVF5?= =?utf-8?Q?LeNu9fREsNQvigCmiE?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 97c21c75-46a2-4529-aaf8-08dedc15ce10 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB9549.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Jul 2026 10:52:14.4176 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: /tzzAcJXqZc9LZwTGRb3ytHwLpQCByQsi+d22CptKweiFjy8flTyPiwtrzbtgz7p X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR12MB4377 On 7/7/2026 3:42 PM, Greg KH wrote: > Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding. > > > On Tue, Jul 07, 2026 at 03:26:20PM +0530, Harsh Jain wrote: >> Versal devices contain a physically unclonable function (PUF) block >> that derives device-unique secrets from intrinsic silicon >> characteristics. The PUF generates a Key Encryption Key (KEK) used >> internally by the AES engine for secure key storage, which is not >> externally accessible. In addition, the PUF provides a readable >> device-unique identifier derived from the same entropy source. > So why isn't this tied into the normal crypto/keys/tee/whatever > subsystem for this type of hardware? Why is a custom user/kernel api ok > for this one specific piece of hardware? > > And where is the userspace code that interacts with this? We will check crypto and keyctl subsystem > >> Add a misc character driver to support PUF registration and regeneration. >> Registration generates a unique secret and outputs binary helper data >> that can later be used during regeneration to reproduce the same >> secrets. >> >> The driver also implements PUF_CLEAR_ID and PUF_CLEAR_KEY ioctls to clear >> the PUF ID and PUF-derived AES key via firmware. They are disabled by default >> unless puf_clear is set. > Please wrap the changelog at 72 columns, checkpatch should have caught > this, right? I ran it on files instead of patches. Will take care next time. Thanks for quick reply, > >> Signed-off-by: Harsh Jain >> --- >> MAINTAINERS | 6 + >> drivers/misc/Kconfig | 11 + >> drivers/misc/Makefile | 1 + >> drivers/misc/xilinx_puf.c | 377 +++++++++++++++++++++++++++++++++ >> include/uapi/misc/xilinx_puf.h | 82 +++++++ >> 5 files changed, 477 insertions(+) >> create mode 100644 drivers/misc/xilinx_puf.c >> create mode 100644 include/uapi/misc/xilinx_puf.h >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 15011f5752a9..a46a34f163b4 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -29546,6 +29546,12 @@ L: netdev@vger.kernel.org >> S: Orphan >> F: drivers/net/ethernet/xilinx/ll_temac* >> >> +XILINX PUF DRIVER >> +M: Harsh Jain >> +S: Maintained > You aren't paid to support this? AMD doesn't care? That's sad. > >> +F: drivers/misc/xilinx_puf.c >> +F: include/uapi/misc/xilinx_puf.h >> + >> XILINX PWM DRIVER >> M: Sean Anderson >> S: Maintained >> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig >> index 390256ed91f4..98ec00765647 100644 >> --- a/drivers/misc/Kconfig >> +++ b/drivers/misc/Kconfig >> @@ -490,6 +490,17 @@ config XILINX_SDFEC >> >> If unsure, say N. >> >> +config XILINX_PUF >> + tristate "Xilinx PUF driver" >> + depends on ZYNQMP_FIRMWARE >> + help >> + This option enables support for the Xilinx Physically Unclonable Function >> + (PUF) driver on AMD Versal devices. >> + It is a configurable driver to generate PUF KEK source either by using >> + PUF registration or regeneration command. >> + >> + If unsure, say N. > Module name? > >> + >> config MISC_RTSX > > >> tristate >> default MISC_RTSX_PCI || MISC_RTSX_USB >> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile >> index fed47c7672b9..66d1ea5d1f13 100644 >> --- a/drivers/misc/Makefile >> +++ b/drivers/misc/Makefile >> @@ -55,6 +55,7 @@ obj-$(CONFIG_BCM_VK) += bcm-vk/ >> obj-y += cardreader/ >> obj-$(CONFIG_PVPANIC) += pvpanic/ >> obj-$(CONFIG_UACCE) += uacce/ >> +obj-$(CONFIG_XILINX_PUF) += xilinx_puf.o >> obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o >> obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o >> obj-$(CONFIG_NTSYNC) += ntsync.o >> diff --git a/drivers/misc/xilinx_puf.c b/drivers/misc/xilinx_puf.c >> new file mode 100644 >> index 000000000000..ad8ada58b105 >> --- /dev/null >> +++ b/drivers/misc/xilinx_puf.c >> @@ -0,0 +1,377 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Driver for Xilinx PUF device. >> + * >> + * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc. >> + * >> + * Description: >> + * This driver is developed for PUF registration and regeneration support. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +static bool puf_clear; >> +module_param(puf_clear, bool, 0600); >> +MODULE_PARM_DESC(puf_clear, "Flag to enable clearing of PUF ID and key."); > This is not the 1990's, please do not add module parameters for things > that should be done other ways. Especially for a device-specific thing. > >> + >> +/** >> + * struct puf_params - parameters for PUF >> + * @pufoperation: PUF registration or regeneration operation >> + * @globalvarfilter: global variation filter >> + * @readoption: option to read PUF data from efuse cache or ram address >> + * @reserved: explicit padding to match the Versal PLM PUF parameter layout. >> + * @shuttervalue: shutter value for PUF registration/regeneration >> + * @readsyndromeaddr: address to store the syndrome data during registration >> + * @chashaddr: CHASH address >> + * @auxaddr: AUX address >> + * @pufidaddr: PUF ID address >> + * @writesyndromeaddr: address where syndrome data is present and it is passed to the user >> + * @trimsyndataaddr: trimmed syndrome data will be stored >> + */ >> +struct puf_params { >> + u8 pufoperation; >> + u8 globalvarfilter; >> + u8 readoption; >> + u8 reserved; >> + u32 shuttervalue; >> + u64 readsyndromeaddr; >> + u64 chashaddr; >> + u64 auxaddr; >> + u64 pufidaddr; >> + u64 writesyndromeaddr; >> + u64 trimsyndataaddr; >> +}; >> + >> +/** >> + * struct xpuf_dev - Driver data for PUF >> + * @dev: pointer to device struct >> + * @miscdev: misc device handle >> + */ >> +struct xpuf_dev { >> + struct device *dev; >> + struct miscdevice miscdev; >> +}; >> + >> +static int xlnx_puf_regis(struct xpuf_dev *puf, struct puf_usrparams *pufreq) >> +{ >> + struct puf_params *pufin; >> + struct pufdata *pufdat; >> + dma_addr_t dma_addr_data; >> + dma_addr_t dma_addr_in; >> + u32 buflen; >> + void *buf; >> + int ret; >> + >> + if (pufreq->pufoperation != PUF_REGIS) >> + return -EINVAL; >> + >> + if (pufreq->readoption != PUF_READ_FROM_RAM && >> + pufreq->readoption != PUF_READ_FROM_EFUSE_CACHE) >> + return -EINVAL; >> + >> + buflen = sizeof(struct puf_params) + sizeof(struct pufdata); >> + buf = kzalloc(buflen, GFP_KERNEL); >> + if (!buf) >> + return -ENOMEM; >> + >> + pufin = buf; >> + pufin->pufoperation = pufreq->pufoperation; >> + pufin->globalvarfilter = pufreq->globalvarfilter; >> + pufin->readoption = pufreq->readoption; >> + pufin->shuttervalue = pufreq->shuttervalue; >> + >> + pufdat = buf + sizeof(struct puf_params); >> + dma_addr_in = dma_map_single(puf->dev, buf, buflen, DMA_BIDIRECTIONAL); >> + if (dma_mapping_error(puf->dev, dma_addr_in)) { >> + ret = -ENOMEM; >> + goto cleanup; >> + } >> + >> + dma_addr_data = dma_addr_in + sizeof(struct puf_params); >> + pufin->readsyndromeaddr = (u64)dma_addr_data; >> + pufin->chashaddr = (u64)(pufin->readsyndromeaddr + sizeof(pufdat->pufhd.syndata)); >> + pufin->auxaddr = (u64)(pufin->chashaddr + sizeof(pufdat->pufhd.chash)); >> + pufin->pufidaddr = (u64)(pufin->auxaddr + sizeof(pufdat->pufhd.aux)); >> + pufin->trimsyndataaddr = (u64)(pufin->pufidaddr + sizeof(pufdat->pufid)); >> + >> + dma_sync_single_for_device(puf->dev, dma_addr_in, buflen, DMA_BIDIRECTIONAL); >> + ret = versal_pm_puf_registration(dma_addr_in); >> + dma_unmap_single(puf->dev, dma_addr_in, buflen, DMA_BIDIRECTIONAL); >> + if (ret) >> + goto cleanup; >> + >> + if (copy_to_user(u64_to_user_ptr(pufreq->pufdataaddr), pufdat, sizeof(struct pufdata))) { >> + ret = -EFAULT; >> + goto cleanup; >> + } >> + >> +cleanup: >> + kfree(buf); >> + >> + return ret; >> +} >> + >> +static int xlnx_puf_regen_id(struct xpuf_dev *puf, struct puf_usrparams *pufreq) >> +{ >> + struct puf_helperdata *pufhd; >> + struct puf_params *pufin; >> + dma_addr_t dma_addr_data; >> + dma_addr_t dma_addr_in; >> + u32 buflen; >> + void *buf; >> + int ret; >> + >> + if (pufreq->pufoperation != PUF_REGEN && >> + pufreq->pufoperation != PUF_REGEN_ID) >> + return -EINVAL; >> + >> + if (pufreq->readoption != PUF_READ_FROM_RAM && >> + pufreq->readoption != PUF_READ_FROM_EFUSE_CACHE) >> + return -EINVAL; >> + >> + buflen = sizeof(struct puf_params) + sizeof(struct puf_helperdata) + >> + PUF_ID_LEN_IN_BYTES; >> + >> + buf = kzalloc(buflen, GFP_KERNEL); >> + if (!buf) >> + return -ENOMEM; >> + >> + pufin = buf; >> + pufin->pufoperation = pufreq->pufoperation; >> + pufin->globalvarfilter = pufreq->globalvarfilter; >> + pufin->shuttervalue = pufreq->shuttervalue; >> + pufin->readoption = pufreq->readoption; >> + >> + pufhd = buf + sizeof(struct puf_params); >> + if (copy_from_user(pufhd, u64_to_user_ptr(pufreq->pufdataaddr), >> + sizeof(struct puf_helperdata))) { >> + ret = -EFAULT; >> + goto cleanup; >> + } >> + >> + dma_addr_in = dma_map_single(puf->dev, buf, buflen, DMA_BIDIRECTIONAL); >> + if (dma_mapping_error(puf->dev, dma_addr_in)) { >> + ret = -ENOMEM; >> + goto cleanup; >> + } >> + >> + dma_addr_data = dma_addr_in + sizeof(struct puf_params); >> + pufin->writesyndromeaddr = (u64)dma_addr_data; >> + pufin->chashaddr = (u64)(pufin->writesyndromeaddr + sizeof(pufhd->syndata)); >> + pufin->auxaddr = (u64)(pufin->chashaddr + sizeof(pufhd->chash)); >> + pufin->pufidaddr = (u64)(pufin->auxaddr + sizeof(pufhd->aux)); >> + >> + dma_sync_single_for_device(puf->dev, dma_addr_in, buflen, DMA_BIDIRECTIONAL); >> + ret = versal_pm_puf_regeneration(dma_addr_in); >> + dma_unmap_single(puf->dev, dma_addr_in, buflen, DMA_BIDIRECTIONAL); >> + if (ret) >> + goto cleanup; >> + >> + if (copy_to_user(u64_to_user_ptr(pufreq->pufidaddr), ((char *)pufhd + >> + sizeof(struct puf_helperdata)), >> + PUF_ID_LEN_IN_BYTES)) { >> + ret = -EFAULT; >> + goto cleanup; >> + } >> + >> +cleanup: >> + kfree(buf); >> + >> + return ret; >> +} >> + >> +static long xlnx_puf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) >> +{ >> + struct xpuf_dev *puf = file->private_data; >> + struct puf_usrparams pufreq; >> + void __user *data = NULL; >> + int ret; >> + >> + if (_IOC_TYPE(cmd) != PUF_IOC_MAGIC) >> + return -ENOTTY; >> + >> + /* check if ioctl argument is present and valid */ >> + if (_IOC_DIR(cmd) != _IOC_NONE) { >> + data = (void __user *)arg; >> + if (!data) >> + return -EINVAL; >> + >> + if (copy_from_user(&pufreq, data, sizeof(struct puf_usrparams))) >> + return -EFAULT; >> + } >> + >> + switch (cmd) { >> + case PUF_REGISTRATION: >> + ret = xlnx_puf_regis(puf, &pufreq); >> + break; >> + case PUF_REGENERATION: >> + case PUF_REGEN_ID_ONLY: >> + ret = xlnx_puf_regen_id(puf, &pufreq); >> + break; >> + case PUF_CLEAR_ID: >> + if (!puf_clear) { >> + ret = -EOPNOTSUPP; >> + break; >> + } >> + ret = versal_pm_puf_clear_id(); >> + break; >> + case PUF_CLEAR_KEY: >> + if (!puf_clear) { >> + ret = -EOPNOTSUPP; >> + break; >> + } >> + ret = versal_pm_aes_init(); >> + if (!ret) >> + ret = versal_pm_puf_key_zero(); >> + break; >> + default: >> + return -ENOTTY; >> + } >> + >> + return ret; >> +} >> + >> +/** >> + * xlnx_puf_open - open puf device >> + * @inode: inode object >> + * @file: file object >> + * >> + * Return: 0 if successful; otherwise -errno >> + */ >> +static int xlnx_puf_open(struct inode *inode, struct file *file) >> +{ >> + struct xpuf_dev *xpuf; >> + >> + xpuf = container_of(file->private_data, struct xpuf_dev, miscdev); >> + file->private_data = xpuf; >> + >> + dev_dbg(xpuf->dev, "device /dev/xpuf opened\n"); >> + >> + return 0; >> +} >> + >> +/** >> + * xlnx_puf_release - release puf resources >> + * @inode: inode object >> + * @file: file object >> + * >> + * Return: 0 if successful; otherwise -errno >> + */ >> +static int xlnx_puf_release(struct inode *inode, struct file *file) >> +{ >> + struct xpuf_dev *xpuf = file->private_data; >> + >> + dev_dbg(xpuf->dev, "device /dev/xpuf closed\n"); >> + >> + return 0; >> +} > This does nothing, why is it needed at all? > >> + >> +static const struct file_operations xlnx_puf_fops = { >> + .owner = THIS_MODULE, >> + .open = xlnx_puf_open, >> + .release = xlnx_puf_release, >> + .unlocked_ioctl = xlnx_puf_ioctl, >> + .compat_ioctl = compat_ptr_ioctl, >> +}; >> + >> +/** >> + * xlnx_puf_probe - probe puf device >> + * @pdev: Pointer to puf platform device structure >> + * >> + * Return: 0 if successful; otherwise -errno >> + */ >> +static int xlnx_puf_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct xpuf_dev *xpuf; >> + int ret; >> + >> + xpuf = devm_kzalloc(dev, sizeof(*xpuf), GFP_KERNEL); >> + if (!xpuf) >> + return -ENOMEM; >> + >> + xpuf->dev = dev; >> + >> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); >> + if (ret < 0) { >> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); >> + if (ret < 0) { >> + dev_err(dev, "no usable DMA configuration\n"); >> + return ret; >> + } >> + } >> + >> + xpuf->miscdev.minor = MISC_DYNAMIC_MINOR; >> + xpuf->miscdev.name = "xpuf"; >> + xpuf->miscdev.fops = &xlnx_puf_fops; >> + xpuf->miscdev.parent = dev; >> + >> + ret = misc_register(&xpuf->miscdev); >> + if (ret) >> + return ret; >> + >> + platform_set_drvdata(pdev, xpuf); >> + >> + dev_dbg(dev, "puf registered as /dev/xpuf successfully\n"); >> + >> + return 0; >> +} >> + >> +/** >> + * xlnx_puf_remove - clean up structures >> + * @pdev: The structure containing the device's details >> + */ >> +static void xlnx_puf_remove(struct platform_device *pdev) >> +{ >> + struct xpuf_dev *xpuf = platform_get_drvdata(pdev); >> + >> + misc_deregister(&xpuf->miscdev); >> + >> + dev_dbg(xpuf->dev, "device /dev/xpuf removed\n"); > ftrace is your friend :) > >> +} >> + >> +static struct platform_driver xlnx_puf_drv = { >> + .probe = xlnx_puf_probe, >> + .remove = xlnx_puf_remove, >> + .driver = { >> + .name = "xlnx-puf", >> + }, >> +}; >> + >> +static struct platform_device *xlnx_puf_pdev; >> + >> +static int __init xlnx_puf_driver_init(void) >> +{ >> + int ret; >> + >> + ret = platform_driver_register(&xlnx_puf_drv); >> + if (ret) >> + return ret; >> + >> + xlnx_puf_pdev = platform_device_register_simple(xlnx_puf_drv.driver.name, >> + 0, NULL, 0); > Why isn't this using the faux bus instead? This isn't a real platform > device at all as you have no resources for it that describe it. > > > > >> + if (IS_ERR(xlnx_puf_pdev)) { >> + ret = PTR_ERR(xlnx_puf_pdev); >> + platform_driver_unregister(&xlnx_puf_drv); >> + } >> + >> + return ret; >> +} >> + >> +static void __exit xlnx_puf_driver_exit(void) >> +{ >> + platform_device_unregister(xlnx_puf_pdev); >> + platform_driver_unregister(&xlnx_puf_drv); >> +} >> + >> +module_init(xlnx_puf_driver_init); >> +module_exit(xlnx_puf_driver_exit); >> + >> +MODULE_AUTHOR("AMD"); >> +MODULE_LICENSE("GPL"); >> +MODULE_DESCRIPTION("Xilinx Versal PUF driver"); >> diff --git a/include/uapi/misc/xilinx_puf.h b/include/uapi/misc/xilinx_puf.h >> new file mode 100644 >> index 000000000000..32565a748df3 >> --- /dev/null >> +++ b/include/uapi/misc/xilinx_puf.h >> @@ -0,0 +1,82 @@ >> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ >> +/* >> + * Driver for Xilinx PUF device. >> + * >> + * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc. >> + * >> + * Description: >> + * This driver is developed for PUF registration and regeneration support. >> + */ >> + >> +#ifndef _UAPI_MISC_XILINX_PUF_H_ >> +#define _UAPI_MISC_XILINX_PUF_H_ >> + >> +#include >> +#include >> + >> +#define PUF_MAX_SYNDROME_DATA_LEN_IN_WORDS 140 >> +#define PUF_EFUSE_TRIM_SYN_DATA_IN_WORDS 127 >> +#define PUF_ID_LEN_IN_WORDS 8 >> +#define PUF_ID_LEN_IN_BYTES 32 >> +#define PUF_REGIS 0 >> +#define PUF_REGEN 1 >> +#define PUF_REGEN_ID 2 >> + >> +/** >> + * struct puf_usrparams - user parameters for PUF from user space. >> + * @pufoperation: PUF registration or regeneration operation >> + * @globalvarfilter: global variation filter >> + * @readoption: option to read PUF data from efuse cache or ram address >> + * @reserved: explicit padding to match the Versal PLM PUF parameter layout >> + * @shuttervalue: shutter value for PUF registration/regeneration >> + * @pufdataaddr: address to store/get the puf data during registration/regeneration >> + * @pufidaddr: puf id will be stored either during registration/regeneration >> + */ >> +struct puf_usrparams { >> + __u8 pufoperation; >> + __u8 globalvarfilter; >> + __u8 readoption; >> + __u8 reserved; >> + __u32 shuttervalue; >> + __u64 pufdataaddr; >> + __u64 pufidaddr; >> +}; >> + >> +/** >> + * struct puf_helperdata - parameters for puf helper data. >> + * @syndata: PUF syndrome data >> + * @chash: PUF chash >> + * @aux: PUF aux >> + */ >> +struct puf_helperdata { >> + __u32 syndata[PUF_MAX_SYNDROME_DATA_LEN_IN_WORDS]; >> + __u32 chash; >> + __u32 aux; >> +}; >> + >> +/** >> + * struct pufdata - parameters for puf data. >> + * @pufhd: puf helper data of type struct puf_helperdata >> + * @pufid: PUF id >> + * @efusesyndata: PUF efuse syndrome data >> + */ >> +struct pufdata { >> + struct puf_helperdata pufhd; >> + __u32 pufid[PUF_ID_LEN_IN_WORDS]; >> + __u32 efusesyndata[PUF_EFUSE_TRIM_SYN_DATA_IN_WORDS]; >> +}; >> + >> +enum pufreadoption { >> + PUF_READ_FROM_RAM = 0, >> + PUF_READ_FROM_EFUSE_CACHE = 1 >> +}; >> + >> +#define PUF_IOC_MAGIC 'P' > Why are you allowed to use "P" for your ioctl? Isn't that already used > by other drivers? > > thanks, > > greg k-h