From patchwork Thu Dec 1 14:04:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061352 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 68A6BC43217 for ; Thu, 1 Dec 2022 14:05:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231739AbiLAOFD (ORCPT ); Thu, 1 Dec 2022 09:05:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231414AbiLAOE6 (ORCPT ); Thu, 1 Dec 2022 09:04:58 -0500 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.82]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B6F0A5191; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903489; 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=KMmrymso6RGjDkYBGOZ13Mhdy02M0I3meAzkE2PuEuM=; b=eUw3jwsqYSSgU0JEe5yxaePj+S26Z/3GnzyYzxmUbBGOLuS7/VlKBmm2s8I7Z+156x vd0wH0VpJ2qhtxBv7eD02ybZVz79URRL2qty/gCBDhYZikY8IOTH67qxisV+VYaK5PPi d9IwSvHV7frbfCi14jyEaahmNYVWcdzqcGzI7l+s7bEBXz9ptzZTRaLQ/PdqnsZOHVGH 9nTDLEAjLBxj2yYSwHwW/30993Gav+7Hlv+dR1ag8jat0bfr8ww4gPduQq0afdomqNB4 A1+5cKhrR74Gh7Qm7B8Cq0EAOKuISVTSsMEuDIc74uUvGwLVFB7IRv2Mu4RzgZqgxLQG VJXQ== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo01 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4mHoT (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:48 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/7] ufs: bsg: Let result in struct ufs_bsg_reply be signed int Date: Thu, 1 Dec 2022 15:04:31 +0100 Message-Id: <20221201140437.549272-2-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo According to the comments in struct ufs_bsg_reply and its usage, the result should be signed int, not __u32. Signed-off-by: Bean Huo --- include/uapi/scsi/scsi_bsg_ufs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/scsi/scsi_bsg_ufs.h b/include/uapi/scsi/scsi_bsg_ufs.h index d55f2176dfd4..64b0cb33e549 100644 --- a/include/uapi/scsi/scsi_bsg_ufs.h +++ b/include/uapi/scsi/scsi_bsg_ufs.h @@ -95,7 +95,7 @@ struct ufs_bsg_reply { * msg and status fields. The per-msgcode reply structure * will contain valid data. */ - __u32 result; + int result; /* If there was reply_payload, how much was received? */ __u32 reply_payload_rcv_len; From patchwork Thu Dec 1 14:04:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061353 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48B77C47088 for ; Thu, 1 Dec 2022 14:05:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231134AbiLAOFE (ORCPT ); Thu, 1 Dec 2022 09:05:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231477AbiLAOE6 (ORCPT ); Thu, 1 Dec 2022 09:04:58 -0500 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B534A518B; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903490; 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=WzbtD/v+UxSUhDVAuhWto551kuQVVfV/F7TNjn6BwCA=; b=DczqBO+k23KIiEJgvWf0/ttclkehINORRcRs1BZxKmaSLbGHNjBNW1E/FiQ7rXrtIq k4/QzoHzSMo+KRp2c51qQibPQ5LO/bHuN+Tfqtz7JJZBsfYD84jHh/AEGOYWvR4+BiZ9 gMYEbkyQI1DQ6nV+AvNJikVpmQVehYvgSm4MqLir/68paKigVn0qOBeoVzkxbR5Y1HWB CKzIah4B3OZ0MMdKia4MV1bXve/6RZkzgg2uOtNZC8iquEZCu3ISwqESazo+xR5kOtVC URl6eNGYNSqFTExQ30HjqQWUvqHqijUTWfWKa98yMOoiKTcrJnfzssz1b5PSXWJM2ipu SPAQ== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo02 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4nHoU (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:49 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/7] ufs: ufs_bsg: Remove unnecessary length checkup Date: Thu, 1 Dec 2022 15:04:32 +0100 Message-Id: <20221201140437.549272-3-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo Remove checks on job->request_len and job->reply_len because The following msgcode checks will rule out malicious requests. Signed-off-by: Bean Huo Acked-by: Avri Altman --- drivers/ufs/core/ufs_bsg.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c index b99e3f3dc4ef..9ac8204f1ee6 100644 --- a/drivers/ufs/core/ufs_bsg.c +++ b/drivers/ufs/core/ufs_bsg.c @@ -30,21 +30,6 @@ static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len, return 0; } -static int ufs_bsg_verify_query_size(struct ufs_hba *hba, - unsigned int request_len, - unsigned int reply_len) -{ - int min_req_len = sizeof(struct ufs_bsg_request); - int min_rsp_len = sizeof(struct ufs_bsg_reply); - - if (min_req_len > request_len || min_rsp_len > reply_len) { - dev_err(hba->dev, "not enough space assigned\n"); - return -EINVAL; - } - - return 0; -} - static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job, uint8_t **desc_buff, int *desc_len, enum query_opcode desc_op) @@ -88,8 +73,6 @@ static int ufs_bsg_request(struct bsg_job *job) struct ufs_bsg_request *bsg_request = job->request; struct ufs_bsg_reply *bsg_reply = job->reply; struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent)); - unsigned int req_len = job->request_len; - unsigned int reply_len = job->reply_len; struct uic_command uc = {}; int msgcode; uint8_t *desc_buff = NULL; @@ -97,10 +80,6 @@ static int ufs_bsg_request(struct bsg_job *job) enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP; int ret; - ret = ufs_bsg_verify_query_size(hba, req_len, reply_len); - if (ret) - goto out; - bsg_reply->reply_payload_rcv_len = 0; ufshcd_rpm_get_sync(hba); From patchwork Thu Dec 1 14:04:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061354 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01CB6C43217 for ; Thu, 1 Dec 2022 14:05:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231745AbiLAOFF (ORCPT ); Thu, 1 Dec 2022 09:05:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231432AbiLAOE6 (ORCPT ); Thu, 1 Dec 2022 09:04:58 -0500 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B57CA518F; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903490; 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=wcfxSKOuTbBkcUevcdbx3NdSEBMJ+Px6H+Sh6zzv4Yg=; b=slw7R3c1xLvlD7j6uBQooP6HrSurV0s5316sovCe31eS+Or1kewtoSa4CDWCQo3bvv IgscYiJz4iTAMV76vdQBgQrb8Re2WjYon+mSg3rBKAVmUvZZ6pmgAkQTVe76gDOr5oQE gA5YZx8IbWczQhoGkzoluDytfYeK74jQlNOnxnObJ+ab/vPGyeeGglAgfy1BodniJ8i/ C4KC6mWjuK7oK7G4OaHzCVoL3XGQMSfgpijQ7FmXQlWKf71rDse1YSeZuwL7agK+bQLF LKISshD/oa7KaiMv02BtZ2znB18W0yprIwO+QmKTrgEzyfJGDF7Pg6PyV/wL9oqaxLpW mhxg== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo02 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4oHoV (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:50 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/7] ufs: ufs_bsg: Cleanup ufs_bsg_request Date: Thu, 1 Dec 2022 15:04:33 +0100 Message-Id: <20221201140437.549272-4-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo Move sg_copy_from_buffer() below its associated case statement. Signed-off-by: Bean Huo Reviewed-by: Avri Altman --- drivers/ufs/core/ufs_bsg.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c index 9ac8204f1ee6..850a0d798f63 100644 --- a/drivers/ufs/core/ufs_bsg.c +++ b/drivers/ufs/core/ufs_bsg.c @@ -90,11 +90,8 @@ static int ufs_bsg_request(struct bsg_job *job) desc_op = bsg_request->upiu_req.qr.opcode; ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff, &desc_len, desc_op); - if (ret) { - ufshcd_rpm_put_sync(hba); + if (ret) goto out; - } - fallthrough; case UPIU_TRANSACTION_NOP_OUT: case UPIU_TRANSACTION_TASK_REQ: @@ -102,9 +99,12 @@ static int ufs_bsg_request(struct bsg_job *job) &bsg_reply->upiu_rsp, msgcode, desc_buff, &desc_len, desc_op); if (ret) - dev_err(hba->dev, - "exe raw upiu: error code %d\n", ret); - + dev_err(hba->dev, "exe raw upiu: error code %d\n", ret); + else if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) + bsg_reply->reply_payload_rcv_len = + sg_copy_from_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + desc_buff, desc_len); break; case UPIU_TRANSACTION_UIC_CMD: memcpy(&uc, &bsg_request->upiu_req.uc, UIC_CMD_SIZE); @@ -123,20 +123,9 @@ static int ufs_bsg_request(struct bsg_job *job) break; } +out: ufshcd_rpm_put_sync(hba); - - if (!desc_buff) - goto out; - - if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) - bsg_reply->reply_payload_rcv_len = - sg_copy_from_buffer(job->request_payload.sg_list, - job->request_payload.sg_cnt, - desc_buff, desc_len); - kfree(desc_buff); - -out: bsg_reply->result = ret; job->reply_len = sizeof(struct ufs_bsg_reply); /* complete the job here only if no error */ From patchwork Thu Dec 1 14:04:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061348 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D92B3C43217 for ; Thu, 1 Dec 2022 14:04:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231405AbiLAOE5 (ORCPT ); Thu, 1 Dec 2022 09:04:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230366AbiLAOE4 (ORCPT ); Thu, 1 Dec 2022 09:04:56 -0500 Received: from mo4-p03-ob.smtp.rzone.de (mo4-p03-ob.smtp.rzone.de [85.215.255.103]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3BAAC9C61B; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903491; 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=8eyKC2fgrN9qumLxJ3Hcsm6flrWlMQT35zpuY2GjhlA=; b=kTTGkmMue8mQ3qeF+gLkKNkSuf7cDNw2REOfX9/BSKmZCMVb/YzjYEnHmRUITcNJGZ C3+a0FQoDCn4+qqQ6G6DRbign8gK8kY5+zDx3LEdecGOUQ2FvKu0kKGq/uR2SgZ0U4vz kJrUy11HdTUSZe7y9cyU1djlxbE5X6igsb0Eaeppnx1Q5cH8aIf5KJ6NiEODdm/wd7LI 36C6N8TPwWpHDhVriEQIH4gZ49sHCjTdqvz1N9qqMa3IVVKc+yjInbYhCrC0FdeZQCMS P0EwNJAF6FfeG3s6/9YFzN7tZO1d3cN2IybGVgzzDS+LDEDCZOuFg5Wz0ccvrH2K0F80 3/iw== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo02 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4pHoW (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:51 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/7] ufs: core: Split ufshcd_map_sg Date: Thu, 1 Dec 2022 15:04:34 +0100 Message-Id: <20221201140437.549272-5-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo Take out the "map scatter-gather list to prdt" part of the code in ufshcd_map_sg and split it into a new function ufshcd_sgl_to_prdt. Signed-off-by: Bean Huo Reviewed-by: Avri Altman --- drivers/ufs/core/ufshcd.c | 48 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2dbe24977822..d1bcb4c4e4e4 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2399,38 +2399,30 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) } /** - * ufshcd_map_sg - Map scatter-gather list to prdt - * @hba: per adapter instance - * @lrbp: pointer to local reference block - * - * Returns 0 in case of success, non-zero value in case of failure + * ufshcd_sgl_to_prdt - SG list to PRTD (Physical Region Description Table, 4DW format) + * @hba: per-adapter instance + * @lrbp: pointer to local reference block + * @sg_entries: The number of sg lists actually used + * @sg_list: Pointer to SG list */ -static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +static void ufshcd_sgl_to_prdt(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, int sg_entries, + struct scatterlist *sg_list) { struct ufshcd_sg_entry *prd_table; struct scatterlist *sg; - struct scsi_cmnd *cmd; - int sg_segments; int i; - cmd = lrbp->cmd; - sg_segments = scsi_dma_map(cmd); - if (sg_segments < 0) - return sg_segments; - - if (sg_segments) { + if (sg_entries) { if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) lrbp->utr_descriptor_ptr->prd_table_length = - cpu_to_le16((sg_segments * - sizeof(struct ufshcd_sg_entry))); + cpu_to_le16((sg_entries * sizeof(struct ufshcd_sg_entry))); else - lrbp->utr_descriptor_ptr->prd_table_length = - cpu_to_le16(sg_segments); + lrbp->utr_descriptor_ptr->prd_table_length = cpu_to_le16(sg_entries); prd_table = lrbp->ucd_prdt_ptr; - scsi_for_each_sg(cmd, sg, sg_segments, i) { + for_each_sg(sg_list, sg, sg_entries, i) { const unsigned int len = sg_dma_len(sg); /* @@ -2449,6 +2441,24 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } else { lrbp->utr_descriptor_ptr->prd_table_length = 0; } +} + +/** + * ufshcd_map_sg - Map scatter-gather list to prdt + * @hba: per adapter instance + * @lrbp: pointer to local reference block + * + * Returns 0 in case of success, non-zero value in case of failure + */ +static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct scsi_cmnd *cmd = lrbp->cmd; + int sg_segments = scsi_dma_map(cmd); + + if (sg_segments < 0) + return sg_segments; + + ufshcd_sgl_to_prdt(hba, lrbp, sg_segments, scsi_sglist(cmd)); return 0; } From patchwork Thu Dec 1 14:04:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061351 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 859FEC4708D for ; Thu, 1 Dec 2022 14:05:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231734AbiLAOFB (ORCPT ); Thu, 1 Dec 2022 09:05:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231411AbiLAOE6 (ORCPT ); Thu, 1 Dec 2022 09:04:58 -0500 Received: from mo4-p03-ob.smtp.rzone.de (mo4-p03-ob.smtp.rzone.de [81.169.146.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F21EA5184; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903492; 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=c/FJw1eQjtrDqv72K4MlGdG6wEsHIdThMCAbiYaGxDU=; b=kREa1XxoNJ1LJ3ewyuLoUkQTmSeZlo/x3RF3D+z+28Da5UFbDnVwETEVXMIIZYeVbF KaFeFwAcWP4fC9zUFbuzwLyKah5VwFKdVPDJc6cnlKHQC3vAsIl3PkYqvYzYheRzBxeJ jeu1PP1QuYXfdjl5fl/PWgSuFjl+RD/PsCpND/0ZqXCfvm/SXwMDjrv+LVPJkTsMBQah QwRDfhkldEwwo2PFyU5KUAagpVlDNQW5UT3WE5v/6xkK65Bz7o2VfW8a/vPRrw5nG81i pLVL+OJ51KxVRCIa3vykz/9zEjKXksqyCqW476+6YPjxvn4AYRzmOX2rTg0Gdmf1vGK2 pkiA== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo03 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4pHoX (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:51 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/7] ufs: core: Advanced RPMB detection Date: Thu, 1 Dec 2022 15:04:35 +0100 Message-Id: <20221201140437.549272-6-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo Check UFS Advanced RPMB LU enablement during ufshcd_lu_init(). Signed-off-by: Bean Huo --- drivers/ufs/core/ufshcd.c | 6 ++++++ include/ufs/ufs.h | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index d1bcb4c4e4e4..641fed6dae5d 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -4954,6 +4954,12 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev) desc_buf[UNIT_DESC_PARAM_LU_WR_PROTECT] == UFS_LU_POWER_ON_WP) hba->dev_info.is_lu_power_on_wp = true; + /* In case of RPMB LU, check if advanced RPMB mode is enabled */ + if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] == UFS_UPIU_RPMB_WLUN && + desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4)) + hba->dev_info.b_advanced_rpmb_en = true; + + kfree(desc_buf); set_qdepth: /* diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 1bba3fead2ce..17e401df674c 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -212,6 +212,28 @@ enum unit_desc_param { UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29, }; +/* RPMB Unit descriptor parameters offsets in bytes*/ +enum rpmb_unit_desc_param { + RPMB_UNIT_DESC_PARAM_LEN = 0x0, + RPMB_UNIT_DESC_PARAM_TYPE = 0x1, + RPMB_UNIT_DESC_PARAM_UNIT_INDEX = 0x2, + RPMB_UNIT_DESC_PARAM_LU_ENABLE = 0x3, + RPMB_UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4, + RPMB_UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5, + RPMB_UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6, + RPMB_UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7, + RPMB_UNIT_DESC_PARAM_MEM_TYPE = 0x8, + RPMB_UNIT_DESC_PARAM_REGION_EN = 0x9, + RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA, + RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB, + RPMB_UNIT_DESC_PARAM_REGION0_SIZE = 0x13, + RPMB_UNIT_DESC_PARAM_REGION1_SIZE = 0x14, + RPMB_UNIT_DESC_PARAM_REGION2_SIZE = 0x15, + RPMB_UNIT_DESC_PARAM_REGION3_SIZE = 0x16, + RPMB_UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17, + RPMB_UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18, +}; + /* Device descriptor parameters offsets in bytes*/ enum device_desc_param { DEVICE_DESC_PARAM_LEN = 0x0, @@ -601,6 +623,8 @@ struct ufs_dev_info { bool b_rpm_dev_flush_capable; u8 b_presrv_uspc_en; + + bool b_advanced_rpmb_en; }; /* From patchwork Thu Dec 1 14:04:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061350 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C255C43217 for ; Thu, 1 Dec 2022 14:05:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231730AbiLAOE7 (ORCPT ); Thu, 1 Dec 2022 09:04:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231374AbiLAOE5 (ORCPT ); Thu, 1 Dec 2022 09:04:57 -0500 Received: from mo4-p03-ob.smtp.rzone.de (mo4-p03-ob.smtp.rzone.de [85.215.255.100]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23EA6A5192; Thu, 1 Dec 2022 06:04:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903493; 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=MIzn1NcSJedwLjPhIjJCpsTHdO40SqaloeB8f4zW50I=; b=KwRpCEUPNqIcOJUdwLuXGFhhWoA0PsnsV5J99AUGJYsQ8LaLhNVaXr5wca++qBn+M9 IkjHZlvcqvEzElpraUWbftaJ0cOniI8wRIbnzwf4kp/GAvRTxCgfcWn9yscxAUSaGU9d nwi7K7m84CTBWDfYjP052xuZlRA7fxWn9imb7uEIAIHSi5ndBHcWZMXydz1qpOoraZEz 10cBbJYJKa8fYzFjlX3Bj2QTINrRigvDbEKpwx8t/pHPaeFuhxNogRvvh2CcMUcOOwyT SM5FCEL6mYo+QvoUePuudHOIrTKKGqwxsBVA0l1SINpGQrHB8j08tPb1EJbNA25uq0DF BfWA== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo03 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4qHoZ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:52 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/7] ufs: core: Pass EHS length into ufshcd_prepare_req_desc_hdr() Date: Thu, 1 Dec 2022 15:04:36 +0100 Message-Id: <20221201140437.549272-7-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo We need to fill in the total EHS length in UTP Transfer Request Descriptor, add this functionality to ufshcd_prepare_req_desc_hdr(). Signed-off-by: Bean Huo Reviewed-by: Avri Altman --- drivers/ufs/core/ufshcd.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 641fed6dae5d..bacc94f87ee2 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2506,14 +2506,15 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) } /** - * ufshcd_prepare_req_desc_hdr() - Fills the requests header + * ufshcd_prepare_req_desc_hdr - Fill UTP Transfer request descriptor header according to request * descriptor according to request * @lrbp: pointer to local reference block * @upiu_flags: flags required in the header * @cmd_dir: requests data direction + * @ehs_length: Total EHS Length (in 32‐bytes units of all Extra Header Segments) */ -static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, - u8 *upiu_flags, enum dma_data_direction cmd_dir) +static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, u8 *upiu_flags, + enum dma_data_direction cmd_dir, int ehs_length) { struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr; u32 data_direction; @@ -2532,8 +2533,8 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, *upiu_flags = UPIU_CMD_FLAGS_NONE; } - dword_0 = data_direction | (lrbp->command_type - << UPIU_COMMAND_TYPE_OFFSET); + dword_0 = data_direction | (lrbp->command_type << UPIU_COMMAND_TYPE_OFFSET) | + ehs_length << 8; if (lrbp->intr_cmd) dword_0 |= UTP_REQ_DESC_INT_CMD; @@ -2588,8 +2589,7 @@ void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u8 upiu_flags) } /** - * ufshcd_prepare_utp_query_req_upiu() - fills the utp_transfer_req_desc, - * for query requsts + * ufshcd_prepare_utp_query_req_upiu() - fill the utp_transfer_req_desc for query request * @hba: UFS hba * @lrbp: local reference block pointer * @upiu_flags: flags @@ -2660,7 +2660,7 @@ static int ufshcd_compose_devman_upiu(struct ufs_hba *hba, else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; - ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE, 0); if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY) ufshcd_prepare_utp_query_req_upiu(hba, lrbp, upiu_flags); else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP) @@ -2688,8 +2688,7 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; if (likely(lrbp->cmd)) { - ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, - lrbp->cmd->sc_data_direction); + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, lrbp->cmd->sc_data_direction, 0); ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags); } else { ret = -EINVAL; @@ -6884,7 +6883,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, /* update the task tag in the request upiu */ req_upiu->header.dword_0 |= cpu_to_be32(tag); - ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE, 0); /* just copy the upiu request as it is */ memcpy(lrbp->ucd_req_ptr, req_upiu, sizeof(*lrbp->ucd_req_ptr)); From patchwork Thu Dec 1 14:04:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bean Huo X-Patchwork-Id: 13061355 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE019C47088 for ; Thu, 1 Dec 2022 14:05:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231749AbiLAOFG (ORCPT ); Thu, 1 Dec 2022 09:05:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231532AbiLAOE6 (ORCPT ); Thu, 1 Dec 2022 09:04:58 -0500 Received: from mo4-p03-ob.smtp.rzone.de (mo4-p03-ob.smtp.rzone.de [85.215.255.104]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9675AA5193; Thu, 1 Dec 2022 06:04:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1669903493; 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=2nRu0P8NbWQ922VMs3rl370fEKxsdqVp5TVrGfVLkEU=; b=hBcBgRf5ricEvQbkp3SdR3MeaW5NX11qXxx3lj3JSMjsPHPBE4tj0J9EYy8SqrHuTa 3tVcIDng6W8OOsEHOJKqUcmU1LQnM5wGn5mfm5zO0T0WLK/ld+iPFohrQUxov9h0oAFZ bZr7x+3ONyC24GzhsAj5hDKrnSsUu2P4Cvb7V+L/LV/xFNZX26kzk02ahxuks0hsFTpy 1PPzGN9D4CzROQ0z00LnoPCTdMACDTVDbtXE8sgPH3kegF/QEWaS7DSyodl4FLnh4QYX vZ+/22q1B8iaB4JsRT/IbQO5rZ6faUtQq1BIh/DnMKTsNS5oQMDKe491lesrlK/kBsgm ZSOQ== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSedrgBzPc9DUyubU4DD2QzemV2tdlNlNRZBXiUw=" X-RZG-CLASS-ID: mo03 Received: from blinux.micron.com by smtp.strato.de (RZmta 48.2.1 AUTH) with ESMTPSA id z9cfbfyB1E4rHob (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 1 Dec 2022 15:04:53 +0100 (CET) From: Bean Huo To: alim.akhtar@samsung.com, avri.altman@wdc.com, jejb@linux.ibm.com, martin.petersen@oracle.com, stanley.chu@mediatek.com, beanhuo@micron.com, bvanassche@acm.org, tomas.winkler@intel.com, daejun7.park@samsung.com, quic_cang@quicinc.com, quic_nguyenb@quicinc.com, quic_xiaosenh@quicinc.com, quic_richardp@quicinc.com, quic_asutoshd@quicinc.com, hare@suse.de Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 7/7] ufs: core: Add advanced RPMB support in ufs_bsg Date: Thu, 1 Dec 2022 15:04:37 +0100 Message-Id: <20221201140437.549272-8-beanhuo@iokpp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221201140437.549272-1-beanhuo@iokpp.de> References: <20221201140437.549272-1-beanhuo@iokpp.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Bean Huo Add advanced RPMB support in ufs_bsg. For these reasons, we try to add Advanced RPMB support in ufs_bsg: 1. According to the UFS specification, only one RPMB operation can be performed at any time. We can ensure this by using reserved slot and its dev_cmd sync operation protection mechanism. 2. For the Advanced RPMB, RPMB metadata is packaged in an EHS(Extra Header Segment) of a command UPIU, and the corresponding reply EHS (from the device) should also be returned to the user space. bsg_job->request and bsg_job->reply allow us to pass and return EHS from/back to userspace. Compared to normal/legacy RPMB, the advantage of advanced RPMB are: 1. The data length in the Advanced RPBM data read/write command could be > 4KB. For the legacy RPMB, the data length in a single RPMB data transfer is 256 bytes. 2. All of the advanced RPMB operations will be a single command shot. But for the legacy RPBM, take the read write-counter value as an example, you need two commands(first SECURITY PROTOCOL OUT, then the second SECURITY PROTOCOL IN). Signed-off-by: Bean Huo Reviewed-by: Avri Altman --- drivers/ufs/core/ufs_bsg.c | 93 +++++++++++++++++++++++++--- drivers/ufs/core/ufshcd.c | 103 +++++++++++++++++++++++++++++++ include/uapi/scsi/scsi_bsg_ufs.h | 46 +++++++++++++- include/ufs/ufs.h | 5 ++ include/ufs/ufshcd.h | 6 +- include/ufs/ufshci.h | 1 + 6 files changed, 242 insertions(+), 12 deletions(-) diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c index 850a0d798f63..a8e58faa7da2 100644 --- a/drivers/ufs/core/ufs_bsg.c +++ b/drivers/ufs/core/ufs_bsg.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include "ufs_bsg.h" @@ -68,6 +69,72 @@ static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job, return 0; } +static int ufs_bsg_exec_advanced_rpmb_req(struct ufs_hba *hba, struct bsg_job *job) +{ + struct ufs_rpmb_request *rpmb_request = job->request; + struct ufs_rpmb_reply *rpmb_reply = job->reply; + struct bsg_buffer *payload = NULL; + enum dma_data_direction dir; + struct scatterlist *sg_list; + int rpmb_req_type; + int sg_cnt; + int ret; + int data_len; + + if (hba->ufs_version < ufshci_version(4, 0) || !hba->dev_info.b_advanced_rpmb_en || + !(hba->capabilities & MASK_EHSLUTRD_SUPPORTED)) + return -EINVAL; + + if (rpmb_request->ehs_req.length != 2 || rpmb_request->ehs_req.ehs_type != 1) + return -EINVAL; + + rpmb_req_type = be16_to_cpu(rpmb_request->ehs_req.meta.req_resp_type); + + switch (rpmb_req_type) { + case UFS_RPMB_WRITE_KEY: + case UFS_RPMB_READ_CNT: + case UFS_RPMB_PURGE_ENABLE: + dir = DMA_NONE; + break; + case UFS_RPMB_WRITE: + case UFS_RPMB_SEC_CONF_WRITE: + dir = DMA_TO_DEVICE; + break; + case UFS_RPMB_READ: + case UFS_RPMB_SEC_CONF_READ: + case UFS_RPMB_PURGE_STATUS_READ: + dir = DMA_FROM_DEVICE; + break; + default: + return -EINVAL; + } + + if (dir != DMA_NONE) { + payload = &job->request_payload; + if (!payload || !payload->payload_len || !payload->sg_cnt) + return -EINVAL; + + sg_cnt = dma_map_sg(hba->host->dma_dev, payload->sg_list, payload->sg_cnt, dir); + if (unlikely(!sg_cnt)) + return -ENOMEM; + sg_list = payload->sg_list; + data_len = payload->payload_len; + } + + ret = ufshcd_advanced_rpmb_req_handler(hba, &rpmb_request->bsg_request.upiu_req, + &rpmb_reply->bsg_reply.upiu_rsp, &rpmb_request->ehs_req, + &rpmb_reply->ehs_rsp, sg_cnt, sg_list, dir); + + if (dir != DMA_NONE) { + dma_unmap_sg(hba->host->dma_dev, payload->sg_list, payload->sg_cnt, dir); + + if (!ret) + rpmb_reply->bsg_reply.reply_payload_rcv_len = data_len; + } + + return ret; +} + static int ufs_bsg_request(struct bsg_job *job) { struct ufs_bsg_request *bsg_request = job->request; @@ -75,10 +142,11 @@ static int ufs_bsg_request(struct bsg_job *job) struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent)); struct uic_command uc = {}; int msgcode; - uint8_t *desc_buff = NULL; + uint8_t *buff = NULL; int desc_len = 0; enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP; int ret; + bool rpmb = false; bsg_reply->reply_payload_rcv_len = 0; @@ -88,8 +156,7 @@ static int ufs_bsg_request(struct bsg_job *job) switch (msgcode) { case UPIU_TRANSACTION_QUERY_REQ: desc_op = bsg_request->upiu_req.qr.opcode; - ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff, - &desc_len, desc_op); + ret = ufs_bsg_alloc_desc_buffer(hba, job, &buff, &desc_len, desc_op); if (ret) goto out; fallthrough; @@ -97,25 +164,31 @@ static int ufs_bsg_request(struct bsg_job *job) case UPIU_TRANSACTION_TASK_REQ: ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req, &bsg_reply->upiu_rsp, msgcode, - desc_buff, &desc_len, desc_op); + buff, &desc_len, desc_op); if (ret) dev_err(hba->dev, "exe raw upiu: error code %d\n", ret); - else if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) + else if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) { bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(job->request_payload.sg_list, job->request_payload.sg_cnt, - desc_buff, desc_len); + buff, desc_len); + } break; case UPIU_TRANSACTION_UIC_CMD: memcpy(&uc, &bsg_request->upiu_req.uc, UIC_CMD_SIZE); ret = ufshcd_send_uic_cmd(hba, &uc); if (ret) - dev_err(hba->dev, - "send uic cmd: error code %d\n", ret); + dev_err(hba->dev, "send uic cmd: error code %d\n", ret); memcpy(&bsg_reply->upiu_rsp.uc, &uc, UIC_CMD_SIZE); break; + case UPIU_TRANSACTION_ARPMB_CMD: + rpmb = true; + ret = ufs_bsg_exec_advanced_rpmb_req(hba, job); + if (ret) + dev_err(hba->dev, "ARPMB OP failed: error code %d\n", ret); + break; default: ret = -ENOTSUPP; dev_err(hba->dev, "unsupported msgcode 0x%x\n", msgcode); @@ -125,9 +198,9 @@ static int ufs_bsg_request(struct bsg_job *job) out: ufshcd_rpm_put_sync(hba); - kfree(desc_buff); + kfree(buff); bsg_reply->result = ret; - job->reply_len = sizeof(struct ufs_bsg_reply); + job->reply_len = !rpmb ? sizeof(struct ufs_bsg_reply) : sizeof(struct ufs_rpmb_reply); /* complete the job here only if no error */ if (ret == 0) bsg_job_done(job, ret, bsg_reply->reply_payload_rcv_len); diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index bacc94f87ee2..1ecee6507e88 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -56,6 +56,9 @@ /* Query request timeout */ #define QUERY_REQ_TIMEOUT 1500 /* 1.5 seconds */ +/* Advanced RPMB request timeout */ +#define ADVANCED_RPMB_REQ_TIMEOUT 3000 /* 3 seconds */ + /* Task management command timeout */ #define TM_CMD_TIMEOUT 100 /* msecs */ @@ -2954,6 +2957,12 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) dev_err(hba->dev, "%s: Reject UPIU not fully implemented\n", __func__); break; + case UPIU_TRANSACTION_RESPONSE: + if (hba->dev_cmd.type != DEV_CMD_TYPE_RPMB) { + err = -EINVAL; + dev_err(hba->dev, "%s: unexpected response %x\n", __func__, resp); + } + break; default: err = -EINVAL; dev_err(hba->dev, "%s: Invalid device management cmd response: %x\n", @@ -7006,6 +7015,100 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, return err; } +/** + * ufshcd_advanced_rpmb_req_handler - handle advanced RPMB request + * @hba: per adapter instance + * @req_upiu: upiu request + * @rsp_upiu: upiu reply + * @req_ehs: EHS field which contains Advanced RPMB Request Message + * @rsp_ehs: EHS field which returns Advanced RPMB Response Message + * @sg_cnt: The number of sg lists actually used + * @sg_list: Pointer to SG list when DATA IN/OUT UPIU is required in ARPMB operation + * @dir: DMA direction + * + * Returns zero on success, non-zero on failure + */ +int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *req_upiu, + struct utp_upiu_req *rsp_upiu, struct ufs_ehs *req_ehs, + struct ufs_ehs *rsp_ehs, int sg_cnt, struct scatterlist *sg_list, + enum dma_data_direction dir) +{ + DECLARE_COMPLETION_ONSTACK(wait); + const u32 tag = hba->reserved_slot; + struct ufshcd_lrb *lrbp; + int err = 0; + int result; + u8 upiu_flags; + u8 *ehs_data; + u16 ehs_len; + + /* Protects use of hba->reserved_slot. */ + ufshcd_hold(hba, false); + mutex_lock(&hba->dev_cmd.lock); + down_read(&hba->clk_scaling_lock); + + lrbp = &hba->lrb[tag]; + WARN_ON(lrbp->cmd); + lrbp->cmd = NULL; + lrbp->task_tag = tag; + lrbp->lun = UFS_UPIU_RPMB_WLUN; + + lrbp->intr_cmd = true; + ufshcd_prepare_lrbp_crypto(NULL, lrbp); + hba->dev_cmd.type = DEV_CMD_TYPE_RPMB; + + /* Advanced RPMB starts from UFS 4.0, so its command type is UTP_CMD_TYPE_UFS_STORAGE */ + lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; + + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 2); + + /* update the task tag and LUN in the request upiu */ + req_upiu->header.dword_0 |= cpu_to_be32(upiu_flags << 16 | UFS_UPIU_RPMB_WLUN << 8 | tag); + + /* copy the UPIU(contains CDB) request as it is */ + memcpy(lrbp->ucd_req_ptr, req_upiu, sizeof(*lrbp->ucd_req_ptr)); + /* Copy EHS, starting with byte32, immediately after the CDB package */ + memcpy(lrbp->ucd_req_ptr + 1, req_ehs, sizeof(*req_ehs)); + + if (dir != DMA_NONE && sg_list) + ufshcd_sgl_to_prdt(hba, lrbp, sg_cnt, sg_list); + + memset(lrbp->ucd_rsp_ptr, 0, sizeof(struct utp_upiu_rsp)); + + hba->dev_cmd.complete = &wait; + + ufshcd_send_command(hba, tag); + + err = ufshcd_wait_for_dev_cmd(hba, lrbp, ADVANCED_RPMB_REQ_TIMEOUT); + + if (!err) { + /* Just copy the upiu response as it is */ + memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu)); + /* Get the response UPIU result */ + result = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr); + + ehs_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) >> 24; + /* + * Since the bLength in EHS indicates the total size of the EHS Header and EHS Data + * in 32 Byte units, the value of the bLength Request/Response for Advanced RPMB + * Message is 02h + */ + if (ehs_len == 2 && rsp_ehs) { + /* + * ucd_rsp_ptr points to a buffer with a length of 512 bytes + * (ALIGNED_UPIU_SIZE = 512), and the EHS data just starts from byte32 + */ + ehs_data = (u8 *)lrbp->ucd_rsp_ptr + EHS_OFFSET_IN_RESPONSE; + memcpy(rsp_ehs, ehs_data, ehs_len * 32); + } + } + + up_read(&hba->clk_scaling_lock); + mutex_unlock(&hba->dev_cmd.lock); + ufshcd_release(hba); + return err ? : result; +} + /** * ufshcd_eh_device_reset_handler() - Reset a single logical unit. * @cmd: SCSI command pointer diff --git a/include/uapi/scsi/scsi_bsg_ufs.h b/include/uapi/scsi/scsi_bsg_ufs.h index 64b0cb33e549..276e2772328f 100644 --- a/include/uapi/scsi/scsi_bsg_ufs.h +++ b/include/uapi/scsi/scsi_bsg_ufs.h @@ -14,10 +14,27 @@ */ #define UFS_CDB_SIZE 16 -#define UPIU_TRANSACTION_UIC_CMD 0x1F /* uic commands are 4DW long, per UFSHCI V2.1 paragraph 5.6.1 */ #define UIC_CMD_SIZE (sizeof(__u32) * 4) +enum ufs_bsg_msg_code { + UPIU_TRANSACTION_UIC_CMD = 0x1F, + UPIU_TRANSACTION_ARPMB_CMD, +}; + +/* UFS RPMB Request Message Types */ +enum ufs_rpmb_op_type { + UFS_RPMB_WRITE_KEY = 0x01, + UFS_RPMB_READ_CNT = 0x02, + UFS_RPMB_WRITE = 0x03, + UFS_RPMB_READ = 0x04, + UFS_RPMB_READ_RESP = 0x05, + UFS_RPMB_SEC_CONF_WRITE = 0x06, + UFS_RPMB_SEC_CONF_READ = 0x07, + UFS_RPMB_PURGE_ENABLE = 0x08, + UFS_RPMB_PURGE_STATUS_READ = 0x09, +}; + /** * struct utp_upiu_header - UPIU header structure * @dword_0: UPIU header DW-0 @@ -79,6 +96,23 @@ struct utp_upiu_req { }; }; +struct ufs_arpmb_meta { + __u16 req_resp_type; + __u8 nonce[16]; + __u32 write_counter; + __u16 addr_lun; + __u16 block_count; + __u16 result; +} __attribute__((__packed__)); + +struct ufs_ehs { + __u8 length; + __u8 ehs_type; + __u16 ehssub_type; + struct ufs_arpmb_meta meta; + __u8 mac_key[32]; +} __attribute__((__packed__)); + /* request (CDB) structure of the sg_io_v4 */ struct ufs_bsg_request { __u32 msgcode; @@ -102,4 +136,14 @@ struct ufs_bsg_reply { struct utp_upiu_req upiu_rsp; }; + +struct ufs_rpmb_request { + struct ufs_bsg_request bsg_request; + struct ufs_ehs ehs_req; +}; + +struct ufs_rpmb_reply { + struct ufs_bsg_reply bsg_reply; + struct ufs_ehs ehs_rsp; +}; #endif /* UFS_BSG_H */ diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 17e401df674c..0c112195b288 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -49,6 +49,11 @@ */ #define UFS_WB_EXCEED_LIFETIME 0x0B +/* + * In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU request/response packet + */ +#define EHS_OFFSET_IN_RESPONSE 32 + /* Well known logical unit id in LUN field of UPIU */ enum { UFS_UPIU_REPORT_LUNS_WLUN = 0x81, diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 5cf81dff60aa..c3dfa8084b5c 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -30,6 +30,7 @@ struct ufs_hba; enum dev_cmd_type { DEV_CMD_TYPE_NOP = 0x0, DEV_CMD_TYPE_QUERY = 0x1, + DEV_CMD_TYPE_RPMB = 0x2, }; enum ufs_event_type { @@ -1201,7 +1202,10 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, int msgcode, u8 *desc_buff, int *buff_len, enum query_opcode desc_op); - +int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *req_upiu, + struct utp_upiu_req *rsp_upiu, struct ufs_ehs *ehs_req, + struct ufs_ehs *ehs_rsp, int sg_cnt, + struct scatterlist *sg_list, enum dma_data_direction dir); int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable); int ufshcd_suspend_prepare(struct device *dev); diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h index f525566a0864..af216296b86e 100644 --- a/include/ufs/ufshci.h +++ b/include/ufs/ufshci.h @@ -63,6 +63,7 @@ enum { enum { MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, + MASK_EHSLUTRD_SUPPORTED = 0x00400000, MASK_AUTO_HIBERN8_SUPPORT = 0x00800000, MASK_64_ADDRESSING_SUPPORT = 0x01000000, MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000,