From nobody Sat Jul 25 20:46:39 2026 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011035.outbound.protection.outlook.com [52.101.62.35]) (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 8D508343D72 for ; Mon, 13 Jul 2026 18:36:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.35 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783967765; cv=fail; b=EuNP1y72tp0SKjZk1ZlNxjdUILYiArHof9uPRqT54el7BGKLH5W+TXVbOViGFGyuUrh5+HWTuHBBNBCeHh8HxS1sGxgI9xnsQ/y7aslfQTn2B96BfD53gUwIo1KPCHSZaARQoC7wj3lJYFHKE7S7ovg0CBOug+GDeKIpaJb1wVE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783967765; c=relaxed/simple; bh=hzm5el2puvd0UpHOTARfCUsUlq12wwV9EOxgToiqfxY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=dkownrJxVtSBSua5y9VoitMcvJzbHXlsv3ZP8nW5R7Wg2lsotpGKxnrBNIjp8mIDR89sKumlkiA7qLrOrYcgRtBAGQQMj74puL8hUSQqXvPnQPaZdIbQUjXlyOAG9RPYrV/oSlmVkBi4bx32ni5i1oo5ImmEyresTPgQZFboYOk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=altera.com; spf=pass smtp.mailfrom=altera.com; dkim=pass (2048-bit key) header.d=altera.com header.i=@altera.com header.b=FipE1HdQ; arc=fail smtp.client-ip=52.101.62.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=altera.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=altera.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=altera.com header.i=@altera.com header.b="FipE1HdQ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=jnhZuQcm4hgta4tR+LjeanN+CnWrLoTI4QFdFJhfY8CDjj5hhQqOqmNLQJkCUINciwDTIa4mpSUzraBeMfxlSQf5mG35WJLl2COOjxAvA5jH7ZZkMsdk+M512tFjTIlOmaUs84Yeqt0Xo7mOm/Oslz8OSTSHDhdLAaZwSoPRrsLId7WyKhkuq9zK1eJoHh7btwmSEOs5I4VEsNcyy1AX094nMG6qamo+3mmO1PSrIZFUiUe9Od3sPrF8CZss1dw38DwZwqjaP+IkzHwWyp0MpYxsb3RoPoynrCvJTNfjJuoCAUlOcOWVtBYjyoIsIiZ/gBvEuF5xdxc9ufnugdI0Vw== 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=2hYlmGfaLzarNkfS56ZqV6JVEw7gNIUhbyVKYQ2CFiw=; b=dT2FFP3MoK/UaR9v4UzptOMef+fR7LFK7wahiJQ3yfaSz7nvnyNk7ojxLaOsfbCgyN399SEV9LO/1TS/BNwqX6LPNfw6gjqT7GRHhKmoWZAvQ7hoALiPMkzSjWUxc/hfC5NE+LiBOMUuAP5HEj1hdYIy6p+RkCEtJWgCyxEzbSS09bBPgENB+Z3E92AO0WPNEaiZyQS9dOQEj7KgEkNRTKXCAjLY6Li6iT65SD+tV/NsvXGi9l+KLYHpR2REu7Q4fdFrKhLKpewv1Ksu5OkwVmZAUO8yEx7zuN0qmDLuyhSEaNaYurvFv6Oilj8BkBqPLbjdcntEH875C6ufv+wDfA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=altera.com; dmarc=pass action=none header.from=altera.com; dkim=pass header.d=altera.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altera.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2hYlmGfaLzarNkfS56ZqV6JVEw7gNIUhbyVKYQ2CFiw=; b=FipE1HdQHAMRr4i94R2aOQohpWEYJavs1EX+sRv8sxERWwEPQnERWkKnoPFoDOHXHsmvhvnGbGDbEmUeE9r+E5OZh+KY5rQCSL31bCfawBJcyt/qZuM+UhJY23TzZbBtvtWjYjUdo/VNG9C6yXVbAbYsb+JQJIoCy4tQZKjqJ+qRHUFOosSiJc5cJtBDYlPQRJYJbE/zp0hgjnfWACI2zc+ZRGdW5vDS8bpoz5A6L9ls3lVEN57ICBmtV/6kFWkk+TrXSBeXguiTSeqvNbwZcTh7BPy+RKh820zgFFM5aircsmyC2/yGrNBJQHi9MW4k4MDS2/aQ0cqn94qGpHlT7Q== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=altera.com; Received: from MW4PR03MB6555.namprd03.prod.outlook.com (2603:10b6:303:126::12) by CO1PR03MB5924.namprd03.prod.outlook.com (2603:10b6:303:9a::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.202.18; Mon, 13 Jul 2026 18:35:58 +0000 Received: from MW4PR03MB6555.namprd03.prod.outlook.com ([fe80::c8e9:5e5d:afad:5eaa]) by MW4PR03MB6555.namprd03.prod.outlook.com ([fe80::c8e9:5e5d:afad:5eaa%3]) with mapi id 15.21.0202.014; Mon, 13 Jul 2026 18:35:58 +0000 From: hang.suan.wang@altera.com To: Greg Kroah-Hartman , Dinh Nguyen , linux-kernel@vger.kernel.org, "Michael S . Tsirkin" , Huacai Chen , Florian Fainelli , Chen-Yu Tsai Cc: muhammad.nazim.amirul.nazle.asmade@altera.com, tze.yee.ng@altera.com, chee.nouk.phoon@altera.com, genevieve.chan@altera.com, adrian.ho.yin.ng@altera.com Subject: [PATCH v2 1/2] firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5 Date: Mon, 13 Jul 2026 11:35:54 -0700 Message-ID: <185cdbe74f2c66e0e73e5907d1a2f1d7859d0960.1783966717.git.hang.suan.wang@altera.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: References: Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SJ0PR13CA0119.namprd13.prod.outlook.com (2603:10b6:a03:2c5::34) To MW4PR03MB6555.namprd03.prod.outlook.com (2603:10b6:303:126::12) 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: MW4PR03MB6555:EE_|CO1PR03MB5924:EE_ X-MS-Office365-Filtering-Correlation-Id: 7ee86610-e1c0-4528-eda1-08dee10d951f X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|1800799024|366016|6133799003|56012099006|11063799006|18002099003|22082099003|55112099003|3023799007; X-Microsoft-Antispam-Message-Info: YdU+Gk0SwTzpiqD5l7TyRapx1Z3H0rJz6DMEzMmjjN6pwFBUX0FXNC3LdWJ1CSQ9Cw9rFThHL36Ck6AbM8cBoRGZVag4VQPns2jd09IfGsi0GHvtLjrkZuHkIqhh4TJDDW8mBtU9Vq2Byacd3Oz1GyX5l9+pFYjUt+yUPW4WiliW92WLETiKZ4vE5Cb6zo5Tf+b0P4Y6PS2Kj8tJ8/Pf2tIbfkuepjzG2IgTtCXFt6B0rqUooFWgmGXScpmZhvzYaTLX8QM/WA8kaQxIYEp32sN6UstEPoB9hMk/QUxV9+/8IzhaE+1lO4kST221+XlFqDaTyMhuoN5rLtSG5gedMXMoCqaccMAm4/YVpWtW/LvhqEY9gn7iSHQ9eI82FuuW5fUVSsr5earS7hzMGvMKeFDVXzirBBypt2wp3mHbpLHJ8L3MyuVck2fVjRQ5/AuW0RpQ/+osroGPDs0yK+iWKJuqpCG0XAs0FBdijL9jXJBJQAOJ0gjJBsw92ptJygtsGLqPE3ea2wY+2+YvgRZnxUiaogph8flsp/RBv1UeT20Y3tP2qcHknmBdMY+s8dTPFzqktUrQD9CYlgJ6xNvFMFMsw5hI14n3wW9FJs5VTMJnvKC99kkZmDopz6B0/I/KHnFrWcLTWdHZ2wH2Mj8ClbIX1nvG4qqkLDKj5UoM/xk= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR03MB6555.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(1800799024)(366016)(6133799003)(56012099006)(11063799006)(18002099003)(22082099003)(55112099003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?nrk0ny534U/mJz4wQx+llDKYK8Fq2FUXBtNbnKnzIs3lZRjgBrz0q/LUKam6?= =?us-ascii?Q?1Clnj81imoLZ5OwQap0gARIQpMNjWBlfQmbfNPsCTTzUafFLH5xCxaqLzWJV?= =?us-ascii?Q?y23cPrDpPT+OeBZw8vDiNuVpgOOUPVGKrdltD79sgtAWeW1VjG5FHwU/Eudp?= =?us-ascii?Q?xjLTjLRkr+zWRBRrnZrr7obDStJV9lLuRtrQaOu5FNd3UKxe2z8fIrYfi0k9?= =?us-ascii?Q?CFGG5GNCP1P5amCwqPcar9jqLHsIlcTc2I75Ql34iLegTVYkIecboxDmyq0c?= =?us-ascii?Q?MzeLH37koGiHKwHLxMQO/tO3eiVE3YWTPuufWlzuifLoNcJqxp//qzQfTAuS?= =?us-ascii?Q?WBdYiD64b5GSEiTvboGzfgpf476MfwDQNAKAQ2fWhpFkdz43RTFW9NByADeG?= =?us-ascii?Q?b2Z9CabCqSH7URZ5z/cqvj6mcw/zG17lmyCkzWndoxOyTmA3mX9xlcwM+xbl?= =?us-ascii?Q?F7nsx3B2nWvuHWWt1/8Yie21B8KTpFNd8WwYsEum1yay+S1MMcOk9Lhu293C?= =?us-ascii?Q?1cHBYQX9uut8fobas8o6eFuM0XRaoa3aPe3wsI/lkTRUNDIul6gc/Hg7EHx4?= =?us-ascii?Q?Jp6OLEOcj9yM6ZHOvMQh3c6yOOi5oSioe9mXgQXZ37WKoe8p4V8w2xhkuw1u?= =?us-ascii?Q?AlyjNFeIzzTvgQdlic08vVsZwVGhKrPpfrfEdnpfh3ZRvEeXm9GAbDHcLTUR?= =?us-ascii?Q?k85T5S2j3OpOySUcLi/o3SkwMcvCLqvq2zNwq/NciicUa0boBPNjgprASL3w?= =?us-ascii?Q?zCBD5DTxLWe+StX6RQRVgqmDKWss0SiSfMT5qyoERDNXGE5DUyg/kxZzz5Qb?= =?us-ascii?Q?imBpAkpj9rOvHxdKjPWd8YFnPfFDyRrQ+KD6EyrWWE8N9AlFystP3pLH+qLk?= =?us-ascii?Q?Bzjy8RqGnOvoAyOBHolRs/sq10+04HWeNZJn5Fz8+9Tul3Lr+8xgepgjLJWt?= =?us-ascii?Q?o+i4EN6gNQ3duPiEPCQYBr2Mt24oLhPSBvGRjNmE9g+w1mnCQ4+AGYGtc9AE?= =?us-ascii?Q?xfyjKOhv7sFF6hfeJSMgFQMfY1Rq7jtg/EsipWpRS2pmZVc2GVvEeKaOgFkq?= =?us-ascii?Q?YKfWGRQY0TrP3etoyz+S+l2qZWmQoUJHMT0zKwheLdbIKq4hD0o/Ju7l/a8F?= =?us-ascii?Q?f81rZS6DZqzJdTWHTAc5mVd9dHnjagCEbQsODLUM+7uOatfbuMbhZE8yD8LM?= =?us-ascii?Q?J+Z4vuSeLjMq2Ki7rUFlAVBsVNiQJpbPaepwovgke+9Q16JiJGZZZuhBe+0i?= =?us-ascii?Q?gtk8kqXlZlyHaW2O1iYsKHLk5bAueElIu9eCRhmP8GAnOoEsy7Efzk16uNZi?= =?us-ascii?Q?7Gxg807KsXNvH5yAB0+bO1hJZJEtVtn/1D8YmuLJbIQVAhinROZzCx0imeqt?= =?us-ascii?Q?AHj8OZuM2zbnGX+0AmDGknGzDDPyKuswIupcHeWpLdVjK8TvKWCh5Ea9IPla?= =?us-ascii?Q?jsWHceP5pofKGApzEvX0pQ1iojvD0/X6+uCuJ9D+By59sdeB0ORIqjgCCBdj?= =?us-ascii?Q?rSjK/7mgGrx5KiwjAB7sKBVcJnAFaB12HkTfmv9sJR1Q+XRIgrdsdjNOipY3?= =?us-ascii?Q?0ALe0/TdS6iNFtBRZ8n0vxc9ktl+R6bGtmT2sMtqblfPQze1tw6ueGYaaTcl?= =?us-ascii?Q?TTWc/RC3c3AdZ3aEoK1bkAWQUpmgFFU0FvGYHhVIXmtwFWc4Eo1B/12NqFRf?= =?us-ascii?Q?xzqVgP/Qv9PcELn77r8Tl3MRG7eCTIjcGHdPLwk8gD2NAREo+hI8GLfd6rYL?= =?us-ascii?Q?dJ0bOuVbkaxb7qmioMRk96JDlz8j+gI=3D?= X-OriginatorOrg: altera.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7ee86610-e1c0-4528-eda1-08dee10d951f X-MS-Exchange-CrossTenant-AuthSource: MW4PR03MB6555.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2026 18:35:58.6960 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 7D3sg2nM31x/DKMljGa8PC+y2uzzyIprZiryoj61xF+XAqUf1hvdbeQBTYXEMy5Utg3qMSIKnOzRhhzCwixhFg5kRL/+J6tD4jkV5A4Pacw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR03MB5924 Content-Type: text/plain; charset="utf-8" From: Hang Suan Wang The Agilex 5 Secure Device Manager (SDM 1.5) exposes an FPGA Crypto Service (FCS) over the existing SIP SMC mailbox: a session-based interface for crypto primitives such as SDOS (Secure Data Object Service) encrypt/decrypt. The service layer has no command to drive it yet. Teach stratix10-svc about this interface so an in-kernel FCS client can use it: - add the client command codes COMMAND_FCS_CRYPTO_OPEN_SESSION, COMMAND_FCS_CRYPTO_CLOSE_SESSION and COMMAND_FCS_SDOS_DATA_EXT (all asynchronous), and grow stratix10_svc_client_msg::arg[] from three to four entries so the SDOS command can carry its session, context, mode and owner arguments; - add the matching asynchronous SIP SMC function IDs (INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION, INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION and INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) with their register-usage documentation; - match "intel,agilex5-svc" and register a "stratix10-fcs" child platform device, mirroring the existing RSU child, so an FCS client driver can bind without a dedicated device-tree node; - dispatch the new commands in the asynchronous send and response paths; for the SDOS data command, translate the source and destination buffers (allocated from the service-layer gen_pool) to physical addresses and pass them, together with the session/context IDs and owner ID, to the SDM. The transport is unchanged: Agilex 5 reuses the SIP SMC calling convention and async mailbox ABI the driver already implements, so no new transport mechanism is required. The SDOS SMMU-remapped address slots currently carry the buffer physical addresses; SMMU remapping support is added in a follow-up series. This is a prerequisite for the SoCFPGA FCS driver, the first in-tree consumer of these commands. Signed-off-by: Hang Suan Wang Reviewed-by: Dinh Nguyen --- drivers/firmware/stratix10-svc.c | 58 +++++++++++++++-- include/linux/firmware/intel/stratix10-smc.h | 64 +++++++++++++++++++ .../firmware/intel/stratix10-svc-client.h | 18 +++++- 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-= svc.c index c24ca5823078..09f709a2f28e 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -45,6 +45,7 @@ =20 /* stratix10 service layer clients */ #define STRATIX10_RSU "stratix10-rsu" +#define STRATIX10_FCS "stratix10-fcs" =20 /* Maximum number of SDM client IDs. */ #define MAX_SDM_CLIENT_IDS 16 @@ -104,9 +105,11 @@ struct stratix10_svc_chan; /** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device + * @stratix10_svc_fcs: pointer to stratix10 FCS device */ struct stratix10_svc { struct platform_device *stratix10_svc_rsu; + struct platform_device *stratix10_svc_fcs; }; =20 /** @@ -1319,6 +1322,30 @@ int stratix10_svc_async_send(struct stratix10_svc_ch= an *chan, void *msg, STRATIX10_SIP_SMC_SET_TRANSACTIONID_X1(handle->transaction_id); =20 switch (p_msg->command) { + case COMMAND_FCS_CRYPTO_OPEN_SESSION: + args.a0 =3D INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION; + break; + case COMMAND_FCS_CRYPTO_CLOSE_SESSION: + args.a0 =3D INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION; + args.a2 =3D p_msg->arg[0]; + break; + case COMMAND_FCS_SDOS_DATA_EXT: + args.a0 =3D INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT; + args.a2 =3D p_msg->arg[0]; + args.a3 =3D p_msg->arg[1]; + args.a4 =3D p_msg->arg[2]; + /* payloads are allocated from the svc gen_pool; pass phys addr */ + args.a5 =3D gen_pool_virt_to_phys(ctrl->genpool, + (unsigned long)p_msg->payload); + args.a6 =3D p_msg->payload_length; + args.a7 =3D gen_pool_virt_to_phys(ctrl->genpool, + (unsigned long)p_msg->payload_output); + args.a8 =3D p_msg->payload_length_output; + args.a9 =3D p_msg->arg[3]; + /* SMMU remapping is added later; pass phys addr for now */ + args.a10 =3D args.a5; + args.a11 =3D args.a7; + break; case COMMAND_RSU_GET_SPT_TABLE: args.a0 =3D INTEL_SIP_SMC_ASYNC_RSU_GET_SPT; break; @@ -1408,8 +1435,13 @@ static int stratix10_svc_async_prepare_response(stru= ct stratix10_svc_chan *chan, data->status =3D STRATIX10_GET_SDM_STATUS_CODE(handle->res.a1); =20 switch (p_msg->command) { + case COMMAND_FCS_CRYPTO_CLOSE_SESSION: case COMMAND_RSU_NOTIFY: break; + case COMMAND_FCS_CRYPTO_OPEN_SESSION: + case COMMAND_FCS_SDOS_DATA_EXT: + data->kaddr1 =3D (void *)&handle->res.a2; + break; case COMMAND_RSU_GET_SPT_TABLE: data->kaddr1 =3D (void *)&handle->res.a2; data->kaddr2 =3D (void *)&handle->res.a3; @@ -1908,6 +1940,7 @@ EXPORT_SYMBOL_GPL(stratix10_svc_free_memory); static const struct of_device_id stratix10_svc_drv_match[] =3D { {.compatible =3D "intel,stratix10-svc"}, {.compatible =3D "intel,agilex-svc"}, + {.compatible =3D "intel,agilex5-svc"}, {}, }; =20 @@ -2011,20 +2044,36 @@ static int stratix10_svc_drv_probe(struct platform_= device *pdev) =20 ret =3D platform_device_add(svc->stratix10_svc_rsu); if (ret) - goto err_put_device; + goto err_put_rsu; + + svc->stratix10_svc_fcs =3D platform_device_alloc(STRATIX10_FCS, 0); + if (!svc->stratix10_svc_fcs) { + dev_err(dev, "failed to allocate %s device\n", STRATIX10_FCS); + ret =3D -ENOMEM; + goto err_unregister_rsu; + } + + ret =3D platform_device_add(svc->stratix10_svc_fcs); + if (ret) + goto err_put_fcs; =20 ret =3D of_platform_default_populate(dev_of_node(dev), NULL, dev); if (ret) - goto err_unregister_rsu_dev; + goto err_unregister_fcs; =20 pr_info("Intel Service Layer Driver Initialized\n"); =20 return 0; =20 -err_unregister_rsu_dev: +err_unregister_fcs: + platform_device_unregister(svc->stratix10_svc_fcs); + goto err_unregister_rsu; +err_put_fcs: + platform_device_put(svc->stratix10_svc_fcs); +err_unregister_rsu: platform_device_unregister(svc->stratix10_svc_rsu); goto err_free_fifos; -err_put_device: +err_put_rsu: platform_device_put(svc->stratix10_svc_rsu); err_free_fifos: /* only remove from list if list_add_tail() was reached */ @@ -2051,6 +2100,7 @@ static void stratix10_svc_drv_remove(struct platform_= device *pdev) of_platform_depopulate(ctrl->dev); =20 platform_device_unregister(svc->stratix10_svc_rsu); + platform_device_unregister(svc->stratix10_svc_fcs); =20 for (i =3D 0; i < SVC_NUM_CHANNEL; i++) { if (ctrl->chans[i].task) { diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/f= irmware/intel/stratix10-smc.h index 9116512169dc..d7ad6bd6f669 100644 --- a/include/linux/firmware/intel/stratix10-smc.h +++ b/include/linux/firmware/intel/stratix10-smc.h @@ -640,6 +640,70 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_= CONFIG_COMPLETED_WRITE) #define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA \ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA) =20 +/** + * Request INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT + * Async call to perform encryption/decryption + * + * Call register usage: + * a0 INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT + * a1 transaction job id + * a2 session ID + * a3 context ID + * a4 cryption operating mode (1 for encryption and 0 for decryption) + * a5 physical address of source + * a6 size of source + * a7 physical address of destination + * a8 size of destination + * a9 sdos ownership + * a10 smmu remapped address of source + * a11 smmu remapped address of destination + * a12-a17 not used + * + * Return status: + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR + * a1-a17 not used + */ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CRYPTION_EXT (0x12F) +#define INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CRYPTION_EXT) + +/** + * Request INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION + * Async call to open and establish a crypto service session with firmware + * + * Call register usage: + * a0 INTEL_SIP_SMC_FCS_OPEN_CRYPTO_SERVICE_SESSION + * a1 transaction job id + * a2-a17 not used + * + * Return status: + * a0 INTEL_SIP_SMC_STATUS_OK ,INTEL_SIP_SMC_STATUS_REJECTED + * or INTEL_SIP_SMC_STATUS_BUSY + * a1-a17 not used + */ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_OPEN_CS_SESSION (0x13A) +#define INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_OPEN_CS_SESSION) + +/** + * Request INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION + * Async call to close a service session + * + * Call register usage: + * a0 INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION + * a1 transaction job id + * a2 session ID + * a3-a17 not used + * + * Return status: + * a0 INTEL_SIP_SMC_STATUS_OK ,INTEL_SIP_SMC_STATUS_REJECTED + * or INTEL_SIP_SMC_STATUS_BUSY + * a1-a17 not used + */ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CLOSE_CS_SESSION (0x13B) +#define INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CLOSE_CS_SESSION) + /** * Request INTEL_SIP_SMC_HWMON_READTEMP * Sync call to request temperature diff --git a/include/linux/firmware/intel/stratix10-svc-client.h b/include/= linux/firmware/intel/stratix10-svc-client.h index 3edd93502bf8..285fddafeacb 100644 --- a/include/linux/firmware/intel/stratix10-svc-client.h +++ b/include/linux/firmware/intel/stratix10-svc-client.h @@ -7,6 +7,8 @@ #ifndef __STRATIX10_SVC_CLIENT_H #define __STRATIX10_SVC_CLIENT_H =20 +#include + /* * Service layer driver supports client names * @@ -122,6 +124,15 @@ struct stratix10_svc_chan; * @COMMAND_SMC_SVC_VERSION: Non-mailbox SMC SVC API Version, * return status is SVC_STATUS_OK * + * @COMMAND_FCS_CRYPTO_OPEN_SESSION: open the crypto service session(s), + * return status is SVC_STATUS_OK or SVC_STATUS_ERROR + * + * @COMMAND_FCS_CRYPTO_CLOSE_SESSION: close the crypto service session(s), + * return status is SVC_STATUS_OK or SVC_STATUS_ERROR + * + * @COMMAND_FCS_SDOS_DATA_EXT: extend SDOS data encryption & decryption, + * return status is SVC_STATUS_OK or SVC_STATUS_ERROR + * * @COMMAND_MBOX_SEND_CMD: send generic mailbox command, return status is * SVC_STATUS_OK or SVC_STATUS_ERROR * @@ -185,6 +196,11 @@ enum stratix10_svc_command_code { COMMAND_FCS_RANDOM_NUMBER_GEN, /* for general status poll */ COMMAND_POLL_SERVICE_STATUS =3D 40, + /* for crypto service */ + COMMAND_FCS_CRYPTO_OPEN_SESSION =3D 50, + COMMAND_FCS_CRYPTO_CLOSE_SESSION, + /* for extended SDOS encrypt/decrypt */ + COMMAND_FCS_SDOS_DATA_EXT =3D 82, /* for generic mailbox send command */ COMMAND_MBOX_SEND_CMD =3D 100, /* Non-mailbox SMC Call */ @@ -210,7 +226,7 @@ struct stratix10_svc_client_msg { void *payload_output; size_t payload_length_output; enum stratix10_svc_command_code command; - u64 arg[3]; + u64 arg[4]; }; =20 /** --=20 2.43.7 From nobody Sat Jul 25 20:46:39 2026 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011035.outbound.protection.outlook.com [52.101.62.35]) (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 93BE8353A7E for ; Mon, 13 Jul 2026 18:36:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.35 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783967768; cv=fail; b=ODsW5T5t/J2F9OokTttD3UJMvQS9visglhRtnfvb8jRalbFOLzxN1YabjtMFhDIOq2isjk6Aju4nQjya28yfIsJ7Jhw/BdmADJ0emq0WxMWhVGDuMRUSLustSBVPRyZYLngcH3ndPl0g8Mz8IbRRWyxLx5+RNXmGSvI4pg7XTZY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783967768; c=relaxed/simple; bh=IUyfl4+24fMYY3GRdQFvLX52ZQk65+x/HYs+xPM4H2M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=MraQp2v8zzaVY0+LWXl1RMhSDWZlLAyqePvv/JXAm2J38cUG9HV/MWOQI2Hushyl3TIJOLr02eEHiwV6S+d91X7scO25axZiIX0ug3arjBZQyI9+wlyH/fxP4BbZ1ykogh8OTAxW7bHoNfYkGcIGx8t7f0MQ7OKPE69UMZvGZB0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=altera.com; spf=pass smtp.mailfrom=altera.com; dkim=pass (2048-bit key) header.d=altera.com header.i=@altera.com header.b=HPgrAUo2; arc=fail smtp.client-ip=52.101.62.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=altera.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=altera.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=altera.com header.i=@altera.com header.b="HPgrAUo2" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MB6REeD9avIUifLfYoxgW6M3cnXfGaWbNphs0ivCS/7yHdwmmW1DR0CsZed7tbrx3c8cMCNHy/ezm9ak72XCeJjN1XAKlAR9p5AlS3vR0FEjkTLL140zezLsuU2FbSIwNpmlNl6LL7jLQgvo5NOpVhDHh5w92rv4UOoNmO3VXfIlYIJgNTKBh1RFkbnz2VEAbaEgCBL35F77IF5wNviuqmGgJA2z+wWcW8htX93XaqzaD0sVH/Q5AWFTroElU1q+CGtJsxB4D/oo6bo97drIEXxjR6mZESLHLJ0WJMy1Cs4Y+CC3m+BQE9KZQYCoUfDGEIl9yO2PEUR9xNGvRvP9Ag== 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=nBz2jCp8gNo0ECTonSWaj+E5zmpMS4iNy+BTkSfEiNU=; b=G+xrEFeaKeVmH6N0vP3xIcbzHQognMbgXtWCfhdTaAnGhO5uisvOKaFkRyllQaLlzSmrbxFUBYJThIiidLVdftL2jeK1Jm42jMwSolftfRe4TIOYRtbFbFDi5TKugDiMc89TEtCeJK7tgtAkzvkwd91eEdmfpQJiwFM/lkPq2lEw9jLpqu4Xd5gbnQQkqN6Wk+2s+t0B1yVa/WjaZrA9jxpZ2ud9CrhtZFJszxOv32N0fEFywxOUG13+EaErPc5D12LDnoj8hgCoTZ41vsT3BXFAH84PuIQFFPZPZQRQZ/EMlyqjZTHwN2pvbhGb5YdT0khIDCSo1IE36lbGhArn0g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=altera.com; dmarc=pass action=none header.from=altera.com; dkim=pass header.d=altera.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altera.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nBz2jCp8gNo0ECTonSWaj+E5zmpMS4iNy+BTkSfEiNU=; b=HPgrAUo2HJooyZtvBsBQbkdRePcquG21JpW0enMZg3SKj0E0xTXkC4h/IO+e3qaz0tYYDDu2kbo81rRJbGraz/+Fo5+mq1IbT1bAUI2OlLbda9rUgqey3tyHMY0LrCWbVaohUnxX5lMH2J5cDJEm9Rw++Jg9mcBzKvST3BEpaCVjdur9idEMAobTORIl4z4GQNv4rxGl3LXX5rD1w+3WUNnF+Ul+POsNflT3s6SkhNFIGLEDUQffCxcsL6vbtqAucK+lkhjW03jsY451PZmzwZwW/cnQtLovnUJbglYxm8BILRTA3O8YK1RuHxKnwHw9I0pt3RA33ZlS2k/2CZgcnA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=altera.com; Received: from MW4PR03MB6555.namprd03.prod.outlook.com (2603:10b6:303:126::12) by CO1PR03MB5924.namprd03.prod.outlook.com (2603:10b6:303:9a::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.202.18; Mon, 13 Jul 2026 18:35:59 +0000 Received: from MW4PR03MB6555.namprd03.prod.outlook.com ([fe80::c8e9:5e5d:afad:5eaa]) by MW4PR03MB6555.namprd03.prod.outlook.com ([fe80::c8e9:5e5d:afad:5eaa%3]) with mapi id 15.21.0202.014; Mon, 13 Jul 2026 18:35:59 +0000 From: hang.suan.wang@altera.com To: Greg Kroah-Hartman , Dinh Nguyen , linux-kernel@vger.kernel.org, "Michael S . Tsirkin" , Huacai Chen , Florian Fainelli , Chen-Yu Tsai Cc: muhammad.nazim.amirul.nazle.asmade@altera.com, tze.yee.ng@altera.com, chee.nouk.phoon@altera.com, genevieve.chan@altera.com, adrian.ho.yin.ng@altera.com Subject: [PATCH v2 2/2] firmware: socfpga-fcs: add Altera SoCFPGA FCS driver with SDOS Date: Mon, 13 Jul 2026 11:35:55 -0700 Message-ID: <900031bb3347ba6dbb1556a8878e1d12e85050ab.1783966717.git.hang.suan.wang@altera.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: References: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SJ0PR13CA0119.namprd13.prod.outlook.com (2603:10b6:a03:2c5::34) To MW4PR03MB6555.namprd03.prod.outlook.com (2603:10b6:303:126::12) 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: MW4PR03MB6555:EE_|CO1PR03MB5924:EE_ X-MS-Office365-Filtering-Correlation-Id: 55f2a65e-50e4-430e-f369-08dee10d9594 X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|1800799024|366016|6133799003|56012099006|5023799004|11063799006|18002099003|22082099003|55112099003|3023799007; X-Microsoft-Antispam-Message-Info: gA1e+IVECq1iikUF0KocBuiQrBdnNHcmB0JEKXmw2qqiKPq6mlaE2XD8GDUZjs9LSgbVd427juP7v4yIjFoh2mCedtC4hHou9HCqy4KS5hYADOKcMBo+YG2Gn9szpgxJi2Ntnnk/z7Mk881u0JqFuSWxNeDp9PscpHz1HdHOKjFMopOJzuu1Fg+zt1I1qLyJSih978DnsQNdWJYYNFDeQKDPkNfLqOYQzMoeShvEMHQPaJwNgcNAJDynVNdtxVsGkUyo9EvsLcxroX2uZO43o+32MJo5FLaN2hZO+a9BlzscQ7IPZVQbOs7mjqFTpem8c0jwHBWssyhwg0cw6GCu/5umrWZAtjFslVIlR2cGhxIaCYOVZsDaH/CdKyyFXCS8fumf8YQXTbHslsP9BMyl2WNk6pIYpJ4J8KT74iEGHsXTO0Y5moz1B4LUpdx+x6Xb34vzpv8anft24XCAEEGs2FEetOw5+5a4sIGWBqJQZu0DEpzuoLkutahE6LQT19HhYcWyrt3rCdsdAhM+qIxqqjjHokgP9x0zygnh2+vys6DY7CAQG6ZCsh+JAlcj57y1L0776Nd7TEKvekUnizhza3nI0Kd8DRxq8MUwJbMVy/GtE5ZsP3SWISdqlQSl0OMi8Ao/IggHhiT02rz1x/lITVeywqZhG97XGRhBR/GA0Ek= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR03MB6555.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(1800799024)(366016)(6133799003)(56012099006)(5023799004)(11063799006)(18002099003)(22082099003)(55112099003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?ZWVMNHdBUVBUVkVBRHF2M0czdFZUSE1remYwTHpKVlM4bi9xU0hqTndEYmgr?= =?utf-8?B?dTZiTjl3cEkwNVoxQUcxZDRMMzEzMG5vMlc3UkdIVkxMdjhHQnc2akxUN29w?= =?utf-8?B?RmljbFhteGVoNG11S0dVOHVKMDgrTUtKUnNaUmh3NHZBS3c4NW5FWURoR2Na?= =?utf-8?B?U2VPbUhQZFIrblhLYndtNXVqOCtkL1NMTmdsNlFYclg5OWdhRXFFYzNFSFp3?= =?utf-8?B?Q2ExRjBIbGVVem1zeEJNcDZyWFptQUVYZEtaZFZjdlN2UGdKYWljVXBMVG4w?= =?utf-8?B?TFdlVTN2eVNBZUxOWFIwMWdFa2xhbmNWYlFxVUh2WWsvWnBwSUJSc3VKdUVR?= =?utf-8?B?WVBYcVE2anlrU0V6ZStwV3RnSGw1Vm5qb2MxMDFLMy84dkRkSGJxV1VqajJI?= =?utf-8?B?OVFXN3puNS96MVl4Z1pzeVM0eGtHK3VBdHVzQVZiNXRQMUgyZjVTYk44b1Nx?= =?utf-8?B?Q2VPTVJlTFpqV25BZXNQOGlkQXlVM00vQVFZcnNTd2p5WVl5eFpVTEk4cFR6?= =?utf-8?B?YUQrdzJtbUNSbkZnYU5UZU9zeGx2RkVyOFllVE1uWjlJNEtySzNRNTJzUFVp?= =?utf-8?B?ejFEOWJFKzlCRWp1am8xVDVXaHhTOVptb3ZjdjR5a0ZEUUJ0MjAwbVdyVUpj?= =?utf-8?B?c3gzZU0vdndHaWxVM0dEcGNPeUpoNERLc1RzUmFEeE5oaFlWMkhtWm82NkZP?= =?utf-8?B?WVhqL2pVeWtzdVBvTEJtbDNvMDFjTDFlVjBVMFR6T0puQXpCb3BnNFRlVDh1?= =?utf-8?B?TW5udEFWK2VzaGY1VVcya3N0TmYzaHk3VXRTQVIzUHYxaTQ2UTY0MENtdHNF?= =?utf-8?B?TzBwSzZWR2RFMXA0QzFLblVqVWc5UlFPVUFTbFpPTkw0MDVUN25zcGlyYVZT?= =?utf-8?B?VnhDdDA1SVlZRW1Kd2FrZ0VqeGhOMXNFZFVFM1MxQy9PcVV5L290RU9Pc0tw?= =?utf-8?B?TVZnUmgzNkZhWFlWUFlaZzdKbkRQNXpBUnk3THpKaExxdGNNaGFIWGIyMENy?= =?utf-8?B?QjJWalJSVGRyNGxmWlRtNm5tWnhQZHlESHNwUXdoTkdzSlp1ajladGEwVndG?= =?utf-8?B?a3JvM2dxNWxvMmZmcTg4cFNUbEJ6V3l2MkxZMnVySlRuTDQybC9iVFdPUW9k?= =?utf-8?B?VlpBazZheC9LZjN6RUV3SS9UVUE1dXIyRXlwb0htVStxcVVUUkRSbkc1VXZC?= =?utf-8?B?QktpZy9TcCtuWUo2eG1BTnVUL0R5RW1wZTEydWw1YjNkWml0VFlkbVliTG03?= =?utf-8?B?QU4rdjgvcWJhZFF6SVVoNHJ6aWZCbG1VWjcxTVh3RUF2QS9IaUNmMHRJK2M4?= =?utf-8?B?R015WnBNTklRY2lBZEtyT3kwU0Zwb1pkTzRXV3kwcHZKaDdEK3AzbDk2S2FP?= =?utf-8?B?b0RWaGRtRmwwN0IxY3dHekR4eTFMR0JVUmQwdGxSMnFaK0xKNmpMdUR0ZXd2?= =?utf-8?B?Q1NUYzJDdFRSaFlZbHBlVmVNRVg5eVoxbzFobjlVVEtsWW5KRDJnc1QxOGIy?= =?utf-8?B?Q3g5OEFYQUVMQUhlV1AzcnVnOEZTNHptNGtzOXBHd3FtWnJtdE1FTkdncmoy?= =?utf-8?B?c0c1K3NBZXJxV3Q3bHE2Q2M3UUs4eGlKaW4zT1VwTmJVVE90UHFSMlRXYkJ6?= =?utf-8?B?RkNGTFdpWEtxM1E0Y3lQc2JyTTlSR0ZNT2VUampKaGVUWGFhYm5hZXB3Mlpn?= =?utf-8?B?OS9YYmsvVEZ1MmtKLzgrUWRtUTdxRGNEUGZOeHJMaTZYQmM5RERuYWJlc1pG?= =?utf-8?B?cVp6dzNVVlNDcjhlamszOVdjV21Wb1pnRVlmdmxpZmgvdmRzaVIxbUFkeE1C?= =?utf-8?B?cmhmMXV0b3Y2U0h1OVlBcmU5bFBMWUdHWk1MWHFIdmZ2RVFGRXp5cEo0Vk13?= =?utf-8?B?Z1k3S3NVODNlalF0NDVRZitnUnFSNzRESDNUaVlsdHAvQ2xHbFI5anJjMjBj?= =?utf-8?B?RUVuM1hjSWI5QWRvK3RlWDVYcWNVa3VoRkZaUWVQblJzY1dCa1FLeGhPZEhi?= =?utf-8?B?dEFHdHZhYzlsTUtmRlducXBISVpJenRSQm9ieW0xZTF2QWg5OTN3UGQwV2xW?= =?utf-8?B?dW9wWGtJUW9POWZabUFSVVBEU01Wc0Y0OE1CelExMzB0NVN5S3BIM1RhRlZa?= =?utf-8?B?TkNETDJyNVUwSWtMQkdkS2FrUXhqczlNRExVVjQyb3JsZytBZitIYSt3TnBt?= =?utf-8?B?OW1tbXJJY3dkdk1jOEVteU1tSHNLUnByZ0g3a3VSa28yRmFuQktjNHVzckJJ?= =?utf-8?B?cHhjbG1VK0FjazNuY1VOaXFsbWY5TmxGS0krZUhjNFNlSUw0SW5YMXZRYXkw?= =?utf-8?B?eWVpWER3M1ZJSWFORzhCcUwrS1dSQVUrM3BrT2pVRVpOd1FhdEc1Zz09?= X-OriginatorOrg: altera.com X-MS-Exchange-CrossTenant-Network-Message-Id: 55f2a65e-50e4-430e-f369-08dee10d9594 X-MS-Exchange-CrossTenant-AuthSource: MW4PR03MB6555.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2026 18:35:59.5383 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: +44zCSBgvh/2ttA7bGOhAk4tcImuWXipA/QN3Ch8ow6S77ht5MjjaOJoXql8rvnAJqK7K8DYGBb71HL/XD1lqVtjbgvYyHXKiDuMTxfE0qQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR03MB5924 From: Hang Suan Wang Add the Altera SoCFPGA Crypto Service (FCS) driver, which exposes the Secure Data Object Service (SDOS) encrypt/decrypt operation and its crypto session lifecycle to non-secure host software. The SDOS is the FCS feature that protects data at rest: the SDM encrypts and decrypts using a key derived from a device-unique SDOS root key plus an SDM-generated IV, so the host never handles raw key material or IVs. It only submits plaintext it already owns and receives authenticated ciphertext objects managed by the SDM. A primary use case is black key provisioning, where operational keys are installed without ever appearing in cleartext. The driver is a standalone module and describes no hardware of its own. It binds by name to the "stratix10-fcs" platform device that the stratix10-svc driver registers in code, so no device-tree node is needed, and detects the SoC by matching the service-layer compatible. It exposes the following sysfs attributes. The SDOS requests are issued to the SDM through the stratix10-svc asynchronous SIP SMC. Source and destination buffers are taken from the service-layer memory pool so the SDM can reach them via physical or SMMU-remapped addresses. For encryption the SDM returns a structured object (metadata, IV, HMAC, ciphertext); for decryption it validates the HMAC, recovers the parameters from the object header, and enforces a 64-bit owner ID so that only the creator of an object can decrypt it. Signed-off-by: Hang Suan Wang Reviewed-by: Dinh Nguyen --- MAINTAINERS | 8 + drivers/firmware/Kconfig | 16 + drivers/firmware/Makefile | 2 + drivers/firmware/socfpga-fcs-core.c | 640 +++++++++++++++++++++ drivers/firmware/socfpga-fcs.c | 250 ++++++++ include/linux/firmware/intel/socfpga-fcs.h | 133 +++++ 6 files changed, 1049 insertions(+) create mode 100644 drivers/firmware/socfpga-fcs-core.c create mode 100644 drivers/firmware/socfpga-fcs.c create mode 100644 include/linux/firmware/intel/socfpga-fcs.h diff --git a/MAINTAINERS b/MAINTAINERS index 15011f5752a9..72b12b32f8fe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -946,6 +946,14 @@ ALPS PS/2 TOUCHPAD DRIVER R: Pali Roh=C3=A1r F: drivers/input/mouse/alps.* =20 +ALTERA FCS DRIVER +M: Hang Suan Wang +M: Genevieve Chan +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: drivers/firmware/socfpga-fcs* +F: include/linux/firmware/intel/socfpga-fcs* + ALTERA MAILBOX DRIVER M: Tien Sung Ang S: Maintained diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 12dc70254842..9a70def6932a 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -172,6 +172,22 @@ config INTEL_STRATIX10_RSU =20 Say Y here if you want Intel RSU support. =20 +config ALTERA_SOCFPGA_FCS + tristate "Altera SoCFPGA Crypto Service (FCS) configuration" + depends on INTEL_STRATIX10_SERVICE + default n + help + Altera SoCFPGA Crypto Service (FCS) driver exposes interfaces access + through the Intel Service Layer to user space via sysfs device + attribute nodes. It exposes the crypto and key-management services + of the Secure Device Manager (SDM) to the host software stack and + requests are forwarded to Arm Trusted Firmware. The SDM then + executes or authorizes them using device-rooted security resources. + Protected key material remains within the secure firmware boundary + and is not directly exposed to non-secure host software. + + Say Y here if you want Altera SoCFPGA FCS support. + config MTK_ADSP_IPC tristate "MTK ADSP IPC Protocol driver" depends on MTK_ADSP_MBOX diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 4ddec2820c96..e9f52f0e5f7a 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -10,6 +10,8 @@ obj-$(CONFIG_EDD) +=3D edd.o obj-$(CONFIG_DMIID) +=3D dmi-id.o obj-$(CONFIG_INTEL_STRATIX10_SERVICE) +=3D stratix10-svc.o obj-$(CONFIG_INTEL_STRATIX10_RSU) +=3D stratix10-rsu.o +obj-$(CONFIG_ALTERA_SOCFPGA_FCS) +=3D altera-fcs.o +altera-fcs-y :=3D socfpga-fcs.o socfpga-fcs-core.o obj-$(CONFIG_ISCSI_IBFT_FIND) +=3D iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) +=3D iscsi_ibft.o obj-$(CONFIG_FIRMWARE_MEMMAP) +=3D memmap.o diff --git a/drivers/firmware/socfpga-fcs-core.c b/drivers/firmware/socfpga= -fcs-core.c new file mode 100644 index 000000000000..598a4d2e3c5b --- /dev/null +++ b/drivers/firmware/socfpga-fcs-core.c @@ -0,0 +1,640 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Altera Corporation + */ + +#include +#include +#include +#include +#include +#include + +#define OWNER_ID_OFFSET 12 +#define OWNER_ID_SIZE 8 + +#define SDOS_DECRYPTION_REPROVISION_KEY_WARN 0x102 +#define SDOS_DECRYPTION_NOT_LATEST_KEY_WARN 0x103 + +#define MSG_RETRY 3 +#define RETRY_SLEEP_MS 1 + +static struct socfpga_fcs_priv *priv; + +/** + * fcs_atf_version_callback() - service-layer callback for the ATF version= query + * @client: pointer to the stratix10-svc client + * @data: pointer to the service-layer callback data + * + * Store the returned Arm Trusted Firmware version (or mailbox error) in @= priv + * and signal completion to the waiting caller. + */ +static void fcs_atf_version_callback(struct stratix10_svc_client *client, + struct stratix10_svc_cb_data *data) +{ + struct socfpga_fcs_priv *p =3D client->priv; + + p->status =3D data->status; + if (data->status =3D=3D BIT(SVC_STATUS_OK)) { + p->status =3D 0; + p->atf_version[0] =3D *((unsigned int *)data->kaddr1); + p->atf_version[1] =3D *((unsigned int *)data->kaddr2); + p->atf_version[2] =3D *((unsigned int *)data->kaddr3); + } else if (data->status =3D=3D BIT(SVC_STATUS_ERROR)) { + p->status =3D *((unsigned int *)data->kaddr1); + dev_err(client->dev, "mbox_error=3D0x%x\n", p->status); + } + + complete(&p->completion); +} + +/** + * fcs_async_callback() - completion callback for an async service request + * @ptr: pointer to the completion to signal + */ +static void fcs_async_callback(void *ptr) +{ + if (ptr) + complete(ptr); +} + +/** + * fcs_svc_send_request() - build and send an FCS command to the service l= ayer + * @command: FCS command code to dispatch + * @timeout: time to wait for completion, in jiffies + * + * Build the service-layer message for @command and send it through the + * stratix10-svc service driver, using the synchronous path for the ATF ve= rsion + * query and the asynchronous mailbox path (with retries) for the remaining + * commands. + * + * Return: 0 on success, negative errno on failure. + */ +static int fcs_svc_send_request(enum fcs_command_code command, + unsigned long timeout) +{ + struct fcs_cmd_context *k_ctx =3D &priv->k_ctx; + struct stratix10_svc_cb_data data; + void *handle =3D NULL; + int status, index; + int ret =3D 0; + struct stratix10_svc_client_msg *msg =3D kzalloc(sizeof(*msg), GFP_KERNEL= ); + + priv->status =3D 0; + priv->resp =3D 0; + + switch (command) { + case FCS_DEV_CRYPTO_OPEN_SESSION: + pr_debug("Sending command: COMMAND_FCS_CRYPTO_OPEN_SESSION\n"); + msg->command =3D COMMAND_FCS_CRYPTO_OPEN_SESSION; + break; + + case FCS_DEV_CRYPTO_CLOSE_SESSION: + pr_debug("Sending command: COMMAND_FCS_CRYPTO_CLOSE_SESSION with session= _id: 0x%x\n", + priv->session_id); + msg->arg[0] =3D priv->session_id; + msg->command =3D COMMAND_FCS_CRYPTO_CLOSE_SESSION; + break; + + case FCS_DEV_ATF_VERSION: + pr_debug("Sending command: COMMAND_SMC_ATF_BUILD_VER\n"); + msg->command =3D COMMAND_SMC_ATF_BUILD_VER; + break; + + case FCS_DEV_SDOS_DATA_EXT: + pr_debug("Sending command: COMMAND_FCS_SDOS_DATA_EXT with session_id: 0x= %x, context_id: 0x%x, op_mode: 0x%x, own: 0x%llx\n", + priv->session_id, k_ctx->sdos.context_id, + k_ctx->sdos.op_mode, k_ctx->sdos.own); + msg->arg[0] =3D priv->session_id; + msg->arg[1] =3D k_ctx->sdos.context_id; + msg->arg[2] =3D k_ctx->sdos.op_mode; + msg->arg[3] =3D k_ctx->sdos.own; + msg->payload =3D k_ctx->sdos.src; + msg->payload_length =3D k_ctx->sdos.src_size; + msg->payload_output =3D k_ctx->sdos.dst; + msg->payload_length_output =3D *k_ctx->sdos.dst_size; + msg->command =3D COMMAND_FCS_SDOS_DATA_EXT; + break; + + default: + pr_err("Unknown command: 0x%x\n", command); + ret =3D -EINVAL; + break; + } + + if (ret) { + kfree(msg); + return ret; + } + + if (command =3D=3D FCS_DEV_ATF_VERSION) { + reinit_completion(&priv->completion); + + /* + * receive_cb is a persistent field on the shared client and + * is only consumed by the synchronous stratix10_svc_send() + * path. Set it immediately before the send and clear it right + * after so it is non-NULL only for the duration of this + * transaction. This keeps the callback correct per command and + * prevents a future synchronous caller from silently + * inheriting a stale fcs_atf_version_callback. + */ + priv->client.receive_cb =3D fcs_atf_version_callback; + + ret =3D stratix10_svc_send(priv->chan, msg); + if (ret) { + pr_err("failed to send message to service channel\n"); + goto fun_ret; + } + + if (!wait_for_completion_timeout(&priv->completion, + msecs_to_jiffies(timeout))) { + pr_err("svc timeout to get completed status\n"); + ret =3D -ETIMEDOUT; + } +fun_ret: + priv->client.receive_cb =3D NULL; + kfree(msg); + return ret; + } + + /* + * Use the device-lifetime priv->completion as the async callback arg + * rather than an on-stack completion: on a timeout/abort this function + * returns while the svc layer still holds a pointer to it in the + * transaction handle, so a stack object would be freed under it. FCS + * serializes commands under priv->lock (one in-flight), so reusing + * priv->completion here is safe. + */ + reinit_completion(&priv->completion); + + for (index =3D 0; index < MSG_RETRY; index++) { + status =3D stratix10_svc_async_send(priv->chan, msg, &handle, + fcs_async_callback, + &priv->completion); + if (status =3D=3D 0) + break; + msleep(RETRY_SLEEP_MS); + } + + if (!handle || status !=3D 0) { + pr_err("Failed to send async message\n"); + kfree(msg); + return -ETIMEDOUT; + } + + ret =3D wait_for_completion_io_timeout(&priv->completion, + msecs_to_jiffies(timeout)); + if (ret > 0) + pr_debug("Received async interrupt\n"); + else + pr_err("timeout occurred while waiting for async message\n"); + + ret =3D stratix10_svc_async_poll(priv->chan, handle, &data); + + if (ret =3D=3D -EAGAIN) { + /* + * SDM still owns this transaction (STATUS_BUSY). Skip + * stratix10_svc_async_done() so its transaction_id is not + * recycled while in flight (which would alias responses); the + * handle/id are reclaimed at teardown and the caller can retry. + * msg is left unfreed to avoid a dangling handle->msg (small, + * bounded leak). Safe only while completions are poll-delivered. + */ + pr_err("SDM transaction is busy, aborting\n"); + return -EINPROGRESS; + } + + if (ret) { + pr_err("Failed to poll async message\n"); + goto out; + } + + priv->status =3D data.status; + + if (data.kaddr1) + priv->resp =3D *((u32 *)data.kaddr1); + else + priv->resp =3D 0; + +out: + stratix10_svc_async_done(priv->chan, handle); + kfree(msg); + + return ret; +} + +/** + * fcs_session_open() - open an FCS crypto service session + * @k_ctx: pointer to the kernel-side FCS command context + * + * Request a new session from the SDM, generate the session UUID and copy = it, + * together with the mailbox status, back to user space. + * + * Return: 0 on success, negative errno on failure. + */ +int fcs_session_open(struct fcs_cmd_context *const k_ctx) +{ + int ret =3D 0; + + ret =3D fcs_svc_send_request(FCS_DEV_CRYPTO_OPEN_SESSION, + SVC_FCS_REQUEST_TIMEOUT_MS); + if (ret) { + pr_err("Failed to send the cmd=3D%d,ret=3D%d\n", + FCS_DEV_CRYPTO_OPEN_SESSION, ret); + return ret; + } + + if (priv->status) { + ret =3D -EIO; + pr_err("Mailbox error, Failed to open session ret: %d\n", ret); + goto copy_mbox_status; + } + + uuid_gen(&priv->uuid_id); + + memcpy(&priv->session_id, &priv->resp, sizeof(priv->session_id)); + + ret =3D copy_to_user(k_ctx->open_session.suuid, &priv->uuid_id, + sizeof(uuid_t)) ? -EFAULT : 0; + if (ret) { + pr_err("Failed to copy session ID to user suuid addr: %p ret: %d\n", + k_ctx->open_session.suuid, ret); + } + +copy_mbox_status: + if (copy_to_user(k_ctx->error_code_addr, &priv->status, + sizeof(priv->status))) { + pr_err("Failed to copy mail box status code to user\n"); + /* surface the copy failure only if nothing failed earlier */ + if (!ret) + ret =3D -EFAULT; + } + + return ret; +} + +/** + * fcs_session_close() - close an FCS crypto service session + * @k_ctx: pointer to the kernel-side FCS command context + * + * Validate the caller-supplied session UUID, ask the SDM to close the ses= sion + * and copy the mailbox status back to user space. + * + * Return: 0 on success, negative errno on failure. + */ +int fcs_session_close(struct fcs_cmd_context *const k_ctx) +{ + int ret =3D 0; + struct fcs_cmd_context ctx; + + memcpy(&ctx, k_ctx, sizeof(struct fcs_cmd_context)); + + if (!uuid_equal(&priv->uuid_id, &ctx.close_session.suuid)) { + ret =3D -EINVAL; + pr_err("Session UUID Mismatch ret: %d\n", ret); + return ret; + } + + ret =3D fcs_svc_send_request(FCS_DEV_CRYPTO_CLOSE_SESSION, + SVC_FCS_REQUEST_TIMEOUT_MS); + if (ret) { + pr_err("Failed to send the cmd=3D%d,ret=3D%d\n", + FCS_DEV_CRYPTO_CLOSE_SESSION, ret); + return ret; + } + + memset(&priv->uuid_id, 0, sizeof(uuid_t)); + priv->session_id =3D 0; + if (priv->status) { + ret =3D -EIO; + pr_err("Mailbox error, Failed to close session ret: %d\n", ret); + } + + if (copy_to_user(ctx.error_code_addr, &priv->status, + sizeof(priv->status))) { + pr_err("Failed to copy mail box status code to user\n"); + /* surface the copy failure only if nothing failed earlier */ + if (!ret) + ret =3D -EFAULT; + } + + return ret; +} + +/** + * fcs_get_atf_version() - return the cached Arm Trusted Firmware version + * @version: array of three u32 entries to receive the major, minor and pa= tch + * version numbers + */ +void fcs_get_atf_version(u32 *version) +{ + memcpy(version, priv->atf_version, sizeof(priv->atf_version)); +} + +/** + * fcs_sdos_crypt() - perform an SDOS encrypt or decrypt operation + * @k_ctx: pointer to the kernel-side FCS command context + * + * Allocate service-layer source and destination buffers, copy the input f= rom + * user space, drive the SDOS data command and copy the result and length = back + * to user space. The operation direction is selected by @k_ctx->sdos.op_m= ode. + * + * Return: 0 on success, negative errno on failure. + */ +int fcs_sdos_crypt(struct fcs_cmd_context *const k_ctx) +{ + void *s_buf =3D NULL, *d_buf =3D NULL; + struct fcs_cmd_context ctx; + u32 output_size; + u32 dst_cap; + u64 owner_id; + int ret =3D 0; + + memcpy(&ctx, k_ctx, sizeof(struct fcs_cmd_context)); + + /* Authorize the caller against the open session before doing any work */ + if (!uuid_equal(&priv->uuid_id, &ctx.sdos.suuid)) { + pr_err("Session UUID mismatch\n"); + return -EINVAL; + } + + if (!ctx.sdos.dst || !ctx.sdos.dst_size) + return -EINVAL; + + /* Caller-provided output buffer capacity (in/out parameter) */ + if (copy_from_user(&dst_cap, ctx.sdos.dst_size, sizeof(dst_cap))) + return -EFAULT; + + if (ctx.sdos.op_mode) { + output_size =3D SDOS_ENCRYPTED_MAX_SZ; + /* encrypt: input is header + plaintext */ + if (ctx.sdos.src_size < SDOS_DECRYPTED_MIN_SZ || + ctx.sdos.src_size > SDOS_DECRYPTED_MAX_SZ) { + pr_err("Invalid SDOS src_size %u\n", ctx.sdos.src_size); + return -EINVAL; + } + } else { + output_size =3D SDOS_DECRYPTED_MAX_SZ; + /* decrypt: input is header + plaintext + HMAC */ + if (ctx.sdos.src_size < SDOS_ENCRYPTED_MIN_SZ || + ctx.sdos.src_size > SDOS_ENCRYPTED_MAX_SZ) { + pr_err("Invalid SDOS src_size %u\n", ctx.sdos.src_size); + return -EINVAL; + } + } + + s_buf =3D stratix10_svc_allocate_memory(priv->chan, ctx.sdos.src_size); + if (IS_ERR(s_buf)) { + ret =3D -ENOMEM; + pr_err("Failed to allocate memory for SDOS input data kernel buffer ret:= %d\n", + ret); + return ret; + } + + /* + * The remaining k_ctx writes intentionally target priv->k_ctx (k_ctx + * points at it): fcs_svc_send_request() reads the outgoing request from + * priv->k_ctx, so the kernel buffers and params are staged there rather + * than in the local ctx snapshot. dst_size must point at device-lifetime + * storage (priv->sdos_output_size), never a caller stack variable, so + * the staged pointer cannot dangle after this function returns. + */ + priv->sdos_output_size =3D output_size; + k_ctx->sdos.dst_size =3D &priv->sdos_output_size; + + d_buf =3D stratix10_svc_allocate_memory(priv->chan, output_size); + if (IS_ERR(d_buf)) { + ret =3D -ENOMEM; + pr_err("Failed to allocate memory for SDOS output kernel buffer ret: %d\= n", ret); + goto free_sbuf; + } + + /* Copy the user space input data to the input data kernel buffer */ + ret =3D copy_from_user(s_buf, ctx.sdos.src, + ctx.sdos.src_size) ? -EFAULT : 0; + if (ret) { + pr_err("Failed to copy SDOS data from user to kernel buffer ret: %d\n", = ret); + goto free_dbuf; + } + + /* Get Owner ID from buf */ + memcpy(&owner_id, (u8 *)s_buf + OWNER_ID_OFFSET, OWNER_ID_SIZE); + k_ctx->sdos.own =3D owner_id; + k_ctx->sdos.src =3D s_buf; + k_ctx->sdos.dst =3D d_buf; + + ret =3D fcs_svc_send_request(FCS_DEV_SDOS_DATA_EXT, + SVC_FCS_REQUEST_TIMEOUT_MS); + + if (ret =3D=3D -EINPROGRESS) { + /* + * SDM still owns this transaction and may still DMA into + * d_buf. Do NOT free s_buf/d_buf or copy results: returning + * them to the gen_pool would let the delayed firmware write + * corrupt reallocated memory. Leak them along with the + * abandoned transaction (bounded, exceptional stuck-SDM path). + */ + return -ETIMEDOUT; + } + + if (ret) { + pr_err("Failed to send the cmd=3D%d,ret=3D%d\n", FCS_DEV_SDOS_DATA_EXT, = ret); + goto free_dbuf; + } + if (priv->status && + priv->status !=3D SDOS_DECRYPTION_REPROVISION_KEY_WARN && + priv->status !=3D SDOS_DECRYPTION_NOT_LATEST_KEY_WARN) { + pr_err("Failed to perform SDOS operation ret: %d Mailbox Status =3D %d\n= ", + ret, priv->status); + goto copy_mbox_status; + } + + /* + * priv->resp is reported by firmware; never trust it to read back + * more than the kernel output buffer (d_buf) actually holds, + * otherwise the copy below would leak adjacent kernel memory. + */ + if (priv->resp > output_size) { + pr_err("SDOS output %u exceeds kernel buffer %u\n", + priv->resp, output_size); + ret =3D -EIO; + goto copy_mbox_status; + } + + /* Do not write past the caller-provided output buffer */ + if (priv->resp > dst_cap) { + pr_err("SDOS output %u exceeds caller buffer %u\n", + priv->resp, dst_cap); + ret =3D -EMSGSIZE; + goto copy_mbox_status; + } + + /* Copy the encrypted/decrypted output from kernel space to user space */ + ret =3D copy_to_user(ctx.sdos.dst, d_buf, priv->resp) ? -EFAULT : 0; + if (ret) { + pr_err("Failed to copy encrypted output to user ret: %d\n", ret); + goto copy_mbox_status; + } + + /* Copy the encrypted output length from kernel space to user space */ + ret =3D copy_to_user(ctx.sdos.dst_size, &priv->resp, + sizeof(priv->resp)) ? -EFAULT : 0; + if (ret) + pr_err("Failed to copy encrypted output length to user ret: %d\n", ret); + +copy_mbox_status: + if (copy_to_user(ctx.error_code_addr, &priv->status, + sizeof(priv->status))) { + pr_err("Failed to copy mailbox status code to user\n"); + /* surface the copy failure only if nothing failed earlier */ + if (!ret) + ret =3D -EFAULT; + } +free_dbuf: + stratix10_svc_free_memory(priv->chan, d_buf); +free_sbuf: + stratix10_svc_free_memory(priv->chan, s_buf); + + return ret; +} + +/** + * fcs_acquire_cmd_ctx() - take the FCS lock and return the command context + * + * Serialises access to the shared command context across concurrent calle= rs. + * The caller must release it with fcs_release_cmd_ctx(). + * + * Return: pointer to the locked FCS command context. + */ +struct fcs_cmd_context *fcs_acquire_cmd_ctx(void) +{ + if (!priv) + return NULL; + + mutex_lock(&priv->lock); + return &priv->k_ctx; +} + +/** + * fcs_release_cmd_ctx() - release the FCS command context lock + * @k_ctx: pointer to the FCS command context previously acquired + */ +void fcs_release_cmd_ctx(struct fcs_cmd_context *const k_ctx) +{ + mutex_unlock(&priv->lock); +} + +/** + * fcs_read_version_from_atf() - query the Arm Trusted Firmware build vers= ion + * + * Send the ATF version command to the SDM and cache the result in @priv. + * + * Return: 0 on success, negative errno on failure. + */ +static int fcs_read_version_from_atf(void) +{ + int ret =3D 0; + + ret =3D fcs_svc_send_request(FCS_DEV_ATF_VERSION, + SVC_FCS_REQUEST_TIMEOUT_MS); + if (ret) { + pr_err("Failed to send the cmd=3D%d,ret=3D%d\n", FCS_DEV_ATF_VERSION, re= t); + return ret; + } + + if (priv->status) { + ret =3D -EIO; + pr_err("Mailbox error, Failed to read ATF version ret: %d\n", ret); + } + + stratix10_svc_done(priv->chan); + + return ret; +} + +/** + * fcs_init() - allocate and initialise the FCS private state + * @dev: pointer to fcs device + * + * Allocate @priv, request the service channel, register the async client, + * and read the ATF version. + * + * Return: 0 on success, -EPROBE_DEFER or negative errno on failure. + */ +int fcs_init(struct device *dev) +{ + int ret; + + if (priv) + return -EBUSY; /* singleton: one FCS instance only */ + + priv =3D devm_kzalloc(dev, sizeof(struct socfpga_fcs_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->lock); + + priv->dev =3D dev; + priv->client.dev =3D dev; + priv->client.receive_cb =3D NULL; + priv->client.priv =3D priv; + + priv->chan =3D stratix10_svc_request_channel_byname(&priv->client, + SVC_CLIENT_FCS); + if (IS_ERR(priv->chan)) { + pr_err("couldn't get service channel %s\n", SVC_CLIENT_FCS); + return -EPROBE_DEFER; + } + + ret =3D stratix10_svc_add_async_client(priv->chan, true); + if (ret) { + pr_err("Failed to add async client\n"); + goto free_chan; + } + + init_completion(&priv->completion); + + fcs_read_version_from_atf(); + + return 0; + +free_chan: + stratix10_svc_free_channel(priv->chan); + + return ret; +} + +/** + * fcs_deinit() - tear down the FCS private state + * + * Close any open session, remove the async client, free the service chann= el + * and clear @priv. + */ +void fcs_deinit(void) +{ + if (priv && priv->session_id) { + int ret =3D fcs_svc_send_request(FCS_DEV_CRYPTO_CLOSE_SESSION, + SVC_FCS_REQUEST_TIMEOUT_MS); + if (ret) + pr_err("Failed to close FCS service session,ret=3D%d\n", ret); + } + + if (priv) { + stratix10_svc_remove_async_client(priv->chan); + stratix10_svc_free_channel(priv->chan); + } + + priv =3D NULL; +} + +/** + * fcs_cleanup() - release the FCS service channel and clear the state + */ +void fcs_cleanup(void) +{ + if (priv) + stratix10_svc_free_channel(priv->chan); + + priv =3D NULL; +} diff --git a/drivers/firmware/socfpga-fcs.c b/drivers/firmware/socfpga-fcs.c new file mode 100644 index 000000000000..616f2735743a --- /dev/null +++ b/drivers/firmware/socfpga-fcs.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026, Altera Corporation + */ + +#include +#include +#include +#include +#include + +/** + * open_session_store() - open an FCS crypto service session + * @dev: pointer to fcs device + * @attr: device attribute + * @buf: pointer to character buffer carrying the user command context + * @buf_size: size of the buffer + * + * Return: @buf_size on success, negative errno on failure. + */ +static ssize_t open_session_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t buf_size) +{ + struct fcs_cmd_context *const u_ctx =3D *(struct fcs_cmd_context **)buf; + struct fcs_cmd_context *k_ctx; + int ret; + + k_ctx =3D fcs_acquire_cmd_ctx(); + if (!k_ctx) { + dev_err(dev, "Failed get context. Context is in use\n"); + return -EBUSY; + } + + if (copy_from_user(k_ctx, u_ctx, sizeof(*k_ctx))) { + dev_err(dev, "Failed to copy context from user space\n"); + ret =3D -EFAULT; + goto out; + } + + ret =3D fcs_session_open(k_ctx); + if (ret) { + dev_err(dev, "Failed to open session\n"); + goto out; + } + + ret =3D buf_size; +out: + fcs_release_cmd_ctx(k_ctx); + + return ret; +} + +/** + * close_session_store() - close an FCS crypto service session + * @dev: pointer to fcs device + * @attr: device attribute + * @buf: pointer to character buffer carrying the user command context + * @buf_size: size of the buffer + * + * Return: @buf_size on success, negative errno on failure. + */ +static ssize_t close_session_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t buf_size) +{ + struct fcs_cmd_context *const u_ctx =3D *(struct fcs_cmd_context **)buf; + struct fcs_cmd_context *k_ctx; + int ret; + + k_ctx =3D fcs_acquire_cmd_ctx(); + if (!k_ctx) { + dev_err(dev, "Failed get context. Context is in use\n"); + return -EBUSY; + } + + if (copy_from_user(k_ctx, u_ctx, sizeof(*k_ctx))) { + dev_err(dev, "Failed to copy context from user space\n"); + ret =3D -EFAULT; + goto out; + } + + ret =3D fcs_session_close(k_ctx); + if (ret) { + dev_err(dev, "Failed to close session\n"); + goto out; + } + + ret =3D buf_size; +out: + fcs_release_cmd_ctx(k_ctx); + + return ret; +} + +/** + * atf_version_show() - report the Arm Trusted Firmware build version + * @dev: pointer to fcs device + * @attr: device attribute + * @buf: pointer to character buffer to receive the version string + * + * Return: number of bytes written to @buf. + */ +static ssize_t atf_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int version[3]; + + fcs_get_atf_version(version); + return sysfs_emit(buf, "%u.%u.%u\n", version[0], version[1], version[2]); +} + +/** + * sdos_store() - perform an SDOS encrypt/decrypt operation + * @dev: pointer to fcs device + * @attr: device attribute + * @buf: pointer to character buffer carrying the user command context + * @buf_size: size of the buffer + * + * Return: @buf_size on success, negative errno on failure. + */ +static ssize_t sdos_store(struct device *dev, struct device_attribute *att= r, + const char *buf, size_t buf_size) +{ + struct fcs_cmd_context *const u_ctx =3D *(struct fcs_cmd_context **)buf; + struct fcs_cmd_context *k_ctx; + int ret; + + k_ctx =3D fcs_acquire_cmd_ctx(); + if (!k_ctx) { + dev_err(dev, "Failed get context. Context is in use\n"); + return -EBUSY; + } + + if (copy_from_user(k_ctx, u_ctx, sizeof(*k_ctx))) { + dev_err(dev, "Failed to copy context from user space\n"); + ret =3D -EFAULT; + goto out; + } + + ret =3D fcs_sdos_crypt(k_ctx); + if (ret) { + dev_err(dev, "Failed to perform SDOS operation\n"); + goto out; + } + + ret =3D buf_size; +out: + fcs_release_cmd_ctx(k_ctx); + + return ret; +} + +static DEVICE_ATTR_WO(open_session); +static DEVICE_ATTR_WO(close_session); +static DEVICE_ATTR_RO(atf_version); +static DEVICE_ATTR_WO(sdos); + +static struct attribute *fcs_attrs[] =3D { + &dev_attr_open_session.attr, + &dev_attr_close_session.attr, + &dev_attr_atf_version.attr, + &dev_attr_sdos.attr, + NULL +}; + +static struct attribute_group fcs_group =3D { + .attrs =3D fcs_attrs, +}; + +static const struct attribute_group *fcs_groups[] =3D { + &fcs_group, + NULL, +}; + +/** + * fcs_driver_probe() - probe the FCS platform device + * @pdev: pointer to the FCS platform device + * + * Initialise the FCS state. The sysfs attribute groups are published + * automatically by the driver core via fcs_driver.driver.dev_groups. + * + * Return: 0 on success, negative errno on failure. + */ +static int fcs_driver_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + int ret; + + ret =3D fcs_init(dev); + if (ret) { + dev_err(dev, "Failed to initialize FCS\n"); + return ret; + } + + return 0; +} + +/** + * fcs_driver_remove() - remove the FCS platform device + * @pdev: pointer to the FCS platform device + * + * Tear down the FCS state. The sysfs attribute groups are removed + * automatically by the driver core. + */ +static void fcs_driver_remove(struct platform_device *pdev) +{ + fcs_deinit(); +} + +static struct platform_driver fcs_driver =3D { + .probe =3D fcs_driver_probe, + .remove =3D fcs_driver_remove, + .driver =3D { + .name =3D "stratix10-fcs", + .dev_groups =3D fcs_groups, + }, +}; + +/** + * socfpga_fcs_init() - register the FCS platform driver + * + * Return: 0 on success, negative errno on failure. + */ +static int __init socfpga_fcs_init(void) +{ + int ret; + + ret =3D platform_driver_register(&fcs_driver); + if (ret) + pr_err("Failed to register platform driver: %d\n", ret); + + return ret; +} + +/** + * socfpga_fcs_exit() - unregister the FCS platform driver + */ +static void __exit socfpga_fcs_exit(void) +{ + platform_driver_unregister(&fcs_driver); +} + +module_init(socfpga_fcs_init); +module_exit(socfpga_fcs_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Altera SoCFPGA FCS SDOS encrypt/decrypt driver"); +MODULE_AUTHOR("Altera Corporation"); +MODULE_ALIAS("platform:stratix10-fcs"); diff --git a/include/linux/firmware/intel/socfpga-fcs.h b/include/linux/fir= mware/intel/socfpga-fcs.h new file mode 100644 index 000000000000..3203be4f0f90 --- /dev/null +++ b/include/linux/firmware/intel/socfpga-fcs.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Altera Corporation + * + * SDOS-only subset of the SoCFPGA FCS (FPGA Crypto Service) interface, + * shared between the driver front-end (socfpga-fcs.c) and the command + * engine (socfpga-fcs-core.c). + */ +#ifndef SOCFPGA_FCS_H +#define SOCFPGA_FCS_H + +#include +#include +#include +#include +#include +#include + +#define SDOS_HEADER_SZ 40 +#define SDOS_HMAC_SZ 48 +#define SDOS_PLAINDATA_MIN_SZ 32 +#define SDOS_PLAINDATA_MAX_SZ 32672 +#define SDOS_DECRYPTED_MIN_SZ (SDOS_PLAINDATA_MIN_SZ + SDOS_HEADER_SZ) +#define SDOS_DECRYPTED_MAX_SZ (SDOS_PLAINDATA_MAX_SZ + SDOS_HEADER_SZ) +#define SDOS_ENCRYPTED_MIN_SZ (SDOS_PLAINDATA_MIN_SZ + SDOS_HEADER_SZ + SD= OS_HMAC_SZ) +#define SDOS_ENCRYPTED_MAX_SZ (SDOS_PLAINDATA_MAX_SZ + SDOS_HEADER_SZ + SD= OS_HMAC_SZ) + +#pragma pack(push, 1) +struct fcs_cmd_context { + /* Error status variable address */ + int *error_code_addr; + union { + struct { + uuid_t *suuid; + unsigned int *suuid_len; + } open_session; + + struct { + uuid_t suuid; + } close_session; + + struct { + uuid_t suuid; + u32 context_id; + char *rng; + u32 rng_len; + } rng; + + struct { + uuid_t suuid; + u32 context_id; + u32 op_mode; + char *src; + u32 src_size; + char *dst; + u32 *dst_size; + u16 id; + u64 own; + int pad; + } sdos; + }; +}; + +#pragma pack(pop) + +/** + * Private driver state for the SoCFPGA FCS that holds the SDM/ATF service + * channel, the shared command context and the lock that guards it, and the + * latest mailbox status/response. + */ +struct socfpga_fcs_priv { + /* Communication channel */ + struct stratix10_svc_chan *chan; + struct fcs_cmd_context k_ctx; + struct stratix10_svc_client client; + struct completion completion; + /* + * Serializes FCS command submission: guards the shared k_ctx and the + * single in-flight mailbox transaction (completion/status/resp) so only + * one SDM request is outstanding at a time. This is the lock taken by + * fcs_acquire_cmd_ctx() and dropped by fcs_release_cmd_ctx(). + */ + struct mutex lock; + int status; + u32 resp; + u32 session_id; + uuid_t uuid_id; + struct device *dev; + u32 atf_version[3]; + /* + * Backing store for the SDOS output-buffer capacity. The outgoing + * request stages k_ctx.sdos.dst_size to point here (device-lifetime) + * instead of at a caller stack variable, so the pointer never dangles. + */ + u32 sdos_output_size; +}; + +enum fcs_command_code { + FCS_DEV_COMMAND_NONE =3D 0, + FCS_DEV_CRYPTO_OPEN_SESSION, + FCS_DEV_CRYPTO_CLOSE_SESSION, + FCS_DEV_SDOS_DATA_EXT, + FCS_DEV_ATF_VERSION, +}; + +/* Take the FCS lock and return the shared command context. */ +struct fcs_cmd_context *fcs_acquire_cmd_ctx(void); + +/* Release the FCS lock previously taken by fcs_acquire_cmd_ctx(). */ +void fcs_release_cmd_ctx(struct fcs_cmd_context *const k_ctx); + +/* Allocate the FCS state and set up the service channel; read ATF version= . */ +int fcs_init(struct device *dev); + +/* Close any open session and release the service channel. */ +void fcs_deinit(void); + +/* Release the service channel and clear the FCS state. */ +void fcs_cleanup(void); + +/* Request the SDM to open a crypto service session. */ +int fcs_session_open(struct fcs_cmd_context *const k_ctx); + +/* Request the SDM to close a previously opened session. */ +int fcs_session_close(struct fcs_cmd_context *const k_ctx); + +/* Return the cached Arm Trusted Firmware build version. */ +void fcs_get_atf_version(u32 *version); + +/* Perform an SDOS (Secure Data Object Service) encrypt/decrypt operation.= */ +int fcs_sdos_crypt(struct fcs_cmd_context *const k_ctx); + +#endif /* SOCFPGA_FCS_H */ --=20 2.43.7