From nobody Fri Dec 19 08:56:18 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 6F7DE26E16F; Wed, 8 Oct 2025 20:19:59 +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=1759954804; cv=pass; b=dfEoQ1adqGaX97aUlJ+8GtBkmxIsRFiP0/IDR7L86blKeZZAnobaYRvFc8uuH9STYZz2GQk+NU5ZpiVTZTGL3m+y7nKDHVDnyy45gy1tPHHtgyv74Xb7sZeZ45jNJE0h8THj8Wj9MrR3bn/tzaowKb/2t7YxGJcKh51h++wVgyw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759954804; c=relaxed/simple; bh=Z/1u284kTILrbc3Vlj2F6kAI7Pm5I8KoorjxQhAoJN0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=iLRlvogU2Wqh8dsL3YdDU5QkNp9ZggiVyh1vZaF5/Y87MJo0At7X3RqEp7fXKO5CLSJtChzsF3GpcYJGAM5rCK3K18CjZA+ufDx6Ga9T2mmR2pdH8mqsifiXoY3Mx28pOBtcoO2suvtwxNhcHH4CaD/lb34NHbGnKL4EPP3yIK4= 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=H8QUiSeS; 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="H8QUiSeS" ARC-Seal: i=1; a=rsa-sha256; t=1759954796; cv=none; d=strato.com; s=strato-dkim-0002; b=Az23f7SyQaNjUKSe+GidudBLBrjildg7MnRWN5Fg3TNBatuDhgoL8CFrggygWGxUyb cOLwd8Q7uFORiW164fBtavYrS6+8v0qG9dkJL/UaTNV+G/hqJ4VBWQTYhamTQDUZ9zMY x5RP4jA5L5yTz/7FvcVkP0nbTpMv+1GcI4OZKEya4qceQh1QcmPBODWzZqfLxg4zeRE+ 6KuQNOH3YesfqQxLSdZYr8XyqhI3TTKk38KIKBnFkz0XwxOEzcK3yG8R7biYfVYEYFH+ EhIU0jiBUCeUoX7iRiW5Lg9jm60DssPnUxrRhEihicsopIUeZr6iEUsjWF2xTIM9V/Um +9yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759954796; 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=dr1R5XYu/hf+7l2A1TdMEHNZ80/JmT/u05H28rMJYYk=; b=iY9g4Mq12Et2QPixHgUYmzp4JpehzHsaCVQPESmDcKfAND8o0jZM1LKYbVH3dS6mdB ti5sdHMWVhhWV6dIbp7fGiOk10pGufPmAEU0xw2IIP5HoCRXpdVLB8b9qxv6Uh8TxUBc 0RXOhfxR68ZvhRCnTpr8G1KnCQxAmdH16Iu6s3qrAsyvv4c0AlTCvyMPz546FnznyVHW LQEQ/QQ76XQS2A76MeSqkjV+vwcPE/MXhhcxpcerz2dibXdClHWFv/JuvVWhT448OlHa sGbO4Db4AvKRzKGA3TigBf7pq8z8CRQEZmU+unRuDee5pqG0TZooAGU14xgr3DTiFcY+ Z4kw== 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=1759954796; 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=dr1R5XYu/hf+7l2A1TdMEHNZ80/JmT/u05H28rMJYYk=; b=H8QUiSeS50airEtHYcryRQMNT2h8B/O14Aih2kXADKc3SdiXQYOM4m4g3JWvLPyGJT dK2aBOoA+u++HnaAHl2lNe1N9PoLJSuM7J6CS5z/BhplBUPdto7s0lzZBgSibRHovNga 9bL2MDkCkWCDibtGMeyX96KbSjC+FwZo2X/AKeEgBn4G6OMIfgq2i7O9nnmHMHA+lAkq 2mt9o8s8wa1PxgzbkgeZ6TwToOfBMthe1r00Mh0YZEXiKJtHddTt35XjbTP6tziI4GN3 ql4wgHquZbWyXg8hXyJQaVmhDaOhfQ1FkNdw3yVo8vmruBh5Z88gMwjgajVy5X+KqUEb FO8w== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RX36IbE0bahBk7fQ77Y5cN0Av1YXTvXCMGxpd0=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 53.4.2 AUTH) with ESMTPSA id z293fb198KJu3U0 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 8 Oct 2025 22:19:56 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, avri.altman@sandisk.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, Avri Altman Subject: [PATCH v4 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Date: Wed, 8 Oct 2025 22:19:18 +0200 Message-Id: <20251008201920.89575-2-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251008201920.89575-1-beanhuo@iokpp.de> References: <20251008201920.89575-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 Convert SD_ASCII_STD and SD_RAW from boolean macros to enum values for impr= oved code readability. This makes ufshcd_read_string_desc() calls self-documenti= ng by using explicit enum values instead of true/false. Move the ufshcd_read_string_desc() declaration from include/ufs/ufshcd.h to drivers/ufs/core/ufshcd-priv.h since this function is not exported. Co-developed-by: Bart Van Assche Signed-off-by: Bart Van Assche Suggested-by: Avri Altman Signed-off-by: Bean Huo --- drivers/ufs/core/ufshcd-priv.h | 14 ++++++++++---- drivers/ufs/core/ufshcd.c | 8 +++----- include/ufs/ufshcd.h | 4 ---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index d0a2c963a27d..d74742a855b2 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -78,11 +78,17 @@ int ufshcd_try_to_abort_task(struct ufs_hba *hba, int t= ag); void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); =20 -#define SD_ASCII_STD true -#define SD_RAW false -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii); +/** + * enum ufs_descr_fmt - UFS string descriptor format + * @SD_RAW: Raw UTF-16 format + * @SD_ASCII_STD: Convert to null-terminated ASCII string + */ +enum ufs_descr_fmt { + SD_RAW =3D 0, + SD_ASCII_STD =3D 1, +}; =20 +int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, = enum ufs_descr_fmt fmt); int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd); int ufshcd_send_bsg_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_c= md); =20 diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2e1fa8cf83f5..773926b04149 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3759,16 +3759,14 @@ static inline char ufshcd_remove_non_printable(u8 c= h) * @desc_index: descriptor index * @buf: pointer to buffer where descriptor would be read, * the caller should free the memory. - * @ascii: if true convert from unicode to ascii characters - * null terminated string. + * @fmt: if %SD_ASCII_STD, convert from UTF-16 to ASCII * * Return: * * string size on success. * * -ENOMEM: on allocation failure * * -EINVAL: on a wrong parameter */ -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii) +int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, = enum ufs_descr_fmt fmt) { struct uc_string_id *uc_str; u8 *str; @@ -3797,7 +3795,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 d= esc_index, goto out; } =20 - if (ascii) { + if (fmt =3D=3D SD_ASCII_STD) { ssize_t ascii_len; int i; /* remove header and divide by 2 to move from UTF16 to UTF8 */ diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 1d3943777584..9ed188d24cb0 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -1453,10 +1453,6 @@ static inline int ufshcd_disable_host_tx_lcc(struct = ufs_hba *hba) void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, const struct ufs_dev_quirk *fixups); -#define SD_ASCII_STD true -#define SD_RAW false -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii); =20 void ufshcd_hold(struct ufs_hba *hba); void ufshcd_release(struct ufs_hba *hba); --=20 2.34.1 From nobody Fri Dec 19 08:56:18 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [81.169.146.171]) (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 314F02857E9; Wed, 8 Oct 2025 20:25:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=81.169.146.171 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759955160; cv=pass; b=Lbx0wEAG6nGvNBy+/6aqlTjSq17v/1dnn8MsBeJTgfzvAXKP2oZn91FlPWKQGD8PcbPJuJEPkV7Xv8s1EvLCZDWeYmHnAmi40BdriYUAI5BVXJHspLPOwzr0U3MJl+XiQhUgOb3Sc7squm9Xk7WdTEjQFXRKlZf4ErAc1dKgH7Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759955160; c=relaxed/simple; bh=UVFs6f1oWX0rO9WCMXjsc+ItaHwF8aGxJfXceJ0qVxM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=G+KKpf0h4EC+eGTigRepBsQcBlS2pGIJEkzojWftSPTl+Gq41n4fw37yxcgxkRy7DYdoW9Db089rCgsynkAQmzmAFyXdWIa5KjQnnF2B0pP9kmjSUI3NSCE7hJ4+cF5MBb9Ug8eVO40h+rJpC40Cmi60Ak/BeEIpaVfPAEtLy9M= 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=K9gW9MJE; arc=pass smtp.client-ip=81.169.146.171 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="K9gW9MJE" ARC-Seal: i=1; a=rsa-sha256; t=1759954797; cv=none; d=strato.com; s=strato-dkim-0002; b=VVyhI/knTnQcMOpg0NuH36yZ2+qTC/Cn5gGEd2JO35KxqZqTF+B1DZGWzC5e1gTGxa JTTS7rmQZSaVkiWVOqMOLl6zxVmz7/q1kY6dp3g532S8EjuLZW7aUvBLeavwkd4G/Af+ lmIYES38jRpi+rJNX9bcXjVOsOKt1jDifP3ca8latdiMDZkJWEllEqSKEMCPcx0twOyZ oSH80tsoTCvykg3T4a1spldGNibaiRSiFQwVrOfkgFO4wiS4Ipgq/w6ungRQgE5hRZJo tq0Yg/CqPahSVaXs5vvfHBhX4ASbzHyAFWYM+NiWKp4CsgGTaDFoDPDqnY7OuEcceGGp NWNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759954797; 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=/xSCu8VvynVNMYTUVx5cO9Gp/o/i91VTG9o19OZT4/M=; b=KX0duHOnUjDRehiddrmoTj2GVcdrHnQ3TpFs8E29gxOqIOyX/b9uR7bj8GOvdFLiqs Ecauw6K+qCDhqifm9y98XjV188H26KWY4iFBnmhbVEJ6mE3w6tyAsMQlD1S4oyY8EDdq LH5+PharSNLpkMc8iThaMVbnZw0Gvnp98ZJ0GtnAdXOgQVvnETuF93+l5Ow7icfitAep STGMkeMFbF9IfKKuakHNZ0HbUyTn0ngdNtoq4daEKC4SnWojdkz2bqu3VKB4fLunn1Nl krcAKN91P92sA+uqvnc2UXElmM1Y5OD5ASywPIpGdJ6Zles5qyMPSUEKhXlKJQeOa9O7 AAcA== 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=1759954797; 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=/xSCu8VvynVNMYTUVx5cO9Gp/o/i91VTG9o19OZT4/M=; b=K9gW9MJEDEezkC57a/ojY4Sktqjfm8Tw6smdyPg7q//kJU1n8QypaVIxBCxU5ruSkh PDT2KDrWIeDwkTJ3X4jeRtnXFjCCk9FtUTcirzWj7co+4N30XOAHiJaT3e3U0GsxZy6n vCuxfvMB+ntw8r4Z8Ve4+yDF6GoXVPkj1J5NN30PD4FcXB1+f05xcPAFO/fqsCbM32aj 0ISq9DalyzGvG/XPqmgXQ6EKHS4JPhYoF7g3QFeZzxyv1FbvIjTCeXMTUnN/vVJY+g3e mNRfbr4ALuSUFrxoJ5qWdjZW7GdqawYaCPkKFT3UoKe1+ZHtGi3szVnnV/KsLmxejIeo j8Ww== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RX36IbE0bahBk7fQ77Y5cN0Av1YXTvXCMGxpd0=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 53.4.2 AUTH) with ESMTPSA id z293fb198KJu3U1 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 8 Oct 2025 22:19:56 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, avri.altman@sandisk.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 v4 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Date: Wed, 8 Oct 2025 22:19:19 +0200 Message-Id: <20251008201920.89575-3-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251008201920.89575-1-beanhuo@iokpp.de> References: <20251008201920.89575-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()") Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo --- 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 773926b04149..d65169733a69 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3821,7 +3821,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 d= esc_index, u8 **buf, enum u 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 Fri Dec 19 08:56:18 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.83]) (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 A5E7227814C; Wed, 8 Oct 2025 20:23:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.83 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759954985; cv=pass; b=ghEsa8Krv7XE5oCNPNFOhrcXQ4mMc9wT9cckr1g7KBtcKDIC4wRIBdEKjsCB0V+1jA169z+8fcWzXvwV0UDwqFjNjGADJknfLjgx8IRIk85e5cuU8uwZpIP21Hac4DcY6ZRvTfzgzRVuWEg1E7GF/CRsgNR7uahzX3dcFNca4qc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759954985; c=relaxed/simple; bh=XLcoM4PeQYKUDK1STtSlax4qqRIwqkx5VQu6yBcaFac=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=PY9KXyfY/1RKbZXStypBXAJbx9LgI20EPS7WxM7PRQ6ZVnhyFsKhr+bEL2Qn1SsXDqfN9IITZTsCYGjZcG4PQ368oiuJlTc5P7wDP3/HGXBtbWXxDN++wyYwtQO//4ua8l6msZbmcZssT/68MKseyDKWssvGT4lcCKGOWgg3whU= 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=j0FLwOST; arc=pass smtp.client-ip=85.215.255.83 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="j0FLwOST" ARC-Seal: i=1; a=rsa-sha256; t=1759954797; cv=none; d=strato.com; s=strato-dkim-0002; b=LlWIxwtSWsmyeycSyhWYecNicA9O4QdNhvjHCyJnZ2ACqDKLFgiA6517ZsFKFc2MO7 bAT0Tn/+7YtnLghbizZGnv/MAz5aBjRSAWqNJ0KJ+uNFPWOmMA2iELPe3uE+ghAF7hHe x0MiwxnpXz5vMGAMYKNbUgVo4/u7CGcIdh4j124MBCnqgzTmgGvvONPHlp7t2c8ek6mA kXj4OvDUePlkb+9mqr2NrWK+oIR97fEwG25V/LP1tSlikS0gmO974mNFOUBjASQ7PbBg KYZwPjywmz6jDof5AWagSSPtYRTDxUGQSI0j+JQK1JCilOlW+pcLKWbD0TmPQDTemY7h r2TA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1759954797; 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=KquzWdNL6D04iJ+jzohSYesBw8aHdl23ulJD3/JAu0E=; b=Cpa7DHuWqeQfTZEcWvY8QzYTB0CkK5QTeUua3igWoF5VoF2KRLLMgkL+eUPmI+NHFC zi8AEdtMoVH00qPDJweQeaZgK4ruDQ7QjeK83nHqy/+KO9ExKOyjESLq9lAswq1XLAPf LNDKn6hmmn70rQfE1mY/sCOUi0jSVCZ0Y0CfeGL548NeR3lIoFs01mnvmpOK6RMHKj/Q NxFv7PUPxgFStcPqTeVCgDuprKX02gX7O+ygcUIIUgoOpfjR5Cro5Zs/6cFvOC51WeAk uVNCosFeNqU5NDxZPVyzf4iRMMeFcMu7e2iV5+uwYYjL8Czequv3pKdllpu2PViOZcqb jRaw== 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=1759954797; 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=KquzWdNL6D04iJ+jzohSYesBw8aHdl23ulJD3/JAu0E=; b=j0FLwOSTVIg/13wKIY/FYv1hKW25CUmWpFIrxrWwLgOm1/piPVhBTTD1Gqq4hB6GpO JlIo1VBqi0BzDcUHLOrDnPRZfqhipyLOyDG5aaZw/v404kJpZNyT3OlFHVDFcZm0oKQs NRkeFCg42/5LqRSsUjnn1rOcRBYufQaaOyzQAF/MKUZTVEYNJ8jAq0PAXECPFQVgsq58 vJvT2UujU2dCetVuy2jWHP0uDFp0BexSKHGMabmBfeqL1OU2M4wogbrYW/fabx1CVZIo dujNE7xsmQ4nH9z5m/v0NKJFsSIyOqKwIYvn55dWKLHzZ9ucd5EVh9U0uspQobXWM5zI TEwg== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RX36IbE0bahBk7fQ77Y5cN0Av1YXTvXCMGxpd0=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 53.4.2 AUTH) with ESMTPSA id z293fb198KJv3U2 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 8 Oct 2025 22:19:57 +0200 (CEST) From: Bean Huo To: avri.altman@wdc.com, avri.altman@sandisk.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 v4 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Date: Wed, 8 Oct 2025 22:19:20 +0200 Message-Id: <20251008201920.89575-4-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251008201920.89575-1-beanhuo@iokpp.de> References: <20251008201920.89575-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 Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo --- drivers/misc/Kconfig | 2 +- drivers/ufs/core/Makefile | 1 + drivers/ufs/core/ufs-rpmb.c | 249 +++++++++++++++++++++++++++++++++ drivers/ufs/core/ufshcd-priv.h | 13 ++ drivers/ufs/core/ufshcd.c | 30 +++- include/ufs/ufs.h | 4 + include/ufs/ufshcd.h | 8 +- 7 files changed, 300 insertions(+), 7 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..98cad0fa0290 --- /dev/null +++ b/drivers/ufs/core/ufs-rpmb.c @@ -0,0 +1,249 @@ +// 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; + } + + 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); + + 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 || hba->dev_info.b_advanced_rpmb_en) { + dev_info(hba->dev, "Skip OP-TEE 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); + + 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 < ARRAY_SIZE(hba->dev_info.rpmb_region_size); r= egion++) { + 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 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 UFS RPMB driver"); diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index d74742a855b2..e63b0e9075e0 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -417,4 +417,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 d65169733a69..3de284759a6a 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5238,10 +5238,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); @@ -8149,8 +8154,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 @@ -8423,6 +8431,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); @@ -8458,6 +8467,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); @@ -8467,6 +8477,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 @@ -8502,6 +8518,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 /** @@ -8645,6 +8663,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; @@ -8830,6 +8850,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; @@ -10389,6 +10410,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 9ed188d24cb0..5d04da9acb52 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -851,6 +851,7 @@ enum ufshcd_mcq_opr { * @host: Scsi_Host instance of the driver * @dev: device handle * @ufs_device_wlun: WLUN that controls the entire UFS device. + * @ufs_rpmb_wlun: RPMB WLUN SCSI device * @hwmon_device: device instance registered with the hwmon core. * @curr_dev_pwr_mode: active UFS device power mode. * @uic_link_state: active state of the link to the UFS device. @@ -965,8 +966,8 @@ enum ufshcd_mcq_opr { * @pm_qos_enabled: flag to check if pm qos is enabled * @critical_health_count: count of critical health exceptions * @dev_lvl_exception_count: count of device level exceptions since last r= eset - * @dev_lvl_exception_id: vendor specific information about the - * device level exception event. + * @dev_lvl_exception_id: vendor specific information about the device lev= el exception event. + * @rpmbs: list of OP-TEE RPMB devices (one per RPMB region) */ struct ufs_hba { void __iomem *mmio_base; @@ -984,6 +985,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 +1142,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