From nobody Wed Oct 1 21:27:06 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.84]) (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 B974C2DC79C; Wed, 1 Oct 2025 06:11:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.84 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299090; cv=pass; b=qoQKVklM69U/++CzDgEARWC2EOfbU6qUhPTRC8rGOOAVXgw0qYgmJhts5iQI0xf+c5bAGVfVsjWgPH3s/K4t0S5e4wb6ojfr+XODE+u9ofhd/7yVPf+Cye/Y9cBuhtNzbFBYpzxsh9x06gByPVGqiWETZgJ2ZIte0EJH/ul/7NI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299090; c=relaxed/simple; bh=kwcq6wSawbK9MsfC4RAARhadzFKSQCwjq8nbkMxWphQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=PD6ZSgnP7Dp24Di7jRg+l2nBfFvXFpUdsX8zILmgJa2rOsco90tuAD0LAtZXzwqqJ/Lnxe1vpjgm6uSkAn42/boI3kRUt4hSH/+ydC9XbW23+pTl9eV7wSsdUR1H407Ebjg9Jfg2PpA/OuFVraWgTGAYqA6NvMaV0mKbLKRPt1g= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=RzGu/TOo; arc=pass smtp.client-ip=85.215.255.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="RzGu/TOo" ARC-Seal: i=1; a=rsa-sha256; t=1759298898; cv=none; d=strato.com; s=strato-dkim-0002; b=Mh0GI93rstICfZ/4Xldb0YhqjdQbNtHrVZ3OL9KNeM4kBRkoziYjo1cRVrGOJvU1ar QC6xkzmhtEDUq3iJtQd+PQq82/5HWMnZo5VMwi4jYBZTbRuXSt4aYpSG2lRkxq3wrRXo SU16vjJtNVtJ2Lwkdx8r7F7zvRcx/lM2hXlsFolDkkW5dDG4QEbAaxBjrs5jV7ja48fU +dVkmG/h0cLua4voWNY6NNebRKeBuutanqOrO4JWepSfuXCLhJxRy1zOPIBeeoxiSE7P DHzEtKestJZyOiKT7UCmQXbr/4ZTTVL1ZfTVdX/DQaLY2psLL4obgbMJuMXuzn8FaGzI yfew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298898; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=YSyxsdgrlVxMmnvY9WXOMGgPGiuic8SC+YqcLO+lvOs=; b=ZUnbPGTD71Byczatx+uiwRNEGVwMVdWTQvUs9YU9AQIRvnk1NVa2XkCkl/PX9cvZgX gGtH4fJEyhc7i9+aPVznDxsTqe2vzvLwfFpDOtT5Xa8OZpQAW7klJulM7vGBFaDCa156 az9YGmCfPHURUifVLk600m1ITcDh5Qz4qs9XT6e6Ev+lB+p3iKMDGoapm5+Ps9+tzbS+ 9D2wv5yxBSrz/95idIb73J0BA2+xoD3U5ydPpIkiUJCdZfCY2ASmmJo0v1CVCbpn0m2V 6tGkFZsEdJFCVj6XMVZyAg1J3AA8TmQWkvjIsWPg69B3aRo5iv2IcA/jDkcFiKT761uR 3mgg== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298898; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=YSyxsdgrlVxMmnvY9WXOMGgPGiuic8SC+YqcLO+lvOs=; b=RzGu/TOoF0jh33jqkzLVs2GViiCxDI4SxtsjyE/GPnqN9ArkQyHgt6+yIhmLWj9YXv PleP51qR/VzJFIftFhHaeZs39uNyvKb0YTq9ail5NyLO4DZTYF0hfwyPuTfagZgXjFHA 8M5o2BBIVFA04hdf3hehUu44xDkvahw+fVvQgXVoUyI1vl/61ZZtxMlH+bfkOULbQYRI kgMg78xc+ut87b7PPi7p5qaYqZtXljz8Ns3bMANRkbMxgGpimKlV2X1g4a0RxzPSmNMW bQegjIj61p2GUZIKKD/c2r8BALM1C1UM9IWXoSpdyZIV0d8d95h5X1C+jDJkf/LOcQqV kzyQ== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O2JmZOo2yQsAdmCB+Gw==" Received: from Munilab01-lab.fritz.box by smtp.strato.de (RZmta 53.3.2 AUTH) with ESMTPSA id z9ebc619168HY7H (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 1 Oct 2025 08:08:17 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] rpmb: move rpmb_frame struct and constants to common header Date: Wed, 1 Oct 2025 08:08:03 +0200 Message-Id: <20251001060805.26462-2-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251001060805.26462-1-beanhuo@iokpp.de> References: <20251001060805.26462-1-beanhuo@iokpp.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Bean Huo Move struct rpmb_frame and RPMB operation constants from MMC block driver to include/linux/rpmb.h for reuse across different RPMB implementations (UFS, NVMe, etc.). Signed-off-by: Bean Huo Reviewed-by: Bart Van Assche --- drivers/mmc/core/block.c | 42 -------------------------------------- include/linux/rpmb.h | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index b32eefcca4b7..bd5f6fcb03af 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -79,48 +79,6 @@ MODULE_ALIAS("mmc:block"); #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) #define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8) =20 -/** - * struct rpmb_frame - rpmb frame as defined by eMMC 5.1 (JESD84-B51) - * - * @stuff : stuff bytes - * @key_mac : The authentication key or the message authentication - * code (MAC) depending on the request/response type. - * The MAC will be delivered in the last (or the only) - * block of data. - * @data : Data to be written or read by signed access. - * @nonce : Random number generated by the host for the requests - * and copied to the response by the RPMB engine. - * @write_counter: Counter value for the total amount of the successful - * authenticated data write requests made by the host. - * @addr : Address of the data to be programmed to or read - * from the RPMB. Address is the serial number of - * the accessed block (half sector 256B). - * @block_count : Number of blocks (half sectors, 256B) requested to be - * read/programmed. - * @result : Includes information about the status of the write coun= ter - * (valid, expired) and result of the access made to the R= PMB. - * @req_resp : Defines the type of request and response to/from the me= mory. - * - * The stuff bytes and big-endian properties are modeled to fit to the spe= c. - */ -struct rpmb_frame { - u8 stuff[196]; - u8 key_mac[32]; - u8 data[256]; - u8 nonce[16]; - __be32 write_counter; - __be16 addr; - __be16 block_count; - __be16 result; - __be16 req_resp; -} __packed; - -#define RPMB_PROGRAM_KEY 0x1 /* Program RPMB Authentication Key */ -#define RPMB_GET_WRITE_COUNTER 0x2 /* Read RPMB write counter */ -#define RPMB_WRITE_DATA 0x3 /* Write data to RPMB partition */ -#define RPMB_READ_DATA 0x4 /* Read data from RPMB partition */ -#define RPMB_RESULT_READ 0x5 /* Read result request (Internal) */ - #define RPMB_FRAME_SIZE sizeof(struct rpmb_frame) #define CHECK_SIZE_NEQ(val) ((val) !=3D sizeof(struct rpmb_frame)) #define CHECK_SIZE_ALIGNED(val) IS_ALIGNED((val), sizeof(struct rpmb_frame= )) diff --git a/include/linux/rpmb.h b/include/linux/rpmb.h index cccda73eea4d..ed3f8e431eff 100644 --- a/include/linux/rpmb.h +++ b/include/linux/rpmb.h @@ -61,6 +61,50 @@ struct rpmb_dev { =20 #define to_rpmb_dev(x) container_of((x), struct rpmb_dev, dev) =20 +/** + * struct rpmb_frame - RPMB frame structure for authenticated access + * + * @stuff : stuff bytes, a padding/reserved area of 196 bytes at the + * beginning of the RPMB frame. They don=E2=80=99t carry m= eaningful + * data but are required to make the frame exactly 512 byt= es. + * @key_mac : The authentication key or the message authentication + * code (MAC) depending on the request/response type. + * The MAC will be delivered in the last (or the only) + * block of data. + * @data : Data to be written or read by signed access. + * @nonce : Random number generated by the host for the requests + * and copied to the response by the RPMB engine. + * @write_counter: Counter value for the total amount of the successful + * authenticated data write requests made by the host. + * @addr : Address of the data to be programmed to or read + * from the RPMB. Address is the serial number of + * the accessed block (half sector 256B). + * @block_count : Number of blocks (half sectors, 256B) requested to be + * read/programmed. + * @result : Includes information about the status of the write coun= ter + * (valid, expired) and result of the access made to the R= PMB. + * @req_resp : Defines the type of request and response to/from the me= mory. + * + * The stuff bytes and big-endian properties are modeled to fit to the spe= c. + */ +struct rpmb_frame { + u8 stuff[196]; + u8 key_mac[32]; + u8 data[256]; + u8 nonce[16]; + __be32 write_counter; + __be16 addr; + __be16 block_count; + __be16 result; + __be16 req_resp; +}; + +#define RPMB_PROGRAM_KEY 0x1 /* Program RPMB Authentication Key */ +#define RPMB_GET_WRITE_COUNTER 0x2 /* Read RPMB write counter */ +#define RPMB_WRITE_DATA 0x3 /* Write data to RPMB partition */ +#define RPMB_READ_DATA 0x4 /* Read data from RPMB partition */ +#define RPMB_RESULT_READ 0x5 /* Read result request (Internal) */ + #if IS_ENABLED(CONFIG_RPMB) struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev); void rpmb_dev_put(struct rpmb_dev *rdev); --=20 2.34.1 From nobody Wed Oct 1 21:27:06 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [81.169.146.169]) (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 587102D9485; Wed, 1 Oct 2025 06:11:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=81.169.146.169 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299085; cv=pass; b=p8nk37HXLe6U4GlEOSALdaZtWleUHsqK2jQS472nrLAlRC7WfLeQf4BOlLbIzk8ZMprSK05NIcm6LOJndNdLW8/VA9eXJI2CwzNF+n/BUp2eE/wCmRHEGRJ94u6oFUD54voATUN6skyNDNxwsb/sBWA8dNVbNO38Lqgw4hOHNSM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299085; c=relaxed/simple; bh=y0a0WLyhGtAaP/H3DJ18c5oLwvRNpP2gV+sk34yrVis=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=phKrvI/OWdMENAiuLNQrjgpUp2HrCaLwC8Rn04Hi2HKJUMT0O2xq3m/t2Bx58nwU/UxJ2hi3X+iBGT+LS5ofw5QjmDJw864gJOTkcjcUxAEp8bhz3dolALL9YRV6vrcwiiODnMBe5j6bAbHuEVot3cvP+X9mqte9ZVo4ed8xOw8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=LVMcf67Q; arc=pass smtp.client-ip=81.169.146.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="LVMcf67Q" ARC-Seal: i=1; a=rsa-sha256; t=1759298899; cv=none; d=strato.com; s=strato-dkim-0002; b=tD42FWj487HHcbih9Fbn0zPmIpXBALCbhE12X2b5ArTbrZCkRC7HakG6ovu6kJXWgP nPkezAXjcfgyRPs5yNCCvwVUcSVEpmU0giJ7zqrprry4xkW8f9OmOUInB0DtcA0ofCVD yz6lumddpXFqKh3uxDIGSh2yGBNFK2fRCGDey5/ai9eDwiX9wywGPIbjnhczebvi+bpY HRY2B3+H1ZGewAdeBa9snlZQaSc3YwTU5QlK5oD6fvMykonWMg57/AfWqDvT4TWghtKe nvWsh8srb6TmoDJdnF+3Sagrh/z01UksPxnmsZRboC9DLhYGRDxA59eW7oUwyW7L3lqF RLgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298899; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=kcTe3eL3ICiBimw9rIl8MZGWcP9OTJ1LXXZ5Tc5bV2w=; b=O3qJoonWwsrKawluSmoF4xE6oMgEN2HAQ5WdiQCCqP72YwQ9JJNizFNvQNDHKzCkn2 8wTIbktuFlu0O2XNXF9bsAT+Bk6c73uOIW4D5f2rJjkcBjdYgJYfbPE8mOJnuWqIm3+B EC6n/bpX5Z9Bz5XWX2u6FL+EjERQbJkL1lksv408ApNtMrdDnUn035Y1ovnVS/hfIXZJ q4ouUunnws7uxLo1fqUcTWkgTKgzrPX0JGcJlsf0XMcbjziIqgBG59FKCBuAJ5Ur6l2H 781PmwXjPyVaE3y4K+IVKl6obTS9AKM95r86zsv7gL0usS4ocB54segCDt0mEJBUFHtX 7HiA== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298899; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=kcTe3eL3ICiBimw9rIl8MZGWcP9OTJ1LXXZ5Tc5bV2w=; b=LVMcf67QT+PLyvKl3DaOZD8oxJBTAQh2QqmmuO4rXBLkzSEDaq9wh9CxOKNpxnbN94 vECjGBooJ0p4/yF0s+2mvii4QWQXWtmCbxNkz5PQJngOXQHlQlhR7Mz7xYOrtx6aTXYQ Cy3YUXg8JHzcMeXpLzM1L3Pm0muvDk3hlon8kqnlIBVnka4ddp3H3bCFW74ZKnCD/s0R dMgLfK/vyV6K7fncWUcWRXWJJU0F4Qs2tDM2VFN8rO+UVJ8REb0I/56TDW0GxiiGAzmt O5FfqTwM8Ok455JTcSdvzM9Qq484QH8x0pwkay4yT1+7MlBnQOFZGZU/MGk7JTRVADnA avxA== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O2JmZOo2yQsAdmCB+Gw==" Received: from Munilab01-lab.fritz.box by smtp.strato.de (RZmta 53.3.2 AUTH) with ESMTPSA id z9ebc619168IY7I (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 1 Oct 2025 08:08:18 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Date: Wed, 1 Oct 2025 08:08:04 +0200 Message-Id: <20251001060805.26462-3-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251001060805.26462-1-beanhuo@iokpp.de> References: <20251001060805.26462-1-beanhuo@iokpp.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Bean Huo The function ufshcd_read_string_desc() was duplicating memory starting from the beginning of struct uc_string_id, which included the length and type fields. As a result, the allocated buffer contained unwanted metadata in addition to the string itself. The correct behavior is to duplicate only the Unicode character array in the structure. Update the code so that only the actual string content is copied into the new buffer. Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") Signed-off-by: Bean Huo Reviewed-by: Bart Van Assche --- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2e1fa8cf83f5..79c7588be28a 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3823,7 +3823,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 d= esc_index, str[ret++] =3D '\0'; =20 } else { - str =3D kmemdup(uc_str, uc_str->len, GFP_KERNEL); + str =3D kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); if (!str) { ret =3D -ENOMEM; goto out; --=20 2.34.1 From nobody Wed Oct 1 21:27:06 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.84]) (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 9CAF81B808; Wed, 1 Oct 2025 06:14:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.84 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299262; cv=pass; b=hq9CLxzlueGYHmPBJeqNA8GANxmoCdDXc09d08y1p0p1UvCWz1SY7cELVdkwqrAuLdCmrOo3S2opcfzqJ9odjyCghpezktm7JgzA0dZkC957eWg+cEEFhQR3WIK6ofiVQemmooF3bYRqKWU89ZeFub+QbBZch9QlkfCJAc+TgDE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759299262; c=relaxed/simple; bh=lBQFQ17ZpjzPpYGEDHwGB7twj+0FCcbWOCQfh3VI+Jg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=gRK+pVzUDhRO1FT3CILEufDO7vz1hLt3v70qczXipUNFeAOfL69hCvKhUVeA5MGGez7f/lQ5VajbQ7P4pg+0Ccr7uclivKPRIsWxeMfgREIY+88JsuZRNMCaCMtQH5fkvrpYLEWlnr1gz0AeRHoja4AnywxoTajDY0pA+L7DYFQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=H9w8aLTK; arc=pass smtp.client-ip=85.215.255.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="H9w8aLTK" ARC-Seal: i=1; a=rsa-sha256; t=1759298901; cv=none; d=strato.com; s=strato-dkim-0002; b=M/IViSOfgyizqnYCoKlRuxDEwFuVPPF0DhL1NItHgl5iMhF1u8twDNCplg799Ra1cw Hv7LBdU4rhNN0Dn6yax5+zCbn0DjY/FPJafEI3B62NL9Axk7c8ZqaboNql8dISF9G2uz iBv70N1y6AWGgeOvDNR4q0xYYv5I+qLH4mbDnlqAPW+tNHFQBJ0EKhi5Qqb+KMrS4VbZ WvdpwTQCYgzMDTC1ePa7SgCzPUCxiFs04fsWSn7LVbgrIOPEaFqknU6wjjbxGfB9yK8L 0RIhHUCy0K3+D8l9KEbhYFhJZBUGYwcJs4xNxLj+zGQYGDLA+XQ3YVQ1LUOWbxMndQKx OfOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298901; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=fwPEBhbpjfg2zPCa/NOMKd/VYDayRsr/k1oZNVD7huc=; b=rUxvofiI1Y5KFs/2rdqAdEGnmTv/VNSfHq20U8UBAcsAKiCQ+i2JLfATJaAJ1+HamT lXGGEBfZnr9oKcWJdCQt6j5UhuU8RmAOLzwhMm7STVQJHJN0OrDj/59wKNQDS4GuWLrN y5WY7ZCovBQU9/9LHlW6qVTo5FMZBX/TLjONF+pfhNA2U5a7OwETWabXVNfAasNL5GG/ /jaXG2dZycmgz8uiEfI9obZZMbcjnmbTx8X0oolgTIeIWPR4ToolSVidn2pycwWG6xRJ lxExLaYRMhmshu4bnwSSzs3dWm7tbbmmBqcXzeH/ocVLK2SIXiL0wOjyl61TSpqfQIF2 tiJQ== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1759298901; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=fwPEBhbpjfg2zPCa/NOMKd/VYDayRsr/k1oZNVD7huc=; b=H9w8aLTK2ZzzMCoY7z9YOb0RwNV4k44qcAi+setbUhW6TDQt9oQpouFduThepkp10W 8jAm2X1B1W9Dkf2im641YQdbpTZWWmC4bkf9r1yDwj5Rxr1iAEU1J7RDWsTcmvi+jZF1 tvbBbq/7tQkfXdpjxsA5t0EA0+QIpHMiIMTskTfWJ2I3bE07VJVTTl2XPmTdu/9Bg+fU 0KeFcE3+JIHUdgGMmsMgZbOkxOk6D6PKiIekn5gCPLpDDLHFLg2rho2/5IEUX9FHdwkk YBznBgqzJ3zlKJIGx+XtbylbhuFPgSxeGCxmwhIea8EPmGFU7RgKGM1VHuzl2wWcfXfi vvBg== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O2JmZOo2yQsAdmCB+Gw==" Received: from Munilab01-lab.fritz.box by smtp.strato.de (RZmta 53.3.2 AUTH) with ESMTPSA id z9ebc619168KY7J (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 1 Oct 2025 08:08:20 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Date: Wed, 1 Oct 2025 08:08:05 +0200 Message-Id: <20251001060805.26462-4-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251001060805.26462-1-beanhuo@iokpp.de> References: <20251001060805.26462-1-beanhuo@iokpp.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Bean Huo This patch adds OP-TEE based RPMB support for UFS devices. This enables sec= ure RPMB operations on UFS devices through OP-TEE, providing the same functionality available for = eMMC devices and extending kernel-based secure storage support to UFS-based systems. Benefits of OP-TEE based RPMB implementation: - Eliminates dependency on userspace supplicant for RPMB access - Enables early boot secure storage access (e.g., fTPM, secure UEFI variabl= es) - Provides kernel-level RPMB access as soon as UFS driver is initialized - Removes complex initramfs dependencies and boot ordering requirements - Ensures reliable and deterministic secure storage operations - Supports both built-in and modular fTPM configurations Co-developed-by: Can Guo Signed-off-by: Can Guo Signed-off-by: Bean Huo Reviewed-by: Bart Van Assche --- drivers/misc/Kconfig | 2 +- drivers/ufs/core/Makefile | 1 + drivers/ufs/core/ufs-rpmb.c | 253 +++++++++++++++++++++++++++++++++ drivers/ufs/core/ufshcd-priv.h | 13 ++ drivers/ufs/core/ufshcd.c | 30 +++- include/ufs/ufs.h | 4 + include/ufs/ufshcd.h | 3 + 7 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 drivers/ufs/core/ufs-rpmb.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b9ca56930003..46ffa62eac6e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -106,7 +106,7 @@ config PHANTOM =20 config RPMB tristate "RPMB partition interface" - depends on MMC + depends on MMC || SCSI_UFSHCD help Unified RPMB unit interface for RPMB capable devices such as eMMC and UFS. Provides interface for in-kernel security controllers to access diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile index cf820fa09a04..51e1867e524e 100644 --- a/drivers/ufs/core/Makefile +++ b/drivers/ufs/core/Makefile @@ -2,6 +2,7 @@ =20 obj-$(CONFIG_SCSI_UFSHCD) +=3D ufshcd-core.o ufshcd-core-y +=3D ufshcd.o ufs-sysfs.o ufs-mcq.o +ufshcd-core-$(CONFIG_RPMB) +=3D ufs-rpmb.o ufshcd-core-$(CONFIG_DEBUG_FS) +=3D ufs-debugfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) +=3D ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) +=3D ufshcd-crypto.o diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c new file mode 100644 index 000000000000..84cdcf8efeb3 --- /dev/null +++ b/drivers/ufs/core/ufs-rpmb.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UFS OP-TEE based RPMB Driver + * + * Copyright (C) 2025 Micron Technology, Inc. + * Copyright (C) 2025 Qualcomm Technologies, Inc. + * + * Authors: + * Bean Huo + * Can Guo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ufshcd-priv.h" + +#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */ +#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB b= yte3 */ + +static const struct bus_type ufs_rpmb_bus_type =3D { + .name =3D "ufs_rpmb", +}; + +/* UFS RPMB device structure */ +struct ufs_rpmb_dev { + u8 region_id; + struct device dev; + struct rpmb_dev *rdev; + struct ufs_hba *hba; + struct list_head node; +}; + +static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, siz= e_t len, bool send) +{ + struct scsi_device *sdev =3D hba->ufs_rpmb_wlun; + u8 cdb[12] =3D { }; + + cdb[0] =3D send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN; + cdb[1] =3D UFS_RPMB_SEC_PROTOCOL; + put_unaligned_be16(spsp, &cdb[2]); + put_unaligned_be32(len, &cdb[6]); + + return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, + buffer, len, /*timeout=3D*/30 * HZ, 0, NULL); +} + +/* UFS RPMB route frames implementation */ +static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int= req_len, u8 *resp, + unsigned int resp_len) +{ + struct ufs_rpmb_dev *ufs_rpmb =3D dev_get_drvdata(dev); + struct rpmb_frame *frm_out =3D (struct rpmb_frame *)req; + bool need_result_read =3D true; + u16 req_type, protocol_id; + struct ufs_hba *hba; + int ret; + + if (!ufs_rpmb) { + dev_err(dev, "Missing driver data\n"); + return -ENODEV; + } + + if (!req || !req_len || !resp || !resp_len) + return -EINVAL; + + hba =3D ufs_rpmb->hba; + + req_type =3D be16_to_cpu(frm_out->req_resp); + + switch (req_type) { + case RPMB_PROGRAM_KEY: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struc= t rpmb_frame)) + return -EINVAL; + break; + case RPMB_GET_WRITE_COUNTER: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struc= t rpmb_frame)) + return -EINVAL; + need_result_read =3D false; + break; + case RPMB_WRITE_DATA: + if (req_len % sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struct r= pmb_frame)) + return -EINVAL; + break; + case RPMB_READ_DATA: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len % sizeof(struct r= pmb_frame)) + return -EINVAL; + need_result_read =3D false; + break; + default: + dev_err(dev, "Unknown request type=3D0x%04x\n", req_type); + return -EINVAL; + } + + protocol_id =3D ufs_rpmb->region_id << 8 | UFS_RPMB_SEC_PROTOCOL_ID; + + ret =3D ufs_sec_submit(hba, protocol_id, req, req_len, true); + if (ret) { + dev_err(dev, "Command failed with ret=3D%d\n", ret); + return ret; + } + + if (need_result_read) { + struct rpmb_frame *frm_resp =3D (struct rpmb_frame *)resp; + + memset(frm_resp, 0, sizeof(*frm_resp)); + frm_resp->req_resp =3D cpu_to_be16(RPMB_RESULT_READ); + ret =3D ufs_sec_submit(hba, protocol_id, resp, resp_len, true); + if (ret) { + dev_err(dev, "Result read request failed with ret=3D%d\n", ret); + return ret; + } + } + + if (!ret) { + ret =3D ufs_sec_submit(hba, protocol_id, resp, resp_len, false); + if (ret) + dev_err(dev, "Response read failed with ret=3D%d\n", ret); + } + + return ret; +} + +static void ufs_rpmb_device_release(struct device *dev) +{ + struct ufs_rpmb_dev *ufs_rpmb =3D dev_get_drvdata(dev); + + if (ufs_rpmb->rdev) + rpmb_dev_unregister(ufs_rpmb->rdev); +} + +/* UFS RPMB device registration */ +int ufs_rpmb_probe(struct ufs_hba *hba) +{ + struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp; + struct rpmb_dev *rdev; + u8 cid[16] =3D { }; + int region; + u8 *sn; + u32 cap; + int ret; + + if (!hba->ufs_rpmb_wlun) { + dev_info(hba->dev, "No RPMB LUN, skip RPMB registration\n"); + return -ENODEV; + } + + /* Get the UNICODE serial number data */ + sn =3D hba->dev_info.serial_number; + if (!sn) { + dev_err(hba->dev, "Serial number not available\n"); + return -EINVAL; + } + + INIT_LIST_HEAD(&hba->rpmbs); + + /* Copy serial number into device ID (max 15 chars + NUL). */ + strscpy(cid, sn, sizeof(cid)); + + struct rpmb_descr descr =3D { + .type =3D RPMB_TYPE_UFS, + .route_frames =3D ufs_rpmb_route_frames, + .dev_id_len =3D sizeof(cid), + .reliable_wr_count =3D hba->dev_info.rpmb_io_size, + }; + + for (region =3D 0; region < 4; region++) { + cap =3D hba->dev_info.rpmb_region_size[region]; + if (!cap) + continue; + + ufs_rpmb =3D devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL); + if (!ufs_rpmb) { + ret =3D -ENOMEM; + goto err_out; + } + + ufs_rpmb->hba =3D hba; + ufs_rpmb->dev.parent =3D &hba->ufs_rpmb_wlun->sdev_gendev; + ufs_rpmb->dev.bus =3D &ufs_rpmb_bus_type; + ufs_rpmb->dev.release =3D ufs_rpmb_device_release; + dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region); + + /* Set driver data BEFORE device_register */ + dev_set_drvdata(&ufs_rpmb->dev, ufs_rpmb); + + ret =3D device_register(&ufs_rpmb->dev); + if (ret) { + dev_err(hba->dev, "Failed to register UFS RPMB device %d\n", region); + put_device(&ufs_rpmb->dev); + goto err_out; + } + + /* Make CID unique for this region by appending region numbe */ + cid[sizeof(cid) - 1] =3D region; + descr.dev_id =3D (void *)cid; + descr.capacity =3D cap; + + /* Register RPMB device */ + rdev =3D rpmb_dev_register(&ufs_rpmb->dev, &descr); + if (IS_ERR(rdev)) { + dev_err(hba->dev, "Failed to register UFS RPMB device.\n"); + device_unregister(&ufs_rpmb->dev); + ret =3D PTR_ERR(rdev); + goto err_out; + } + + ufs_rpmb->rdev =3D rdev; + ufs_rpmb->region_id =3D region; + + list_add_tail(&ufs_rpmb->node, &hba->rpmbs); + + dev_info(hba->dev, "UFS RPMB region %d registered (capacity=3D%u)\n", re= gion, cap); + } + + return 0; +err_out: + list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) { + list_del(&it->node); + device_unregister(&it->dev); + } + + return ret; +} + +/* UFS RPMB remove handler */ +void ufs_rpmb_remove(struct ufs_hba *hba) +{ + struct ufs_rpmb_dev *ufs_rpmb, *tmp; + + if (list_empty(&hba->rpmbs)) + return; + + /* Remove all registered RPMB devices */ + list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) { + dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id); + /* Remove from list first */ + list_del(&ufs_rpmb->node); + /* Unregister device */ + device_unregister(&ufs_rpmb->dev); + } + + dev_info(hba->dev, "All UFS RPMB devices unregistered\n"); +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("OP-TEE RPMB subsystem based UFS RPMB driver"); diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index d0a2c963a27d..523828d6b1d5 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -411,4 +411,17 @@ static inline u32 ufshcd_mcq_get_sq_head_slot(struct u= fs_hw_queue *q) return val / sizeof(struct utp_transfer_req_desc); } =20 +#ifdef CONFIG_RPMB +int ufs_rpmb_probe(struct ufs_hba *hba); +void ufs_rpmb_remove(struct ufs_hba *hba); +#else +static inline int ufs_rpmb_probe(struct ufs_hba *hba) +{ + return 0; +} +static inline void ufs_rpmb_remove(struct ufs_hba *hba) +{ +} +#endif + #endif /* _UFSHCD_PRIV_H_ */ diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 79c7588be28a..ec1670d94946 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5240,10 +5240,15 @@ static void ufshcd_lu_init(struct ufs_hba *hba, str= uct scsi_device *sdev) desc_buf[UNIT_DESC_PARAM_LU_WR_PROTECT] =3D=3D UFS_LU_POWER_ON_WP) hba->dev_info.is_lu_power_on_wp =3D true; =20 - /* In case of RPMB LU, check if advanced RPMB mode is enabled */ - if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] =3D=3D UFS_UPIU_RPMB_WLUN && - desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4)) - hba->dev_info.b_advanced_rpmb_en =3D true; + /* In case of RPMB LU, check if advanced RPMB mode is enabled, and get re= gion size */ + if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] =3D=3D UFS_UPIU_RPMB_WLUN) { + if (desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4)) + hba->dev_info.b_advanced_rpmb_en =3D true; + hba->dev_info.rpmb_region_size[0] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON0_SIZE]; + hba->dev_info.rpmb_region_size[1] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON1_SIZE]; + hba->dev_info.rpmb_region_size[2] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON2_SIZE]; + hba->dev_info.rpmb_region_size[3] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON3_SIZE]; + } =20 =20 kfree(desc_buf); @@ -8151,8 +8156,11 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); if (IS_ERR(sdev_rpmb)) { ret =3D PTR_ERR(sdev_rpmb); + hba->ufs_rpmb_wlun =3D NULL; + dev_err(hba->dev, "%s: RPMB WLUN not found\n", __func__); goto remove_ufs_device_wlun; } + hba->ufs_rpmb_wlun =3D sdev_rpmb; ufshcd_blk_pm_runtime_init(sdev_rpmb); scsi_device_put(sdev_rpmb); =20 @@ -8425,6 +8433,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba) int err; u8 model_index; u8 *desc_buf; + u8 serial_index; struct ufs_dev_info *dev_info =3D &hba->dev_info; =20 desc_buf =3D kzalloc(QUERY_DESC_MAX_SIZE, GFP_KERNEL); @@ -8460,6 +8469,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba) UFS_DEV_HID_SUPPORT; =20 model_index =3D desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; + serial_index =3D desc_buf[DEVICE_DESC_PARAM_SN]; =20 err =3D ufshcd_read_string_desc(hba, model_index, &dev_info->model, SD_ASCII_STD); @@ -8469,6 +8479,12 @@ static int ufs_get_device_desc(struct ufs_hba *hba) goto out; } =20 + err =3D ufshcd_read_string_desc(hba, serial_index, &dev_info->serial_numb= er, SD_RAW); + if (err < 0) { + dev_err(hba->dev, "%s: Failed reading Serial Number. err =3D %d\n", __fu= nc__, err); + goto out; + } + hba->luns_avail =3D desc_buf[DEVICE_DESC_PARAM_NUM_LU] + desc_buf[DEVICE_DESC_PARAM_NUM_WLU]; =20 @@ -8504,6 +8520,8 @@ static void ufs_put_device_desc(struct ufs_hba *hba) =20 kfree(dev_info->model); dev_info->model =3D NULL; + kfree(dev_info->serial_number); + dev_info->serial_number =3D NULL; } =20 /** @@ -8647,6 +8665,8 @@ static int ufshcd_device_geo_params_init(struct ufs_h= ba *hba) else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] =3D=3D 0) hba->dev_info.max_lu_supported =3D 8; =20 + hba->dev_info.rpmb_io_size =3D desc_buf[GEOMETRY_DESC_PARAM_RPMB_RW_SIZE]; + out: kfree(desc_buf); return err; @@ -8832,6 +8852,7 @@ static int ufshcd_add_lus(struct ufs_hba *hba) =20 ufs_bsg_probe(hba); scsi_scan_host(hba->host); + ufs_rpmb_probe(hba); =20 out: return ret; @@ -10391,6 +10412,7 @@ void ufshcd_remove(struct ufs_hba *hba) ufshcd_rpm_get_sync(hba); ufs_hwmon_remove(hba); ufs_bsg_remove(hba); + ufs_rpmb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); cancel_delayed_work_sync(&hba->ufs_rtc_update_work); blk_mq_destroy_queue(hba->tmf_queue); diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 72fd385037a6..1d44e2b32253 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -651,6 +651,10 @@ struct ufs_dev_info { u8 rtt_cap; /* bDeviceRTTCap */ =20 bool hid_sup; + + u8 *serial_number; + u8 rpmb_io_size; + u8 rpmb_region_size[4]; }; =20 /* diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 1d3943777584..17e97a45ef71 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -984,6 +984,7 @@ struct ufs_hba { struct Scsi_Host *host; struct device *dev; struct scsi_device *ufs_device_wlun; + struct scsi_device *ufs_rpmb_wlun; =20 #ifdef CONFIG_SCSI_UFS_HWMON struct device *hwmon_device; @@ -1140,6 +1141,8 @@ struct ufs_hba { int critical_health_count; atomic_t dev_lvl_exception_count; u64 dev_lvl_exception_id; + + struct list_head rpmbs; }; =20 /** --=20 2.34.1