From nobody Sun Sep 27 00:36:54 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 2F799488224 for ; Thu, 27 Aug 2026 16:08:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846908; cv=none; b=gIGFYzgJmLwLz7zV0Jy+Rhz2+sFikRYqxGhVTjZxyjmXCh85PHVFCCkDkJeu+GHGd15DgB/dy9HvtW+IiIpPUl8/SKK60p8FsD3gG0mJpUyYBVpsSIyOiisDi/LyV6SPtBOsPZJkLR3bIZcdvzA5UMJa21pCzuzhdMCj0WH1Y5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846908; c=relaxed/simple; bh=IIdZmC/LM00PwR5KHA2xpiIqG5UVbMYS/zEiNRNREio=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H42gfU91nQuZOmu25XmOJbJEVhb3GwIUlhjtt7wT7/LhxkiIyKIumd1i9far8hCdCCqBBDeWe+eld7S/V+70AuCpUjBjDSi8+Ct74zv+kuoGuSK3HHWKEdVk4ZnkxJlfPq/3qo+K6yuXWILb8i08WDtyou0bSB0taYAucMk8DCQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=No9Edywy; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=LC/7sY10; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="No9Edywy"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="LC/7sY10" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFcRNF3360395 for ; Thu, 27 Aug 2026 16:08:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=zlZEuku42ul qNc3ih1pFp1rs3evdduqZIg1SlzbXZv8=; b=No9EdywyxhYBjMK0CreG/ee8B20 +Ze1t6Vts55zTISy/vNkJQ725lDNjnj9PKSG6bJcPgYkTxoBckGgIx+Gf4gvvr40 6x4Pi4/yEqMcLJNU8hX6Vz+8r0xjF+BwtOZBTc8LzJOKviFZB4yTPuhkrEXBLhm1 nWBNCuKRPcMe/lOS/MCc4wpI7NM84tSVJFLhCPBSJ1iFH9NdwmW9vs0v5DHBhPe3 Dy6w7iCtPDDICBN/vmdntg0SeEwYaDN16ZczVWeAgd0GNeQlrLbPUguUjXrHBVVl 0Jwt57ll/MZ9luK4hS99lDEtLsE8mrIDjreETwfpLI7UZE09ObUre1dwFug== Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gab7t39d3-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:24 +0000 (GMT) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-cc11b5dd54dso83285a12.3 for ; Thu, 27 Aug 2026 09:08:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846904; x=1788451704; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=zlZEuku42ulqNc3ih1pFp1rs3evdduqZIg1SlzbXZv8=; b=LC/7sY10+LxgPs2jTkwniDZvNJ4vtewkYRHzkXMe6mY7vp8MQLOXBNlT8deY7i8y0Y w5ic5Yo/mPWVkXSdX5vPlXwWSWbEvP0zzppkbI9qpikvlpaYtGb/DbGPGMw6vnuf8s6f PsVNQ3d4BQCEvtCkQW2J6YmELszmjt3SZED2gQZ10XwmdK+GzGmd1cGkRFUM+JkOO8Ep 8UQaO46d3apqE8fTKzSMllHh1SkKribJ5HjOqM92mWL+EXY+CjYGMg4pnfjbEqjntwuJ LTb2iKzRUEMwJSxanG2cawe9By3/K3W0/6O6V3fDHO3nDD5jB8utk+EFUyt1FG2qS1DX 0TTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846904; x=1788451704; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=zlZEuku42ulqNc3ih1pFp1rs3evdduqZIg1SlzbXZv8=; b=jLLzegdRJQSTXo2EYyc2vSwxXjftDwN1scOj6z/lL1Eb3sr+uiTnR05X5ODcXjtnj2 5YWq9qaYZdqzpSx+N+NXJL4ONXIUWgVMi47IRaXAgZMi9cJUx74dFuxiiCpDc4TCURv1 m+EnPCvEJTcPq5zQigXVh7Ohr5r+hrOTVwOdFHlEykAElOqtZnaJ2nsdmBCdqA6dgwM9 EtOBuBcaNv/DvogJr8JVh0GZrArf2Y0U7JlAvXW6ne8xSFIB63MjRLWjK5iB9VzmRSyu S33qMq5EDzR/aMXj3tLKr/tZ+DLceUPJybgASBvAQG/xMVK8TiMrM5TOU4S5luDAzvf1 baMA== X-Forwarded-Encrypted: i=1; AHgh+Ro4yyo2W4PBzY60vxMcaRxfNW5Kzq+mXfVgEsuwQMjA8wU1MGsJ4nSbKuEUGK+aL3aTbi+JhDwtMwgdoUc=@vger.kernel.org X-Gm-Message-State: AFuF++nQfKD6c6zs3UryV3ABHhaEmQne7v1hfOu0uYL1pRr36wWwETvo UHT7oeQhBhZ+ka69oGcIZIFFmKZu+UKvU5dEiy1ke2cz6uygx8qfqK6w8ZQgt5P5T7WqziSrhk3 s25XkIEVB0C4z8AzaLWcc85lmf9MkZeoU9aIW8MqQuMYfCJxVAG8L0zvZ39abY/eN8gs= X-Gm-Gg: AR+sD13nePb8XTh+a8U+Pzzs+hJbxVdO36aCaYX2x+ThBlUOUQRocpPoSHHNyKPmv4t iMWRenkKtEpkABl5BMJcqtohcSamwOc4AwE4kngcVQsRkfvnFf9UagMNGnIoXnJLxlDI+0SH9bT 4nUUp/NpXUGH/e8qQSp1SdvIacH1qLLEELJq9+j2U/lO9TLEUvolJ3gxqionGexsofQv17EDyKs q+ZUwb1MhjOPkdMifc9TAF1CbCvipS0Te1Db3BLME7WXwNCY8ryAOKm/4o4UXQIjmrUqAGLWY9k r2OJIkJolF2Bb3f8BnqJvwoZ5dIoB6+JYDwImKLhaL/Z/EQrshbx8vqtq+HQhdNL8bM7pjqVJ+6 YfYj31uUefnx4VUfJL+X7kelf7GBb6sbvYZFcaf3LdXR4kjP5M4yc1A/AxFM= X-Received: by 2002:a17:90b:54c6:b0:36d:b424:4f17 with SMTP id 98e67ed59e1d1-396d0e24bdamr617127a91.1.1787846903005; Thu, 27 Aug 2026 09:08:23 -0700 (PDT) X-Received: by 2002:a17:90b:54c6:b0:36d:b424:4f17 with SMTP id 98e67ed59e1d1-396d0e24bdamr616889a91.1.1787846902153; Thu, 27 Aug 2026 09:08:22 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:21 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 01/11] virtio_blk: add inline encryption support Date: Thu, 27 Aug 2026 09:07:10 -0700 Message-ID: <20260827160806.1295313-2-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Authority-Analysis: v=2.4 cv=X6Bi7mTe c=1 sm=1 tr=0 ts=6a9060f8 cx=c_pps a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=Bv6Tw1xzN9wVcIKmVv0A:9 a=x9snwWr2DeNwDh03kgHS:22 X-Proofpoint-ORIG-GUID: j_g7udwmT6cb_Xatmp26li3_1IjKKaYj X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX/77mQzvfo5jv LVVUsZO+BsIHTDUuSJD36aHPmeZlroSEt5/7a5BorBXpV3Ya4Fu9DsT0NXWblfsv/uMYWw+ZRUR hRKxnsO1N0L+7ki5zfujAB4cLHR4ncI= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX64T6lZ2sEh8p AdJrCfmI3xI36otooPRq+YvVmNEw6h3Ot1uw5ubg1mXyTp/w1TPbfnJUfcOcW7qQTjZOzBifBE0 Q2eDalVISJRDMTO2iVVdjfm2JnN7gbJV/jSayVRwseEKQYFLyGvieWh3nCbw/iCqXRK9BYYbcpY ZUQsvdJHWVbGnT1wtu/fCbCigxefeDqA62WEP6f+/xDcrRHIBMV8Z1RTZ+rUYIc5qLejOs9ucve 8sOyp/oTB/bFaeE0OAbOHCdypDqcSqKi0sW1+sPUXfpPttAxfutHVYKhITfn74R6RJ87j35g5wW KfG1Ai3MVnznUHak1xcxhxYAcgQpMrQV1qr8ycHhscBSQXFfEdQObSeSSwaHxpB9fCz2Hhk61uU FaWFSG3firMhuJlVgQ9qNFSBeNYj3v6LjPZw30M97JZCR6WRnbzIxRDyAkXOFnRTpRMfpOIY8iY 7BX2gMyUMsIwDB2he1g== X-Proofpoint-GUID: j_g7udwmT6cb_Xatmp26li3_1IjKKaYj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 adultscore=0 clxscore=1011 priorityscore=1501 suspectscore=0 spamscore=0 phishscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan Negotiate VIRTIO_BLK_F_INLINE_ENCRYPTION with the host and wire it into the block layer's inline-crypto framework to enable inline encryption on virtio block device. When the feature is present, the driver reads crypto characteristics from virtio config space (key-slot count, DUN size, supported key types) and issues VIRTIO_BLK_T_GET_CRYPTO_MODES to discover supported cipher and data-unit-size combinations. Encrypted requests use new request types VIRTIO_BLK_T_CRYPTO_IN/OUT, which append a virtio_blk_crypto_msg (keyslot index, DUN, data-unit-size-bits) to the standard outhdr. A new virtio block crypto extension driver (virtio_blk_crypto_ext), owns the blk_crypto_profile singleton and the blk_crypto_ll_ops dispatch table. Actual key operations are forwarded to a platform-specific backend registered via virtblk_set_crypto_ops(); without one, VIRTIO_BLK_F_INLINE_ENCRYPTION is still negotiated and the profile is registered, but every keyslot operation returns -EOPNOTSUPP. The shared profile is a singleton as per blk_crypto_profile is corresponding to one ICE hardware: the first device to negotiate the feature initializes it; subsequent devices reuse it only when their negotiated capabilities (slot count, DUN size, key types) match exactly. Signed-off-by: linlzhan --- drivers/block/Kconfig | 13 ++ drivers/block/Makefile | 2 + drivers/block/virtio_blk.c | 199 ++++++++++++++++-- drivers/block/virtio_blk_crypto_ext.c | 283 ++++++++++++++++++++++++++ include/linux/virtio_blk_crypto_ext.h | 78 +++++++ include/uapi/linux/virtio_blk.h | 62 ++++++ 6 files changed, 623 insertions(+), 14 deletions(-) create mode 100644 drivers/block/virtio_blk_crypto_ext.c create mode 100644 include/linux/virtio_blk_crypto_ext.h diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 858320b6ebb7..7790ee2c700c 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -312,6 +312,19 @@ config VIRTIO_BLK This is the virtual block driver for virtio. It can be used with QEMU based VMMs (like KVM or Xen). Say Y or M. =20 +config VIRTBLK_CRYPTO_VIRTUALIZATION + tristate "Virtio block inline encryption virtualization support" + depends on VIRTIO_BLK && BLK_INLINE_ENCRYPTION + help + Say 'Y or M' to enable routing of crypto requests to a different + operating system in a virtualized environment. This option by + itself does not provide a working backend: enable a + platform-specific driver that implements struct + virtblk_crypto_variant_ops as well (e.g. QCOM_CRYPTO_VIRT on + Qualcomm platforms). Without one, VIRTIO_BLK_F_INLINE_ENCRYPTION is + still negotiated and advertised to the block layer, but every + inline-crypto operation fails with -EOPNOTSUPP at runtime. + config BLK_DEV_RBD tristate "Rados block device (RBD)" depends on INET && BLOCK diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 2d8096eb8cdf..079c910d5fc9 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -25,6 +25,8 @@ obj-$(CONFIG_SUNVDC) +=3D sunvdc.o obj-$(CONFIG_BLK_DEV_NBD) +=3D nbd.o obj-$(CONFIG_VIRTIO_BLK) +=3D virtio_blk.o =20 +obj-$(CONFIG_VIRTBLK_CRYPTO_VIRTUALIZATION) +=3D virtio_blk_crypto_ext.o + obj-$(CONFIG_XEN_BLKDEV_FRONTEND) +=3D xen-blkfront.o obj-$(CONFIG_XEN_BLKDEV_BACKEND) +=3D xen-blkback/ obj-$(CONFIG_BLK_DEV_DRBD) +=3D drbd/ diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 32bf3ba07a9d..61a3967bb4df 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include =20 #define PART_BITS 4 #define VQ_NAME_LEN 16 @@ -87,7 +89,14 @@ struct virtio_blk { =20 struct virtblk_req { /* Out header */ - struct virtio_blk_outhdr out_hdr; + union { + struct virtio_blk_outhdr base; + struct { + struct virtio_blk_outhdr base; + /* Crypto message (if VIRTIO_BLK_F_INLINE_ENCRYPTION) */ + struct virtio_blk_crypto_msg msg; + } crypto_append; + } out_hdr; =20 /* In header */ union { @@ -140,12 +149,17 @@ static int virtblk_add_req(struct virtqueue *vq, stru= ct virtblk_req *vbr) { struct scatterlist out_hdr, in_hdr, *sgs[3]; unsigned int num_out =3D 0, num_in =3D 0; + size_t out_hdr_len =3D sizeof(vbr->out_hdr.base); + + if (vbr->out_hdr.base.type =3D=3D cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_= CRYPTO_IN) || + vbr->out_hdr.base.type =3D=3D cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_= CRYPTO_OUT)) + out_hdr_len =3D sizeof(vbr->out_hdr.crypto_append); =20 - sg_init_one(&out_hdr, &vbr->out_hdr, sizeof(vbr->out_hdr)); + sg_init_one(&out_hdr, &vbr->out_hdr, out_hdr_len); sgs[num_out++] =3D &out_hdr; =20 if (vbr->sg_table.nents) { - if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT)) + if (vbr->out_hdr.base.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT)) sgs[num_out++] =3D vbr->sg_table.sgl; else sgs[num_out + num_in++] =3D vbr->sg_table.sgl; @@ -235,6 +249,15 @@ static void virtblk_cleanup_cmd(struct request *req) kfree(bvec_virt(&req->special_vec)); } =20 +static bool is_crypto_request(struct virtio_device *vdev, struct request *= req) +{ + if (!IS_ENABLED(CONFIG_VIRTBLK_CRYPTO_VIRTUALIZATION) || + !virtio_has_feature(vdev, VIRTIO_BLK_F_INLINE_ENCRYPTION)) + return false; + + return req->crypt_ctx && req->crypt_keyslot; +} + static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev, struct request *req, struct virtblk_req *vbr) @@ -248,15 +271,21 @@ static blk_status_t virtblk_setup_cmd(struct virtio_d= evice *vdev, return BLK_STS_NOTSUPP; =20 /* Set fields for all request types */ - vbr->out_hdr.ioprio =3D cpu_to_virtio32(vdev, req_get_ioprio(req)); + vbr->out_hdr.base.ioprio =3D cpu_to_virtio32(vdev, req_get_ioprio(req)); =20 switch (req_op(req)) { case REQ_OP_READ: - type =3D VIRTIO_BLK_T_IN; + if (is_crypto_request(vdev, req)) + type =3D VIRTIO_BLK_T_CRYPTO_IN; + else + type =3D VIRTIO_BLK_T_IN; sector =3D blk_rq_pos(req); break; case REQ_OP_WRITE: - type =3D VIRTIO_BLK_T_OUT; + if (is_crypto_request(vdev, req)) + type =3D VIRTIO_BLK_T_CRYPTO_OUT; + else + type =3D VIRTIO_BLK_T_OUT; sector =3D blk_rq_pos(req); break; case REQ_OP_FLUSH: @@ -298,8 +327,9 @@ static blk_status_t virtblk_setup_cmd(struct virtio_dev= ice *vdev, break; case REQ_OP_DRV_IN: /* - * Out header has already been prepared by the caller (virtblk_get_id() - * or virtblk_submit_zone_report()), nothing to do here. + * Out header has already been prepared by the caller (virtblk_get_id(), + * virtblk_submit_zone_report() or virtblk_get_crypto_modes()), nothing + * to do here. */ return 0; default: @@ -309,8 +339,8 @@ static blk_status_t virtblk_setup_cmd(struct virtio_dev= ice *vdev, =20 /* Set fields for non-REQ_OP_DRV_IN request types */ vbr->in_hdr_len =3D in_hdr_len; - vbr->out_hdr.type =3D cpu_to_virtio32(vdev, type); - vbr->out_hdr.sector =3D cpu_to_virtio64(vdev, sector); + vbr->out_hdr.base.type =3D cpu_to_virtio32(vdev, type); + vbr->out_hdr.base.sector =3D cpu_to_virtio64(vdev, sector); =20 if (type =3D=3D VIRTIO_BLK_T_DISCARD || type =3D=3D VIRTIO_BLK_T_WRITE_ZE= ROES || type =3D=3D VIRTIO_BLK_T_SECURE_ERASE) { @@ -318,6 +348,17 @@ static blk_status_t virtblk_setup_cmd(struct virtio_de= vice *vdev, return BLK_STS_RESOURCE; } =20 + if (type =3D=3D VIRTIO_BLK_T_CRYPTO_IN || type =3D=3D VIRTIO_BLK_T_CRYPTO= _OUT) { + unsigned int slot =3D blk_crypto_keyslot_index(req->crypt_keyslot); + unsigned int data_unit_size_bits =3D req->crypt_ctx->bc_key->data_unit_s= ize_bits; + u64 dun =3D req->crypt_ctx->bc_dun[0]; + + vbr->out_hdr.crypto_append.msg.slot =3D cpu_to_virtio32(vdev, slot); + vbr->out_hdr.crypto_append.msg.data_unit_size_bits =3D + cpu_to_virtio32(vdev, data_unit_size_bits); + vbr->out_hdr.crypto_append.msg.dun =3D cpu_to_virtio64(vdev, dun); + } + return 0; } =20 @@ -568,8 +609,8 @@ static int virtblk_submit_zone_report(struct virtio_blk= *vblk, =20 vbr =3D blk_mq_rq_to_pdu(req); vbr->in_hdr_len =3D sizeof(vbr->in_hdr.status); - vbr->out_hdr.type =3D cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_ZONE_REPOR= T); - vbr->out_hdr.sector =3D cpu_to_virtio64(vblk->vdev, sector); + vbr->out_hdr.base.type =3D cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_ZONE_= REPORT); + vbr->out_hdr.base.sector =3D cpu_to_virtio64(vblk->vdev, sector); =20 err =3D blk_rq_map_kern(req, report_buf, report_len, GFP_KERNEL); if (err) @@ -817,8 +858,8 @@ static int virtblk_get_id(struct gendisk *disk, char *i= d_str) =20 vbr =3D blk_mq_rq_to_pdu(req); vbr->in_hdr_len =3D sizeof(vbr->in_hdr.status); - vbr->out_hdr.type =3D cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_ID); - vbr->out_hdr.sector =3D 0; + vbr->out_hdr.base.type =3D cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_I= D); + vbr->out_hdr.base.sector =3D 0; =20 err =3D blk_rq_map_kern(req, id_str, VIRTIO_BLK_ID_BYTES, GFP_KERNEL); if (err) @@ -863,6 +904,70 @@ static int virtblk_getgeo(struct gendisk *disk, struct= hd_geometry *geo) return ret; } =20 +/* Maps VIRTIO_BLK_CRYPTO_MODE_* values to the kernel's internal enum. */ +static const enum blk_crypto_mode_num + virtio_blk_crypto_mode_map[VIRTIO_BLK_CRYPTO_MODE_MAX + 1] =3D { + [VIRTIO_BLK_CRYPTO_MODE_INVALID] =3D BLK_ENCRYPTION_MODE_INVALID, + [VIRTIO_BLK_CRYPTO_MODE_AES_256_XTS] =3D BLK_ENCRYPTION_MODE_AES_256_XTS, +}; + +static int virtblk_get_crypto_modes(struct virtio_blk *vblk, + unsigned int *crypto_modes_supported) +{ + struct request_queue *q =3D vblk->disk->queue; + unsigned int nr_modes =3D VIRTIO_BLK_CRYPTO_MODE_MAX + 1; + size_t buf_size =3D sizeof(struct virtio_blk_crypto_modes); + struct virtio_blk_crypto_modes *virtblk_cmodes; + struct request *req; + struct virtblk_req *vbr; + unsigned int i; + int err; + + virtblk_cmodes =3D kzalloc(buf_size, GFP_KERNEL); + if (!virtblk_cmodes) + return -ENOMEM; + + req =3D blk_mq_alloc_request(q, REQ_OP_DRV_IN, 0); + if (IS_ERR(req)) { + err =3D PTR_ERR(req); + goto out_free; + } + + vbr =3D blk_mq_rq_to_pdu(req); + vbr->in_hdr_len =3D sizeof(vbr->in_hdr.status); + vbr->out_hdr.base.type =3D cpu_to_virtio32(vblk->vdev, + VIRTIO_BLK_T_GET_CRYPTO_MODES); + vbr->out_hdr.base.sector =3D 0; + + err =3D blk_rq_map_kern(req, virtblk_cmodes, buf_size, GFP_KERNEL); + if (err) + goto out_req; + + blk_execute_rq(req, false); + err =3D blk_status_to_errno(virtblk_result(vbr->in_hdr.status)); + if (err) + goto out_req; + + for (i =3D 1; i < nr_modes; i++) { + u32 mode_mask =3D virtio32_to_cpu(vblk->vdev, virtblk_cmodes->modes[i]); + enum blk_crypto_mode_num mode =3D virtio_blk_crypto_mode_map[i]; + + if (!mode_mask) + continue; + if (!mode) { + dev_warn(&vblk->vdev->dev, + "ignoring unknown crypto mode %u\n", i); + continue; + } + crypto_modes_supported[mode] =3D mode_mask; + } +out_req: + blk_mq_free_request(req); +out_free: + kfree(virtblk_cmodes); + return err; +} + static void virtblk_free_disk(struct gendisk *disk) { struct virtio_blk *vblk =3D disk->private_data; @@ -1435,6 +1540,51 @@ static int virtblk_read_limits(struct virtio_blk *vb= lk, return 0; } =20 +static int virtblk_init_crypto(struct virtio_blk *vblk) +{ + struct virtio_device *vdev =3D vblk->vdev; + unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX] =3D { 0 }; + /* virtio_cread() requires the variable size to match the config field ex= actly */ + u16 max_slots; + u8 max_dun_bytes, key_types; + int err; + + virtio_cread(vdev, struct virtio_blk_config, + enc_characteristics.max_slots, &max_slots); + virtio_cread(vdev, struct virtio_blk_config, + enc_characteristics.max_dun_bytes, &max_dun_bytes); + virtio_cread(vdev, struct virtio_blk_config, + enc_characteristics.key_types, &key_types); + + dev_dbg(&vdev->dev, + "max_slots =3D %u, max_dun_bytes =3D %u, key_types =3D 0x%x\n", + max_slots, max_dun_bytes, key_types); + + if (!max_slots) + return -EINVAL; + if (!(key_types & (VIRTIO_BLK_CRYPTO_KEY_TYPE_RAW | + VIRTIO_BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))) + return -EINVAL; + /* + * struct virtio_blk_crypto_msg.dun is a fixed __virtio64, i.e. this + * driver can only ever transmit 8 bytes of DUN per request. Refuse + * to advertise more than that as supported, or blk-crypto could + * negotiate a larger dun_bytes with the filesystem and have the + * high-order bytes of req->crypt_ctx->bc_dun silently dropped in + * virtblk_setup_cmd(), reusing the same IV across data units that + * only differ in those high-order bytes. + */ + if (max_dun_bytes > sizeof(u64)) + return -EINVAL; + + err =3D virtblk_get_crypto_modes(vblk, crypto_modes_supported); + if (err) + return err; + + return virtblk_init_inline_crypto(max_slots, max_dun_bytes, key_types, + crypto_modes_supported, &vdev->dev); +} + static int virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -1540,6 +1690,26 @@ static int virtblk_probe(struct virtio_device *vdev) goto out_cleanup_disk; } =20 + if (IS_ENABLED(CONFIG_VIRTBLK_CRYPTO_VIRTUALIZATION) && + virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_INLINE_ENCRYPTION)) { + if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_ZONED)) { + dev_warn(&vdev->dev, + "zoned device does not support inline encryption, disabling it\n"); + } else { + /* Initialize supported crypto capabilities */ + err =3D virtblk_init_crypto(vblk); + if (!err) { + if (!virtblk_crypto_register(vblk->disk->queue)) + dev_warn(&vdev->dev, + "failed to register inline crypto profile with the block layer, cont= inuing without inline crypto support\n"); + } else { + dev_warn(&vdev->dev, + "inline crypto init failed: %d, continuing without inline crypto supp= ort\n", + err); + } + } + } + err =3D device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups); if (err) goto out_cleanup_disk; @@ -1672,6 +1842,7 @@ static unsigned int features[] =3D { VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES, VIRTIO_BLK_F_SECURE_ERASE, VIRTIO_BLK_F_ZONED, + VIRTIO_BLK_F_INLINE_ENCRYPTION, }; =20 static struct virtio_driver virtio_blk =3D { diff --git a/drivers/block/virtio_blk_crypto_ext.c b/drivers/block/virtio_b= lk_crypto_ext.c new file mode 100644 index 000000000000..00b6d410d303 --- /dev/null +++ b/drivers/block/virtio_blk_crypto_ext.c @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +struct virtblk_crypto_profile { + struct blk_crypto_profile profile; + struct virtblk_crypto_variant_ops *ops; +}; + +static struct virtblk_crypto_profile g_vdcp; +static bool g_crypto_profile_initialized; +static struct device *virtblk_profile_owner; +static unsigned int g_max_slots; +static unsigned int g_max_dun_bytes; +static unsigned int g_key_types; +static DEFINE_MUTEX(virtblk_crypto_init_lock); +static DEFINE_MUTEX(virtblk_crypto_ops_lock); + +bool virtblk_crypto_register(struct request_queue *q) +{ + return blk_crypto_register(&g_vdcp.profile, q); +} +EXPORT_SYMBOL_GPL(virtblk_crypto_register); + +/* + * Returns the variant ops registered for @profile's virtblk_crypto_profile + * with a module reference held on ops->owner, or NULL if none are + * registered. Pairs with virtblk_crypto_ops_put(). + * + * Holding a module reference for the duration of each dispatch call (rath= er + * than just dereferencing the raw pointer) is what makes it safe for the + * module that implements these ops (e.g. drivers/soc/qcom/crypto_virt.c) = to + * be rmmod'd: module removal will fail/block until every in-flight dispat= ch + * call has released its reference, instead of racing with a concurrent + * virtblk_set_crypto_ops(NULL) and the ops table disappearing mid-call. + */ +static struct virtblk_crypto_variant_ops * +virtblk_crypto_ops_get(struct blk_crypto_profile *profile) +{ + struct virtblk_crypto_profile *vdcp =3D + container_of(profile, struct virtblk_crypto_profile, profile); + struct virtblk_crypto_variant_ops *ops; + + mutex_lock(&virtblk_crypto_ops_lock); + ops =3D vdcp->ops; + if (ops && !try_module_get(ops->owner)) + ops =3D NULL; + mutex_unlock(&virtblk_crypto_ops_lock); + + return ops; +} + +static void virtblk_crypto_ops_put(struct virtblk_crypto_variant_ops *ops) +{ + module_put(ops->owner); +} + +static int virtblk_crypto_keyslot_program(struct blk_crypto_profile *profi= le, + const struct blk_crypto_key *key, + unsigned int slot) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->program_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->program_key(key, slot); + virtblk_crypto_ops_put(ops); + if (ret) + pr_err("program hardware wrapped key failed: slot=3D%u ret=3D%d\n", slot= , ret); + + return ret; +} + +static int virtblk_crypto_keyslot_evict(struct blk_crypto_profile *profile, + const struct blk_crypto_key *key, + unsigned int slot) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->evict_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->evict_key(slot); + virtblk_crypto_ops_put(ops); + if (ret) + pr_err("evict keyslot %u failed: %d\n", slot, ret); + + return ret; +} + +static int virtblk_crypto_derive_sw_secret(struct blk_crypto_profile *prof= ile, + const u8 *eph_key, + size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->derive_sw_secret_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->derive_sw_secret_key(eph_key, eph_key_size, sw_secret); + virtblk_crypto_ops_put(ops); + if (ret) + pr_err("derive software secret failed: %d\n", ret); + + return ret; +} + +static int virtblk_crypto_generate_key(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->generate_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->generate_key(lt_key); + virtblk_crypto_ops_put(ops); + if (ret < 0) + pr_err("generate hardware wrapped key failed: %d\n", ret); + + return ret; +} + +static int virtblk_crypto_prepare_key(struct blk_crypto_profile *profile, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->prepare_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->prepare_key(lt_key, lt_key_size, eph_key); + virtblk_crypto_ops_put(ops); + if (ret < 0) + pr_err("prepare hardware wrapped key failed: %d\n", ret); + + return ret; +} + +static int virtblk_crypto_import_key(struct blk_crypto_profile *profile, + const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct virtblk_crypto_variant_ops *ops =3D virtblk_crypto_ops_get(profile= ); + int ret; + + if (!ops || !ops->import_key) { + if (ops) + virtblk_crypto_ops_put(ops); + return -EOPNOTSUPP; + } + + ret =3D ops->import_key(raw_key, raw_key_size, lt_key); + virtblk_crypto_ops_put(ops); + if (ret < 0) + pr_err("import hardware wrapped key failed: %d\n", ret); + + return ret; +} + +static const struct blk_crypto_ll_ops virtblk_crypto_ops =3D { + .keyslot_program =3D virtblk_crypto_keyslot_program, + .keyslot_evict =3D virtblk_crypto_keyslot_evict, + .derive_sw_secret =3D virtblk_crypto_derive_sw_secret, + .generate_key =3D virtblk_crypto_generate_key, + .prepare_key =3D virtblk_crypto_prepare_key, + .import_key =3D virtblk_crypto_import_key, +}; + +int virtblk_init_inline_crypto(unsigned int max_slots, unsigned int max_du= n_bytes, + unsigned int key_types, + const unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MA= X], + struct device *dev) +{ + struct blk_crypto_profile *profile =3D &g_vdcp.profile; + unsigned int key_type_supported =3D 0; + int err =3D 0; + + dev_info(dev, "probing inline crypto capabilities\n"); + + mutex_lock(&virtblk_crypto_init_lock); + + /* + * profile is a single, process-wide blk_crypto_profile shared by every + * VIRTIO_BLK_F_INLINE_ENCRYPTION device. Only the first device to get + * here actually initializes it; any other device just reuses it as-is + * if its negotiated capabilities match. A mismatch means this device's + * capabilities don't actually correspond to what the shared profile + * was set up for (wrong keyslot count, DUN size, or key types), which + * is a correctness/security concern, not just a cosmetic one -- fail + * instead of silently registering a profile that doesn't match what + * this device supports. + */ + if (g_crypto_profile_initialized) { + if (max_slots !=3D g_max_slots || max_dun_bytes !=3D g_max_dun_bytes || + key_types !=3D g_key_types) { + dev_warn(dev, + "inline crypto profile already initialized by %s (max_slots=3D%u max_= dun_bytes=3D%u key_types=3D0x%x); " + "this device reports max_slots=3D%u max_dun_bytes=3D%u key_types=3D0x= %x -- sharing one " + "blk_crypto_profile across multiple VIRTIO_BLK_F_INLINE_ENCRYPTION de= vices with differing " + "capabilities is not supported, refusing to enable inline crypto for = this device\n", + dev_name(virtblk_profile_owner), g_max_slots, g_max_dun_bytes, g_key_= types, + max_slots, max_dun_bytes, key_types); + err =3D -EINVAL; + } + goto out_unlock; + } + + if (key_types & VIRTIO_BLK_CRYPTO_KEY_TYPE_RAW) + key_type_supported |=3D BLK_CRYPTO_KEY_TYPE_RAW; + if (key_types & VIRTIO_BLK_CRYPTO_KEY_TYPE_HW_WRAPPED) + key_type_supported |=3D BLK_CRYPTO_KEY_TYPE_HW_WRAPPED; + + err =3D blk_crypto_profile_init(profile, max_slots); + if (err) { + dev_err(dev, "crypto profile initialization failed: %d\n", err); + goto out_unlock; + } + + profile->ll_ops =3D virtblk_crypto_ops; + profile->max_dun_bytes_supported =3D max_dun_bytes; + profile->key_types_supported =3D key_type_supported; + profile->dev =3D dev; + memcpy(profile->modes_supported, crypto_modes_supported, + BLK_ENCRYPTION_MODE_MAX * sizeof(unsigned int)); + + virtblk_profile_owner =3D dev; + g_max_slots =3D max_slots; + g_max_dun_bytes =3D max_dun_bytes; + g_key_types =3D key_types; + g_crypto_profile_initialized =3D true; + + dev_info(dev, "inline crypto profile initialized\n"); + +out_unlock: + mutex_unlock(&virtblk_crypto_init_lock); + return err; +} +EXPORT_SYMBOL_GPL(virtblk_init_inline_crypto); + +void virtblk_set_crypto_ops(struct virtblk_crypto_variant_ops *ops) +{ + if (!g_crypto_profile_initialized) + pr_warn("virtio blk crypto profile hasn't been initialized\n"); + + mutex_lock(&virtblk_crypto_ops_lock); + g_vdcp.ops =3D ops; + mutex_unlock(&virtblk_crypto_ops_lock); +} +EXPORT_SYMBOL_GPL(virtblk_set_crypto_ops); + +MODULE_DESCRIPTION("Virtio block inline crypto extension"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/virtio_blk_crypto_ext.h b/include/linux/virtio_b= lk_crypto_ext.h new file mode 100644 index 000000000000..3fe66029ac0d --- /dev/null +++ b/include/linux/virtio_blk_crypto_ext.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LINUX_VIRTIO_BLK_CRYPTO_EXT_H +#define __LINUX_VIRTIO_BLK_CRYPTO_EXT_H + +#include + +struct blk_crypto_profile; +struct blk_crypto_key; +struct device; +struct request_queue; + +#if IS_ENABLED(CONFIG_VIRTBLK_CRYPTO_VIRTUALIZATION) +struct virtblk_crypto_variant_ops { + /* + * Module providing the function pointers below. virtio_blk_crypto_ext.c + * pins it with try_module_get()/module_put() around every call, so that + * the module implementing these ops can be safely rmmod'd: the unload + * will simply block/fail until no dispatch call is in flight, instead + * of racing with one. + */ + struct module *owner; + int (*program_key)(const struct blk_crypto_key *key, + unsigned int slot); + int (*evict_key)(unsigned int slot); + int (*derive_sw_secret_key)(const u8 *eph_key, size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); + int (*generate_key)(u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + int (*prepare_key)(const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + int (*import_key)(const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); +}; + +/* + * Probes the platform's inline-encryption capabilities and initializes the + * shared blk_crypto_profile singleton (once) with the keyslot/DUN limits, + * supported key types, wrapped key size, and supported crypto modes repor= ted + * by the device over virtio config space / VIRTIO_BLK_T_GET_CRYPTO_MODES. + * + * Safe to call from multiple devices, including concurrently: only the + * first caller actually initializes the shared profile, every other caller + * just validates its own capabilities against what was already negotiated. + */ +int virtblk_init_inline_crypto(unsigned int max_slots, unsigned int max_du= n_bytes, + unsigned int key_types, + const unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX], + struct device *dev); + +/* + * Registers the (already-initialized) shared blk_crypto_profile with the + * given request queue. Returns false (and leaves the queue without inline + * crypto) if the queue's block-integrity support conflicts with inline + * encryption; see blk_crypto_register(). + */ +bool virtblk_crypto_register(struct request_queue *q); + +void virtblk_set_crypto_ops(struct virtblk_crypto_variant_ops *ops); + +#else + +static inline int virtblk_init_inline_crypto(unsigned int max_slots, + unsigned int max_dun_bytes, unsigned int key_types, + const unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX], + struct device *dev) +{ + return -EOPNOTSUPP; +} + +static inline bool virtblk_crypto_register(struct request_queue *q) +{ + return false; +} + + +#endif + +#endif /* __LINUX_VIRTIO_BLK_CRYPTO_EXT_H */ diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_bl= k.h index 3744e4da1b2a..c1941f7fe019 100644 --- a/include/uapi/linux/virtio_blk.h +++ b/include/uapi/linux/virtio_blk.h @@ -42,6 +42,7 @@ #define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */ #define VIRTIO_BLK_F_SECURE_ERASE 16 /* Secure Erase is supported */ #define VIRTIO_BLK_F_ZONED 17 /* Zoned block device */ +#define VIRTIO_BLK_F_INLINE_ENCRYPTION 22 /* Inline Encryption is support= ed */ =20 /* Legacy feature bits */ #ifndef VIRTIO_BLK_NO_LEGACY @@ -148,6 +149,18 @@ struct virtio_blk_config { __u8 model; __u8 unused2[3]; } zoned; + + /* Inline Encryption device characteristics (if VIRTIO_BLK_F_INLINE_ENCRY= PTION) */ + struct virtio_blk_enc_characteristics { + __virtio16 max_slots; + __u8 max_dun_bytes; +/* Bitmask values for virtio_blk_enc_characteristics.key_types */ +#define VIRTIO_BLK_CRYPTO_KEY_TYPE_RAW (1 << 0) +#define VIRTIO_BLK_CRYPTO_KEY_TYPE_HW_WRAPPED (1 << 1) + /* Bitmask of supported key types: VIRTIO_BLK_CRYPTO_KEY_TYPE_* */ + __u8 key_types; + __virtio32 unused3; + } enc_characteristics; } __attribute__((packed)); =20 /* @@ -206,6 +219,15 @@ struct virtio_blk_config { /* Reset All zones command */ #define VIRTIO_BLK_T_ZONE_RESET_ALL 26 =20 +/* Inline-encrypted write: crypto_msg set in outhdr */ +#define VIRTIO_BLK_T_CRYPTO_OUT 27 + +/* Inline-encrypted read: crypto_msg set in outhdr */ +#define VIRTIO_BLK_T_CRYPTO_IN 28 + +/* Get inline crypto modes */ +#define VIRTIO_BLK_T_GET_CRYPTO_MODES 30 + #ifndef VIRTIO_BLK_NO_LEGACY /* Barrier before this op. */ #define VIRTIO_BLK_T_BARRIER 0x80000000 @@ -225,6 +247,46 @@ struct virtio_blk_outhdr { __virtio64 sector; }; =20 +/* + * Crypto message descriptor, appended to the outhdr of a + * VIRTIO_BLK_T_CRYPTO_OUT or VIRTIO_BLK_T_CRYPTO_IN request. + */ +struct virtio_blk_crypto_msg { + /* virtual key slot index */ + __virtio32 slot; + /* log2 of the data unit size in bytes */ + __virtio32 data_unit_size_bits; + /* data unit number (DUN / IV) for this request */ + __virtio64 dun; +}; + +/* + * Crypto mode numbers used in VIRTIO_BLK_T_GET_CRYPTO_MODES replies and in + * indexing struct virtio_blk_crypto_modes.modes[] below. These numbers are + * assigned by the virtio spec and are stable: a number is never reused for + * a different crypto mode, and additional crypto modes are assigned new, + * higher numbers. + */ +enum { + VIRTIO_BLK_CRYPTO_MODE_INVALID, + VIRTIO_BLK_CRYPTO_MODE_AES_256_XTS, + __VIRTIO_BLK_CRYPTO_MODE_MAX, /* sentinel: always one past the last real = mode */ +}; + +/* Highest crypto mode number defined by this version of the header. */ +#define VIRTIO_BLK_CRYPTO_MODE_MAX (__VIRTIO_BLK_CRYPTO_MODE_MAX - 1) + +/* Reply to a VIRTIO_BLK_T_GET_CRYPTO_MODES request. */ +struct virtio_blk_crypto_modes { + /* + * modes[N], for crypto mode number N <=3D VIRTIO_BLK_CRYPTO_MODE_MAX, is + * a bitmask of the data unit sizes with which crypto mode N can be + * used: bit i is set if a data unit size of (1 << i) bytes is + * supported. modes[0] is reserved and always 0. + */ + __virtio32 modes[__VIRTIO_BLK_CRYPTO_MODE_MAX]; +}; + /* * Supported zoned device models. */ --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 BD52B488D86 for ; Thu, 27 Aug 2026 16:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846912; cv=none; b=XgL51s8hgpsNrzGCqF+sFoiqrVlnIsmkgPaQQbdIYw4i6He3fqNmhSib8zP6Pm8GXBDnJqiaM1oZ7dyldt7I9iOzWOiPbXxdMb/s621/QT9kobJRZwQt9qSl+e8GWRlzicQmruGjUCJg8ZgYK+iY4YZL9z1d8QiThZXjcFjHD6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846912; c=relaxed/simple; bh=fVeZw9EDi7ERA4LNK8w26r8i8AIslzVnGqRWpyHht7s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=smPsJZhHkhiZnKwcyURTKJPvWCqwMvIjfypIxux3zj4s7fIzYNmqGF5K3IWylhk5SYKF6RVvT+aYg6PNiQvPQ9FCV0HYEaiP3VS7xZeJFE8vPnOVMqptoXsFUtl+et6RA4f+Rf8qH8TpIeeAzNg6m2ffVOG7UHkXicFR+ab0Fq4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Q2KWwxIF; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=AyYMyGzW; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Q2KWwxIF"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="AyYMyGzW" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFc3YY3921931 for ; Thu, 27 Aug 2026 16:08:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=Tb6pSykcv9W jH2s5aqk5SoF1TrILL2gUQOLQeoLKEig=; b=Q2KWwxIFk2F/i0p4ivIdce28hi/ Kfsvpi/llW7MriXLEr1R0lJqVOkL+SdAqphOorZ6C9TBaPJXTJklaz1exwKCHVRl 3rDnkKEOvS71K/HuQMf5/kLeEzwBlzwqd4p4EuIdd7Y1USbAcCEW5LMRYI55Aao0 TaObjUU00cbV4mCBt5ClP0WkQmXvuoobdPr8eJC20Rkgb8HBUSvDsJmj2tPHmMME 6gmyuVtWum1Pg2myTCpiy/9Cv57OHsPznzLt5LUUE34y5tfhFlliVQpzSTEHmK2z dFxWYzr4y3HKTO4FolcMpJwWVp+aNccuH6ZpXECEuZ33SJuXeHadtWd5YUA== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gaphw0h7n-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:28 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-38e11baa66eso166139a91.2 for ; Thu, 27 Aug 2026 09:08:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846907; x=1788451707; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Tb6pSykcv9WjH2s5aqk5SoF1TrILL2gUQOLQeoLKEig=; b=AyYMyGzWfKZhELLJ5hPfIOJnbF3S4RkVdIyVPfFD/xFTLcC5aqUAU9HihCqsEXLPh6 /4sC8XvhCONxs+wM+td+jppaz9tupzcwMNzAYulfbodK9RipWvHnxCzjrxhaW4zwyxxs CYokNiypyLBFbZ1byC1PyehUv6bEQUovuSpnaFPOwCRs7KbY+SYZgPlbxb0BzU7fp7KW 2CO+PmdafC53kZM6zTRAZ43+NV55xTAArIdYfGzgmn5T4tkf3CviE0edrb6ig8G0D9YL jGQio3I5UIneMmxs98Zf8XWuIOWFp4j86B2vc9lTyvmiLB0YprKlclMTAfkWXyQAhMJQ bQfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846907; x=1788451707; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Tb6pSykcv9WjH2s5aqk5SoF1TrILL2gUQOLQeoLKEig=; b=Nowh7ZYKc4/vUzA8mtsSGJBYHkkvjykXQ7cM+/pQ6RpXfc/LWq6niBoeUzSwPDFqcN 0+8TwC6wzz4RsRt9BSPUtFmXVrnXOgM6qRmlj89KtywjA/uMoUrda9PayxcUIRQ66UdP zutXSMgIHs3RShLYgmI3+2E69L30fgYZQNIaiFSVSRYm+wbWZ9+W8STRPRAGSuQ18o4L Ow6rak5XonJOLnXeQOB4XW7TYeRruLxu6lmqSqRcFmfFPYKl/L06okFnLbPkWUHPJXfE mtkyW/5AdS3bS0fEKLL2WtwjvRCe63PMV7fR9v2PkMi498rctlgauKhM8GJqDK0m7xNk +aYA== X-Forwarded-Encrypted: i=1; AHgh+Rrr5gNd29kj8RCeyT3Fh9ggRnWXWquGUHDu99UO44KnktENCOpc9z5cO5DJH1Z4KzBCxbhFd59hS5ST6xc=@vger.kernel.org X-Gm-Message-State: AFuF++nxP93/zTjgf1LVsJEUHHWJxjnAI7VGGpeLXs0NjPp3NKCAHlPm wRd3SpEdacCiR6AbueYHM6khQYwl82zAJfgm6qAGIrv815kHtcCL8/UYJaKuHwRMPFhCAPyISmU nAQRKqA4BaGlIKAuXfdAt7uVpXJIv3bepM3URoRdACb+yiEOirD8ot+SHNDbx36xp+kc= X-Gm-Gg: AR+sD13APgX2Tcaefh3csNB1ZGykUiKzljLZcjUBVurKAq/aGw0EfsZR0QQdd56qau2 LM9ZIPYl99nnA1YyGI3NiSKMLD37VqVcKvkWdFH7IcT65aQY3SgwpWPt9st+5VSix+s4F5BQtBV RqqcGZrxvzEpLwfeFrEPeUC2TQym7x7S1QBmPvpzhT7hqW059dPTTcutApaIHIieXyu6jlHNTYA CSiHD6hGaZfTbnA7aw6VQmA/DjYWDfH4Cqvk0A/cClukNPeAYwyMjhULaFn2fG9RYwLaQu82K3a onBMjGuTi42sAb8z94JHQuWnmK0WHME2A/eC5Kz3+rqZevaey7Wbc7Cg5maDKcxq2+rb96fXNei cQlko/HsPtMzBPzGYe2JVEnojuNN9qFYEGxZK9HVIxlkTZj6fkTijDHKrIZs= X-Received: by 2002:a17:90b:1d83:b0:38e:2e86:ed02 with SMTP id 98e67ed59e1d1-396d1023217mr343758a91.14.1787846905131; Thu, 27 Aug 2026 09:08:25 -0700 (PDT) X-Received: by 2002:a17:90b:1d83:b0:38e:2e86:ed02 with SMTP id 98e67ed59e1d1-396d1023217mr343639a91.14.1787846904578; Thu, 27 Aug 2026 09:08:24 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:24 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 02/11] soc: qcom: add crypto_virt backend for virtio-blk inline crypto Date: Thu, 27 Aug 2026 09:07:11 -0700 Message-ID: <20260827160806.1295313-3-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-GUID: y5EpcPZG9ekUUFOpEDfnGnlm1sGNOOU6 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX+N57czW2ptAw qt+0NGlePAESsXVtVbYeGWpzXhvDI+7g2w+1FqGWhUWJ728eCIJIimVHKbshzMwYhQN1Qmwxvl/ xArDn3XNMiCF8OsIKyJvWNL9ahSheTc= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX4Ca1+O1o4/ME 4YSCf8YS+0CAr3XGU93GK/7v+kPZ5gKSCV/PlI7A8WJqCV47zVCxz8rx2o6kLFgx7XEYb6FCKR5 W0oF5SA7Dwe0s9dtxYhz8CEmSTcebhT3o3qEoJQLo4sRpDCqxr6WQmC8wVhkIAOCmkadgiQnFhw 8bZLC92xU7+AjPCzUc0YzsKqFFgKi5OaZcEdtHL/JTYdb/YHmbzIpPkoTlU8HM9hB1++SQH5I68 6r3Yz5Q0UQAR+LBcCgcy4eVLdgov0xpNRmaYYuCnixqsnF+IL4JTXmsByEBFDOCXkZ+CvI0YrU8 U9NwOjuMS/BVc7Jfymn8daCNW9L9VSMQWEFMKyFUYMjOYufFcIyUP/QXn1uBr2CaITJLlVTGyL2 2pETFXyP9w4TIlcbKLx5kdMv9hZHepJhH0NRcuOhKDbpQ79BSRKxrJkidYKISTIgCu64KTA7J7k e5eg+0C0AzRmXCj2CLQ== X-Proofpoint-ORIG-GUID: y5EpcPZG9ekUUFOpEDfnGnlm1sGNOOU6 X-Authority-Analysis: v=2.4 cv=E8b9Y6dl c=1 sm=1 tr=0 ts=6a9060fc cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=EqLUM-vDyOCcG5bjvusA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 spamscore=0 adultscore=0 phishscore=0 clxscore=1015 priorityscore=1501 impostorscore=0 malwarescore=0 bulkscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan In a Qualcomm GVM environment the ICE hardware is controlled by the host, GVM has no direct access to it. So, key operation in GVM is done through SCM calls rather than direct register access. In this way the access to ICE registers are offloaded to Trust Zone. Add QCOM_CRYPTO_VIRT, which implements struct virtblk_crypto_variant_ops for the virtio_blk_crypto_ext dispatch layer. It maps keyslot program/evict to qcom_scm_ice_set_key() and qcom_scm_ice_invalidate_key(), and software-secret derivation to qcom_scm_derive_sw_secret(). Signed-off-by: linlzhan --- drivers/soc/qcom/Kconfig | 12 +++++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/crypto_virt.c | 89 ++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 drivers/soc/qcom/crypto_virt.c diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 2b524154d9fb..6c632d114d45 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -298,6 +298,18 @@ config QCOM_INLINE_CRYPTO_ENGINE tristate select QCOM_SCM =20 +config QCOM_CRYPTO_VIRT + tristate "Qualcomm Technologies, Inc. Crypto Virt driver" + depends on VIRTBLK_CRYPTO_VIRTUALIZATION + depends on QCOM_SCM + default VIRTBLK_CRYPTO_VIRTUALIZATION if ARCH_QCOM + help + GVM-side hardware-wrapped-key SCM operations exposed to + virtio_blk's inline crypto layer: per-slot key programming and + eviction, and key derive/generate/prepare/import. + Say Y here to compile the driver as a part of kernel or M to compile + as a module. + config QCOM_KRYO_L2_ACCESSORS bool depends on ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 798643be3590..6d4b7546d1fb 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -39,5 +39,6 @@ obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=3D kryo-l2-accesso= rs.o obj-$(CONFIG_QCOM_ICC_BWMON) +=3D icc-bwmon.o qcom_ice-objs +=3D ice.o obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE) +=3D qcom_ice.o +obj-$(CONFIG_QCOM_CRYPTO_VIRT) +=3D crypto_virt.o obj-$(CONFIG_QCOM_PBS) +=3D qcom-pbs.o obj-$(CONFIG_QCOM_UBWC_CONFIG) +=3D ubwc_config.o diff --git a/drivers/soc/qcom/crypto_virt.c b/drivers/soc/qcom/crypto_virt.c new file mode 100644 index 000000000000..4ee2a36af6c1 --- /dev/null +++ b/drivers/soc/qcom/crypto_virt.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include + +static int crypto_virt_program_key(const struct blk_crypto_key *key, + unsigned int slot) +{ + u32 dus_512_units; + int ret; + + if (!key || !key->size) { + pr_err("%s: invalid key\n", __func__); + return -EINVAL; + } + + /* Only AES-256-XTS has been tested so far. */ + if (key->crypto_cfg.crypto_mode !=3D + BLK_ENCRYPTION_MODE_AES_256_XTS) { + pr_err_ratelimited("Unsupported crypto mode: %d\n", + key->crypto_cfg.crypto_mode); + return -EINVAL; + } + + /* qcom_scm_ice_set_key()'s data_unit_size is expressed in 512-byte units= */ + dus_512_units =3D key->crypto_cfg.data_unit_size / 512; + + ret =3D qcom_scm_ice_set_key(slot, key->bytes, key->size, + QCOM_SCM_ICE_CIPHER_AES_256_XTS, dus_512_units); + if (ret) + pr_err("%s: slot=3D%u ret=3D%d\n", __func__, slot, ret); + + return ret; +} + +static int crypto_virt_invalidate_key(unsigned int slot) +{ + int ret; + + ret =3D qcom_scm_ice_invalidate_key(slot); + if (ret) + pr_err("%s: slot=3D%u ret=3D%d\n", __func__, slot, ret); + + return ret; +} + +static int crypto_virt_derive_sw_secret_key(const u8 *eph_key, size_t eph_= key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + int ret; + + ret =3D qcom_scm_derive_sw_secret(eph_key, eph_key_size, + sw_secret, BLK_CRYPTO_SW_SECRET_SIZE); + if (ret =3D=3D -EIO || ret =3D=3D -EINVAL) + ret =3D -EBADMSG; /* probably invalid key */ + + if (ret) + pr_err("%s: ret=3D%d\n", __func__, ret); + + return ret; +} + +static struct virtblk_crypto_variant_ops virtblk_crypto_qcom_vops =3D { + .owner =3D THIS_MODULE, + .program_key =3D crypto_virt_program_key, + .evict_key =3D crypto_virt_invalidate_key, + .derive_sw_secret_key =3D crypto_virt_derive_sw_secret_key, +}; + +static int __init crypto_virt_init(void) +{ + virtblk_set_crypto_ops(&virtblk_crypto_qcom_vops); + return 0; +} +module_init(crypto_virt_init); + +#if IS_MODULE(CONFIG_QCOM_CRYPTO_VIRT) +static void __exit crypto_virt_exit(void) +{ + virtblk_set_crypto_ops(NULL); +} +module_exit(crypto_virt_exit); +#endif + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Crypto Virt Driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 0310E486E6D for ; Thu, 27 Aug 2026 16:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846912; cv=none; b=DmnImrjP91QJnEsOXqL3MvSUtzild9Jon6XB+zSv0QOcgN+cxGo+cXvPOiroJJtxFx6dqT0rnF1FPALdGcOEKlaHNlFYIOKEh71ZcbvJfi7IPmnlXtZ6ND1RKwJgiAuu4DLppCNw0v71bqMmVUQvX2HrEeK2DkYVS5fhlHvqs9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846912; c=relaxed/simple; bh=W2FvuC3UAMWOvDf9d7cUr0bHheIKwhtwrVu5Kd4enps=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g4HfvRNC/mA3+5CLLomYRlPM+ruSYCgCfLzAyfD+7adGkpjxIFC2dKj/QCc7LnnPEKSODK3f4uFYwHQFli54TyV5AQuvDE1K1FeLgmmNNbBnt8DG3rkRQTiq3JI6bD4fojNUEOwxcxm75R3xZX+2xWqD32+pn0bWf0fZ3zvdsag= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=pK/1FkFp; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=BAmmouGA; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="pK/1FkFp"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="BAmmouGA" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFbl733829511 for ; Thu, 27 Aug 2026 16:08:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=KYyeQjUxEAJ V0K1tV20w0mqSZ8OSewiwvX20cAVBov8=; b=pK/1FkFp/YuVrQVZ3XV5JhZC54Y VJvgzkEADr4QJ4o/F1WaTg/G9xHOXw7cAPPNP9sAfoGq8wz0Yeq0zt5NEZU/Q40d MSZpXTskA70VTf+iqB6i8ze8y7hxAg98ofTQdT8w6q+Q9kdusm9E5jLTX+2GvizK QT4iNEvcCUJRHXiQ4revxxbQAZi6cU7DKuN3WSeDMVRl3hGAumLIDDTi0bXu4cSp aUxqOVwXrAOvIiJ/SrRbGTv2gqRuJ811PGjoQYUjC8dIuKB1qyHRTOr+i0n+vqjL Rw5rOo3ftrwiNFXktzxQqK7ojYT9N3eaKD2s7P1foMYvsDI+6GwTMHW2VOg== Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4game7s58u-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:28 +0000 (GMT) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-395543dc382so138823a91.0 for ; Thu, 27 Aug 2026 09:08:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846908; x=1788451708; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=KYyeQjUxEAJV0K1tV20w0mqSZ8OSewiwvX20cAVBov8=; b=BAmmouGAiJWXU1rJ72GBkEmND6IwxL6+kSZ9IpkL8aP1wSonQLAiG8PR5xLmzIVgn/ YCQRcRJA7k4Iyj/vsDQnffHWRfub2vs+L82SBooFYaNm37qEjJCKxWKDCXlPXFngGL+h EzR74rOdg88WpvsF2nP9Vpuv1O+XBOhYfD5f9iohVFWbxhRNgrBJ8xuY18MDvw/TRh+U Dq8v1xv5ytqK82y8baMK/h3I2dHksVuRxTY8U/kg8FU6hEd3ufbBmDCW96LG3BZxUh2u SUWbPaHZMmJHH40zh20f0TwygLbLy3xMW2gJ6TR7okQPgw/A+D2wq/mJ4o1xnMogbwPu tKJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846908; x=1788451708; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=KYyeQjUxEAJV0K1tV20w0mqSZ8OSewiwvX20cAVBov8=; b=M+k/mMCiXMOxcM4DChzjXJyggjoednElRPX+2Riu3MGCDkRt4z0cbXTSJAbpZF4oeJ YQA7JelpWsO0ZUq9WV70nEercLLlX3J97CFcGJldcOJhHzgJVhNbskFX3tiHRbPBkmNI X5eAI0aWcG5pp2QJoR766c3RsPIlOhXBxDoFLUJGsuEFYczue+FKKjA3rEQ/B5IWtWp0 om+/tuZiSLlXI1zCAnDRAmzNGedIBihCWvB51IyqY3K6KV+4Hw/fo3bDXwJ7llHSXL7g cB3cavCubER7h0lQZKNZr55GM8nby8njhUHb3ipRSuYvCyF7an8I7aP9gB6Wp2kFB4NQ lrog== X-Forwarded-Encrypted: i=1; AHgh+RpIW9aAfwUUX6K/6yMRmtrs0kM2Jbm+phzJrLCpuJzYeQBFfI6NHGiO3SWJV1Sd9KlyQTlj/osMkwAQ9TQ=@vger.kernel.org X-Gm-Message-State: AFuF++mKSDyU3ui8V4XKNYfEbq6H8i330dKdeyzwwES+4gX+oSTQ06rY O/MrSOPODZKqSCRD9Pf00aW32JkzWsbuZJFe82Vv8GOZah0kW3EPvCyFqQGbvLeUuqjeNDHxw5u zzyVbkWTSZpID2EPAHrtw9mcccvDoc5CRHDbDq1MSMTP1dHBMz8MDkwn94upwV0ncbTA= X-Gm-Gg: AR+sD10CRKwerRGPGuIrBdzuEO2q8ILYcogy5fzEuoBnm9p/RQMdGZCg+ho8Ab/O3Hj 6UAE0o0B15oNFojRyq2BiPUR0tSn0g9yltlGWx0lQ9NWoneRGP4ULnffAA+AoB7fH6ANLolpKMn Wnr08VrXflAbXohtO0p0+qxGpV7Q5T36y/VTS5K8w0FUS4F446rPoBbNud0ucLESzqfTr4LlIsH X3l4Knv9fDs3jvdpa5+xZXChRVokIqsFb2G4d5sKEcqpfttN6Nkrk7tpCrZ9ZFTxwGclwiooNAy STAJaHVTYDozlQ5/PmfO6OlCmh/6HN/uw0Ok2M4zAvrO3fRG01JWV7rt8EIWiJ+YCytxyJ5ISkH K1Qnkba/1SQDfyUgHqo0EJUt3/reRq3DQODNJ8ZMg4hp4PYm8nC6UNjqi2b8= X-Received: by 2002:a17:90a:e710:b0:37f:fb1d:63fa with SMTP id 98e67ed59e1d1-396d0fe0d0dmr523870a91.15.1787846907726; Thu, 27 Aug 2026 09:08:27 -0700 (PDT) X-Received: by 2002:a17:90a:e710:b0:37f:fb1d:63fa with SMTP id 98e67ed59e1d1-396d0fe0d0dmr523654a91.15.1787846907116; Thu, 27 Aug 2026 09:08:27 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:26 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 03/11] soc: qcom: crypto_virt: add support for create, prepare and import keys Date: Thu, 27 Aug 2026 09:07:12 -0700 Message-ID: <20260827160806.1295313-4-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX2lu/LDLYruOG UVfKIFY3QBs3MdgX1PF1MB5eiBpCFhSHNIQFk5ZxSksAUEEfImQWSQqxtekkOew9k2Z9XfczUpU 10LgCufKW/5xD49GGwYv1FfHQ7JHk/h+0j27pDSBOjPX03AvrWRk1Q3ITwEwMyMNYC5eDpTSfy1 I2xgK7nlanseY08JARenyYw1pwmfTKGnBoZIsuPkGXdk9yMC2hDoATxTkOydCiIZXXi2hmgLjBW W4y17NWC3jiSc5CD/hMuAtef9vQKVf0ZdA87z2CJa7t1tvri72I+h48xQJ9pttIwwHIhwtTfefZ VtnICTVRfVYvNAYMp0FMdJdDVs23UHMG+IfMI/TH6hAFFvFYQaR6r6iWwGaOoFvxO6ZIPup2ky1 L9uR/5+g+b2Nn9WG5nxU+v3tpOs5xgJ8hhR7+BzULCTuN9Mu7WOjEd1mGL7MmMiwCcDZnhDQdSa /4WqFNhB2oFHV/PsEdg== X-Proofpoint-GUID: 7PsXMuhDv5WyVa_pLSnoxzBDeTezlF_Y X-Authority-Analysis: v=2.4 cv=Yrc/gYYX c=1 sm=1 tr=0 ts=6a9060fc cx=c_pps a=vVfyC5vLCtgYJKYeQD43oA==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=KUJ1cKNvbcR4PWbS2kkA:9 a=rl5im9kqc5Lf4LNbBjHf:22 X-Proofpoint-ORIG-GUID: 7PsXMuhDv5WyVa_pLSnoxzBDeTezlF_Y X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX//oUybNkYaSW 8tQMuKsuaGhKJZjiK/1JMHzSYa+Nikg+7feJ1VGf875gjfoKj6IQjHWIazMbAVpoCxOqoEHuB0c Mbt87zzQ5/6NxkxjYacUMuWVRRsq8CY= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 clxscore=1015 spamscore=0 priorityscore=1501 adultscore=0 impostorscore=0 bulkscore=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan The SCM interfaces used to generate, prepare and import hardware wrapped keys require the exact wrapped key size as input. The size is ICE hardware specific and cannot be derived by the guest. Since the guest does not have direct access to the ICE hardware and the information is not exposed through virtio, obtain the wrapped key size from the "wrapped-key-size" DT property. Convert the driver to a platform_driver matching "qcom,crypto-virt" and initialize the wrapped-key operations during probe. When a valid wrapped key size is provided, enable the SCM based wrapped-key helpers: generate_key -> qcom_scm_generate_ice_key() prepare_key -> qcom_scm_prepare_ice_key() import_key -> qcom_scm_import_ice_key() If the property is missing or invalid, the driver still probes successfully. In that case, only wrapped-key generation, preparation and import are unavailable, while key programming and eviction continue to work for keys provisioned through other mechanisms. Signed-off-by: linlzhan --- drivers/soc/qcom/crypto_virt.c | 114 ++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/crypto_virt.c b/drivers/soc/qcom/crypto_virt.c index 4ee2a36af6c1..93c7993fb4a5 100644 --- a/drivers/soc/qcom/crypto_virt.c +++ b/drivers/soc/qcom/crypto_virt.c @@ -1,11 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only =20 #include +#include +#include #include #include #include #include =20 +static unsigned int g_wrapped_key_size; + static int crypto_virt_program_key(const struct blk_crypto_key *key, unsigned int slot) { @@ -17,7 +21,7 @@ static int crypto_virt_program_key(const struct blk_crypt= o_key *key, return -EINVAL; } =20 - /* Only AES-256-XTS has been tested so far. */ + /* Only AES-256-XTS is supported so far. */ if (key->crypto_cfg.crypto_mode !=3D BLK_ENCRYPTION_MODE_AES_256_XTS) { pr_err_ratelimited("Unsupported crypto mode: %d\n", @@ -63,24 +67,128 @@ static int crypto_virt_derive_sw_secret_key(const u8 *= eph_key, size_t eph_key_si return ret; } =20 +static int crypto_virt_generate_key(u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KE= Y_SIZE]) +{ + int ret; + + if (!g_wrapped_key_size) { + pr_err("%s: no expected wrapped key size\n", __func__); + return -EINVAL; + } + + ret =3D qcom_scm_generate_ice_key(lt_key, g_wrapped_key_size); + if (ret) { + pr_err("%s: generate hardware wrapped key failed: %d\n", __func__, ret); + return ret; + } + + return g_wrapped_key_size; +} + +static int crypto_virt_prepare_key(const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + int ret; + + if (!g_wrapped_key_size) { + pr_err("%s: no expected wrapped key size\n", __func__); + return -EINVAL; + } + + ret =3D qcom_scm_prepare_ice_key(lt_key, lt_key_size, + eph_key, g_wrapped_key_size); + if (ret =3D=3D -EIO || ret =3D=3D -EINVAL) + ret =3D -EBADMSG; /* probably invalid key */ + + if (ret) { + pr_err("%s: prepare hardware wrapped key failed: %d\n", __func__, ret); + return ret; + } + + return g_wrapped_key_size; +} + +static int crypto_virt_import_key(const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + int ret; + + if (!g_wrapped_key_size) { + pr_err("%s: no expected wrapped key size\n", __func__); + return -EINVAL; + } + + ret =3D qcom_scm_import_ice_key(raw_key, raw_key_size, + lt_key, g_wrapped_key_size); + if (ret) { + pr_err("%s: import hardware wrapped key failed: %d\n", __func__, ret); + return ret; + } + + return g_wrapped_key_size; +} + static struct virtblk_crypto_variant_ops virtblk_crypto_qcom_vops =3D { .owner =3D THIS_MODULE, .program_key =3D crypto_virt_program_key, .evict_key =3D crypto_virt_invalidate_key, .derive_sw_secret_key =3D crypto_virt_derive_sw_secret_key, + .generate_key =3D crypto_virt_generate_key, + .prepare_key =3D crypto_virt_prepare_key, + .import_key =3D crypto_virt_import_key, }; =20 -static int __init crypto_virt_init(void) +static int crypto_virt_probe(struct platform_device *pdev) { + int ret; + + ret =3D of_property_read_u32(pdev->dev.of_node, "qcom,wrapped-key-size", + &g_wrapped_key_size); + if (ret) + dev_warn(&pdev->dev, "qcom,wrapped-key-size not found\n"); + + if (!g_wrapped_key_size || + g_wrapped_key_size > BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE) { + dev_err(&pdev->dev, + "invalid qcom,wrapped-key-size %u, won't support generate/import/prepar= e hardware wrapped key\n", + g_wrapped_key_size); + g_wrapped_key_size =3D 0; + } + virtblk_set_crypto_ops(&virtblk_crypto_qcom_vops); return 0; } + +static void crypto_virt_remove(struct platform_device *pdev) +{ + virtblk_set_crypto_ops(NULL); +} + +static const struct of_device_id crypto_virt_of_match[] =3D { + { .compatible =3D "qcom,crypto-virt" }, + { } +}; +MODULE_DEVICE_TABLE(of, crypto_virt_of_match); + +static struct platform_driver crypto_virt_driver =3D { + .probe =3D crypto_virt_probe, + .remove =3D crypto_virt_remove, + .driver =3D { + .name =3D "crypto_virt", + .of_match_table =3D crypto_virt_of_match, + }, +}; + +static int __init crypto_virt_init(void) +{ + return platform_driver_register(&crypto_virt_driver); +} module_init(crypto_virt_init); =20 #if IS_MODULE(CONFIG_QCOM_CRYPTO_VIRT) static void __exit crypto_virt_exit(void) { - virtblk_set_crypto_ops(NULL); + platform_driver_unregister(&crypto_virt_driver); } module_exit(crypto_virt_exit); #endif --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 ABF7448BD29 for ; Thu, 27 Aug 2026 16:08:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846915; cv=none; b=YS3DezhH7kbBqMqzigFLqOjVyLQzk5C9t/FTUQi6GPuuK/H36f/vuMA8OG1MUZzzbHKOCiVohK2iT0s5rAbA/hRDjmSQnV6+h5zzOpWEr0VFJQFja+FLSd6890BWlBv1cuehF2VxXoxNcco45WeyAHaqlewKiuy++2m2h4nAyKo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846915; c=relaxed/simple; bh=Ro1Tw7bimijLX+zSbVZzcIcnTuF4NWioN9yBfIv7fvA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d7b+11/ryVncGVgjo4sbBVpNPfVLgcH7JcahvdvpRafzoDlCrvJrQ7JJLe7WdFsvF/33UVuiFYYdiXOcE69LtPW/KZMiz/+Hh+2dz76zcvP9PgG22yThJOgC+dp/wI1BuJPUKP2X9QTTR3R+ycPqpUK2fbXeQTdDCOBJ0gQPWrU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=c2BXcxZ5; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=KGVbwW77; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="c2BXcxZ5"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="KGVbwW77" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFcmxJ359178 for ; Thu, 27 Aug 2026 16:08:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=szEkNwgY771 Xv6m8T3J/mh1f/ayBeeTB35yTWk5lZdE=; b=c2BXcxZ5dH6V7p/j2Ymmx/kbwuk 5ypm5J+Gy/Xe/Rzmh16ripn5C4xaaNvcWhKVxilUrwSyL8ZaX1EONIWOJxKjHI6C 9r8+zMkdIft7vyYF67XPAqAb/fze38RxCGxangfO7+n4KFZc/us+ZyuwC1j8Pr3q nXuWhE9t3ykQ9oKvWijc/LsP+z+xEZF0jnxEn6d6IoUsbP/bqvHFOuCzr7iOGEzf VCs/kF+aS58KXOsQVJPfBiAwXVM6ag2XRg296GLNCNw+hk8XAYYcFSzNfjV+8JVZ KwOz7DPYZ1w7iq4y7PTnCS311Urm9TKF4Q9jj4hYpivdxTMopVBqWIF3hQQ== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ganr68r1x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:31 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-3965ba1ba3eso122469a91.2 for ; Thu, 27 Aug 2026 09:08:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846911; x=1788451711; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=szEkNwgY771Xv6m8T3J/mh1f/ayBeeTB35yTWk5lZdE=; b=KGVbwW77Rzan9Z3Mih582giN4wv0ZFRi0j9yXemCvfqWrD5Tb/6cKsbyLDVholvC2I tZuBtfN8lDvN2hXhOXJiPtJBNmVlb0v0P4hKl85Sg508FDQYBQrzu6dqVn8giK9hiBKE h0znI+S/YUy00THiPfJIK9CMXwcZkpuhcTB2kRMZA/KdeCUQm8XQGOTflYbaai/SnYRg cCkWEn9mHJK5RQOXaSqh8KqTIJRAy0ooGFrvC8vRNcXzgj1rAFZ6C0P7oFdGRVVo51// bNRMOL0ny0cLHIO8CHWVJL9bRu7gE831CNRCmV99smR8L8vSnO3A03gp0tWcX2ev3gYm wyew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846911; x=1788451711; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=szEkNwgY771Xv6m8T3J/mh1f/ayBeeTB35yTWk5lZdE=; b=KPkcEQdq3dfAz3yurNNLareh133MuScaywsrH7D5Cu/2fU3nrnNmaERjB5Ub1hkKjD gVrm9sYOwZcxcKq+Ay1OEOiTXTTmThRbGZJZoljh3C7euJCwhl0Fk8Ct9iyEMnZjFu2Q 4GyMif4rH8wNBiuAKOPGBFjbgHEY7QC1bAKPDhgcc1ruf1JY1+GNyKZldDwiFF8/+K4S 6lQk1c5BlCrw9VtsJXFj11y8uo1+QsDU7TX9EwJv6Kv3vZQOa9Xwa2r43gT8dH9e8N9E bpay5XTAW6zcOhoteZwawWN6W8h4gzVjKGhEB+tveOAmGoJPvXN9Hzff6uj1lYtnfFV5 sUEQ== X-Forwarded-Encrypted: i=1; AHgh+RqQE83DHb/Qv+p8ay9SIfjmxMBo+Gu8dhA+IB/PlcP0A/YBgDR4tvPUgCMMj2qHe5qTMEwhHWwkx87x2DY=@vger.kernel.org X-Gm-Message-State: AFuF++lqZ3ALC92/RAtsweIIe4RlIj3abS6JF/WsKEhDDvj1lRsl3W7H 0kE0I9JGw7qC7JmCHFUHFGNwYshH3rLEmvkE97Kelzttv7fllYT6skMiwRvVzhHrNmf//KAILke OFr2912Xp+lQIYGd1uB0PobsYwRWODd1mBC490Wgyq4U3jy40RTXKiyQM3K63LYL9SDc= X-Gm-Gg: AR+sD11GCepab9whibOpmXlWUVncvKJEzTYhiZLiCLICoSet3A+vaAdwlftwLGu6xxn ZjpNIF3hZdpuH6ryEyowPLyEYNwxsxZ8V7trms2w1NEF+4IG6iIi45RtN1/JSDaqFEShvB2O01Q 6gSPKVv8dipS8/+UQOs1mD/fxCJIOZy3D6he1+taINeKM0k8skxsUhKAkOtfcOkb17xJ+oH5n4g ohP42armYlrQvkFUHz8RO6EyC4Le0CG4F3r8BJLWpYuVFoSvC9LeO9Qc78OPDxAZD/3nCRL7qeg o6gGOxsPJHPOt4EBzYVUteuDC6woF3iLzEGlpnopivIw3iF7T4K2cScFK/7ouYlXxln14GRDugB Pj6jRdZ35RzJkQ4GWLiMxW/UODUkcuVfh5jl7K3blZV0k2uW6MPwfDjehxBk= X-Received: by 2002:a17:90b:3c47:b0:38d:f5bb:e0f4 with SMTP id 98e67ed59e1d1-396d0e27e11mr634861a91.1.1787846910209; Thu, 27 Aug 2026 09:08:30 -0700 (PDT) X-Received: by 2002:a17:90b:3c47:b0:38d:f5bb:e0f4 with SMTP id 98e67ed59e1d1-396d0e27e11mr634645a91.1.1787846909524; Thu, 27 Aug 2026 09:08:29 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:29 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 04/11] dt-bindings: soc: qcom: add binding for qcom,crypto-virt Date: Thu, 27 Aug 2026 09:07:13 -0700 Message-ID: <20260827160806.1295313-5-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX3l13Mdy7o75V BUksQPO/PTiG5pfLiEk7gVqyeSxL4Ru946BrSLHXQnwwOqUMiFlCWyizUIgmO73z3AUmYb/WHDA rYWtVnUQAIEwrwCyls4Dmi/MCaUsZwqUiVYqQl/+ZzbO/W5+5VhnZ1s2RkTD/J3sNvVDyMdjBsG Cm0zm+PMIiZFp0ichHZapYMjqtlics2aP2Q4E0K7H6d8w3j7t7pNS8RPF4Le17pmjbWXTOEBsct aQ1uqapw1M0ccKrexBtupqOGSPCUbuoJxAC0rywqTEdYd9UMTZQsPnI6c5mKDWCcojFS30vPAW4 4bwRXbD/jZJ4QfHp6a0vnB+aDf3uz6WuvBAsODH9LFVJA59I7/6EQplNzqLwH/RfHiU9cViAVrg ng+DRtPz4K+ft1Rn4ZLbRo8R7aYIVfFgzcEUcBKgUxzK1Wuib4snrQVBOuf7/mjaujCYTOjVUC9 gstapXsFmUztftOxdkA== X-Authority-Analysis: v=2.4 cv=d5DFDxjE c=1 sm=1 tr=0 ts=6a9060ff cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=S71HXAmslS2k5ljwlz8A:9 a=uKXjsCUrEbL0IQVhDsJ9:22 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-GUID: Zf-9dRdEnv26F8hkUqwkNXRJuh_DGwej X-Proofpoint-ORIG-GUID: Zf-9dRdEnv26F8hkUqwkNXRJuh_DGwej X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX8Rkff7QjP1zN MICOelgGMaCoDSB0MgtdxmSMOa6IZ7DvzbJoF4Wii1ajYrk6R36oEVDW2tXIYd5TsDjWySiuDPK 9AYsW7nnSmnx8JNoKdu3bL5TgD1iWNU= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 malwarescore=0 lowpriorityscore=0 impostorscore=0 clxscore=1011 priorityscore=1501 spamscore=0 adultscore=0 suspectscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan Document the device tree binding for the Qualcomm GVM crypto-virt node, which provides the wrapped-key buffer size needed by the QCOM_CRYPTO_VIRT driver to perform hardware-wrapped-key SCM operations backing virtio_blk's inline crypto layer. The host does not report this size over virtio, so it is supplied via DT through the optional qcom,wrapped-key-size property. Signed-off-by: linlzhan --- .../bindings/soc/qcom/qcom,crypto-virt.yaml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,crypto-= virt.yaml diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,crypto-virt.ya= ml b/Documentation/devicetree/bindings/soc/qcom/qcom,crypto-virt.yaml new file mode 100644 index 000000000000..5eb204f29762 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,crypto-virt.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/qcom/qcom,crypto-virt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: QCOM GVM Crypto Virt driver + +description: | + GVM-side hardware-wrapped-key SCM operations backing virtio_blk's inline + crypto layer. The host does not report a wrapped key size over virtio, so + it is provided here instead. + +maintainers: + - Linlin Zhang + +properties: + compatible: + const: qcom,crypto-virt + + qcom,wrapped-key-size: + description: | + Size, in bytes, of the hardware-wrapped key generated/prepared/impor= ted + via SCM calls. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 64 + maximum: 128 + +required: + - compatible + +additionalProperties: false + +examples: + - | + crypto_virt { + compatible =3D "qcom,crypto-virt"; + qcom,wrapped-key-size =3D <100>; + }; --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 A270B48C8CD for ; Thu, 27 Aug 2026 16:08:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846917; cv=none; b=A2OGQqs85kShe95FD2UxsFV5QE7oR5fLdFEvWjY3bT+zGwhZQ7kkc5sBiAC7ScGIlbtM17aQHWHIcG7E8qvYlIPeDrtirGhF3QdZrLaoVuQB3qZUZvdQ+okfgh7FUdyut7WZF+fAVBXmAyYz4bsvTorDYJgaawQfJ2w6XfDgNVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846917; c=relaxed/simple; bh=oSgJwGLxnmoFdZg1kjVbiBRTTxyJZh2fbQVmNPq59Ts=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qF+My8PDlsA93ECZtwF71jMDpiwXIwU0RqITMRmtC0rsMJnT7QY/nDcxm2pDXDGilI32gfX4rYD7iMozLcbl6ktR3a1j6XZ1DfQsxWt1I15uqpa+kgnaCdiZIA5H/lk8l/y5LOxLyqjeEyuW7DhwIxiXBMZIhHCaf++nCoo455I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=AK9S4frc; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=LTMfGyY/; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="AK9S4frc"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="LTMfGyY/" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFc1At164324 for ; Thu, 27 Aug 2026 16:08:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=jGZdyNVRoPn uELHhGohR0kdLBQlQJfa6SSwFJk/s1LQ=; b=AK9S4frci4VDxG5fjZmeGLlcArg 21kvuLV7nGYyMKq2nOsG1bclVR3sNLOSNIEQoH0liMGj1xNKjBIg91nFoPQqrsNH KSp/ldhVpnxCIZKoY+0njofJOZeeyTOqkuLa6mn28tUkr1HvzMXI23XbLYRLQfjz caEJ1wsxuhTTMP7Ycxf14SibStJWAa/FvFp2M2Nar4Dii40yWq5A6+3zcK6e4zC6 AGeUEPvemGNe+EaQO5RixKWWdz9MFahfjgDnjYrkUq6YNB2wg5w35k8tGBs9X0SG JAFl7zAbMBRYCqncKCK1tQ6dKItBof2hAGj5wVLKfP2jnTaJq3yD6EI60Gg== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gagjft3d0-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:33 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-39512608fb1so149628a91.1 for ; Thu, 27 Aug 2026 09:08:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846912; x=1788451712; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=jGZdyNVRoPnuELHhGohR0kdLBQlQJfa6SSwFJk/s1LQ=; b=LTMfGyY/yicjQ79NOzaXtxqHg9qybxyxXqkFqK9c16CDguYZPzB5uun9b1b0tXTqig aNLH+5C1Ni9u5ZrLd5qzgfKekniyEkobYCLTIfAfX6vdeF2ON/YVtwZtlHrYBR0iT0FG JDO/eEy/uez2O9Pr4yQOPyrvJa8Zv+SgQPVgDMXzLy/S0iqviYkzlS8tJ9Zse2EVQGzd Nu74T1exIGGE2xAT6F3WgbDT0ZYcmzcfZrVRzeYe1UkpsSU5dlT0GPzhZoU11zZJl4GJ 7TJhJJRyuSkKcUoA0Eitmt+Xxq0mpS5Ytn2lJytPqKoSstN09lAzWtOAFyr7V+6oNA1G 2b6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846912; x=1788451712; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=jGZdyNVRoPnuELHhGohR0kdLBQlQJfa6SSwFJk/s1LQ=; b=s3V/RdGyfsIOYy7D0MaaHfMMNilKRnGvCLToWNqGJ04xEShwTwaGinaH97wwsaihD3 4e6O1xyNfI2QtAhcS+x4JObabcjlELtBynd5Q7bHPGqSQSZOfgBO8XdScnBKKd61W6Xx Ms5crfktVZGIKeD+V1RByxlrBmMZiqxzroYmboHllsg+Ckv0PKMtJQv+yvzg8X3EyNT4 f4wqq5V+n10SaPiqBQWEkT+h7hZj16boOtEGLqIpMcxw3QUHwAoYYjudwiLM8VrWb/P1 MeoeDqSoHeqTpqkOLCfeqIQjNZfAvPQUVI94ofDRDo6ipEkytHa4RQfnMFEnKtAkbdkW 4WSg== X-Forwarded-Encrypted: i=1; AHgh+RrnuuJcsPpVDx272otkfIWf50ZGABKgqsMXIqO+OwLqMSRoqHlC+UHzt3/7Qgq8msI4K5scU3JWA3BBMXs=@vger.kernel.org X-Gm-Message-State: AFuF++llUmdYeXABTmqvjyLnrdtqMkz+BwNvjJcceBWoGdfy+XzHVwqf nb1YQXnlHWALZtkFmyVmUDfVFhVK/vqnUq2z/vzuc5Z6psnLnPJmuqvVYQG2vt5YYNz4MNipxUY /KEjh2lkejywhVoO+lylB0BrHtxQsV2SRTcBsv5jLm84KEh2+T0n+xTNUfEwkJGsRIKI= X-Gm-Gg: AR+sD10ZKqz1FsVTCsDoesi5FZmYSiX/ad26Ylzcy/ENJ9jJRsIdXjsw3b7p8dlc6Jn Bbh0hfvp03ep2+JEQ74JoR723Y9Z37e74SEY09RAoJ6fqJMEuxpI3/mAehuxxrz3B5xIVe/wZ1B HET/QrWYwf7HFydlVPozbvaQdbOL+M0dP6MyXmSFkOgh/AfS1Ea727FDKltDbWgVnesUGVl3c+S FXFYBCZDTUWxoW7NQY1fiT4DXnJiTh0Vf3IMTteyzMyhb4M60srjNK0btEnuHChx9dgcteh0NlG J7tBWyopc0hpi8sDBlt80aPFqwspJ+Dk9IVJU+W/HRtGvrSJ++B/XDnjAKmyJlsTEeJ1mvdWtNW TDie+55qCPcWj6i9yh2sbpU61uirnn4vJ5F93kRf4DbHPbETK3SeYB0u/nBQ= X-Received: by 2002:a17:90b:264c:b0:396:61f1:da5c with SMTP id 98e67ed59e1d1-396d0e86577mr565962a91.4.1787846912443; Thu, 27 Aug 2026 09:08:32 -0700 (PDT) X-Received: by 2002:a17:90b:264c:b0:396:61f1:da5c with SMTP id 98e67ed59e1d1-396d0e86577mr565806a91.4.1787846911952; Thu, 27 Aug 2026 09:08:31 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:31 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 05/11] blk-crypto: add slot-based inline encryption path Date: Thu, 27 Aug 2026 09:07:14 -0700 Message-ID: <20260827160806.1295313-6-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-ORIG-GUID: NqgiyZbJ6Q87vi54HJRr3LTiQGwQKcT_ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX774HqTspUZaA TbpGn8izYKYEzbFq4ftW9BlMIXef2fO5yrJ3XxdrXIGu3hyR7tB3NTFBMyP8/IlmO/1vXtEWL5r Lmo9wU2vd9s0WRvu8RQUT/ezb90pSfQVZvWRHmqVC6b6e2uC4drOavHIWdGRpwsNr4EKIQI+DTB K97cf91ejafX9dP9iIj2B7YFBdpAjM8w153IF7eqlR7ZZBnXSgs6UpWwLue11aUP/bivDsck36W opFv51VFIaIxaS/4atUJ9d6PWHbIR87B0X3WVgLWVFhpxBrgKnqrsW9WhZWF9o/kl/dHjbLKLG2 9T/jXZC/txP+gwSYmWeBm0p9PGJurqGl7I6TDpiphVZde58hzcjN9T52NHVyoaDFDfeTWDFmcRB Sje8SBQddror9hdKj6IYdePCCEV5V8w+wgxxzuI60AKNeEw0PW6MoWTTRswXLcDBEewLD1W9+BO H3phwFuXSNv7a8CDdWA== X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX/yYNvlhMiCgT RAReUiYqckqjOoNP/rZbAx9GovyIwpPVzXKl9ZVGdvnHB1r7Z5w/LCtg7i0kSVhtxR2TeCcjO5G GO04/olfBRMBuzoqRtrDefBQXVVijJ8= X-Proofpoint-GUID: NqgiyZbJ6Q87vi54HJRr3LTiQGwQKcT_ X-Authority-Analysis: v=2.4 cv=dd+wG3Xe c=1 sm=1 tr=0 ts=6a906101 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=0coNgh9vqHAzk87cOx8A:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 clxscore=1015 bulkscore=0 adultscore=0 suspectscore=0 impostorscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan For the virtio-blk inline encryption use case, the guest kernel goes through the normal blk_crypto_key programming flow via SMC call in a virtual slot format before I/O starts. It then requests the host to handle that I/O with the key programmed into the corresponding physical keyslot. Introduce a "slot path" that lets a bio carry a pre-programmed physical ICE keyslot index rather than a blk_crypto_key pointer. Add struct blk_crypto_slot, containing the physical slot index (phy_slot) and data_unit_size_bits, and embed it in struct bio_crypt_ctx alongside the existing bc_key pointer. A NULL bc_key indicates the slot path. Provide bio_crypt_set_ctx_by_slot() as the caller-facing API for this path. Update the internal consumers of bio_crypt_ctx to handle both paths: - __bio_crypt_advance() and bio_crypt_dun_is_contiguous() use bc_slot.data_unit_size_bits to update the DUN when bc_key is NULL. - bio_crypt_ctx_compatible() compares phy_slot and data_unit_size_bits when bc_key is NULL, preserving request-merging for slot-based bios. - __blk_crypto_submit_bio() short-circuits for the slot path: if the device exposes a crypto_profile the bio is passed through as-is; otherwise it fails with BLK_STS_NOTSUPP. The software fallback is not attempted since the guest has no key material. - blk_crypto_rq_get_keyslot() skips kernel-side keyslot allocation when bc_key is NULL. There is no functional change to the existing key-based path. Signed-off-by: linlzhan --- block/blk-crypto-internal.h | 2 +- block/blk-crypto.c | 57 ++++++++++++++++++++++++++++++++++--- include/linux/blk-crypto.h | 25 ++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h index 2c7a0446572a..04035d237f03 100644 --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -176,7 +176,7 @@ static inline void bio_crypt_do_front_merge(struct requ= est *rq, blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq); static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq) { - if (blk_crypto_rq_is_encrypted(rq)) + if (blk_crypto_rq_is_encrypted(rq) && rq->crypt_ctx->bc_key) return __blk_crypto_rq_get_keyslot(rq); return BLK_STS_OK; } diff --git a/block/blk-crypto.c b/block/blk-crypto.c index bc3a9f59574b..2212d06d3c11 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -113,11 +113,31 @@ void bio_crypt_set_ctx(struct bio *bio, const struct = blk_crypto_key *key, =20 bc->bc_key =3D key; memcpy(bc->bc_dun, dun, sizeof(bc->bc_dun)); + memset(&bc->bc_slot, 0, sizeof(bc->bc_slot)); =20 bio->bi_crypt_context =3D bc; } EXPORT_SYMBOL_GPL(bio_crypt_set_ctx); =20 +void bio_crypt_set_ctx_by_slot(struct bio *bio, + const struct blk_crypto_slot *slot, + const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], + gfp_t gfp_mask) +{ + struct bio_crypt_ctx *bc; + + WARN_ON_ONCE(!(gfp_mask & __GFP_DIRECT_RECLAIM)); + + bc =3D mempool_alloc(bio_crypt_ctx_pool, gfp_mask); + + bc->bc_key =3D NULL; + bc->bc_slot =3D *slot; + memcpy(bc->bc_dun, dun, sizeof(bc->bc_dun)); + + bio->bi_crypt_context =3D bc; +} +EXPORT_SYMBOL_GPL(bio_crypt_set_ctx_by_slot); + void __bio_crypt_free_ctx(struct bio *bio) { mempool_free(bio->bi_crypt_context, bio_crypt_ctx_pool); @@ -156,8 +176,12 @@ void __bio_crypt_advance(struct bio *bio, unsigned int= bytes) { struct bio_crypt_ctx *bc =3D bio->bi_crypt_context; =20 - bio_crypt_dun_increment(bc->bc_dun, - bytes >> bc->bc_key->data_unit_size_bits); + if (bc->bc_key) + bio_crypt_dun_increment(bc->bc_dun, + bytes >> bc->bc_key->data_unit_size_bits); + else if (bc->bc_slot.data_unit_size_bits) + bio_crypt_dun_increment(bc->bc_dun, + bytes >> bc->bc_slot.data_unit_size_bits); } =20 /* @@ -169,7 +193,14 @@ bool bio_crypt_dun_is_contiguous(const struct bio_cryp= t_ctx *bc, const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]) { int i; - unsigned int carry =3D bytes >> bc->bc_key->data_unit_size_bits; + unsigned int carry; + + if (bc->bc_key) + carry =3D bytes >> bc->bc_key->data_unit_size_bits; + else if (bc->bc_slot.data_unit_size_bits) { + carry =3D bytes >> bc->bc_slot.data_unit_size_bits; + } else + return false; =20 for (i =3D 0; i < BLK_CRYPTO_DUN_ARRAY_SIZE; i++) { if (bc->bc_dun[i] + carry !=3D next_dun[i]) @@ -198,7 +229,12 @@ static bool bio_crypt_ctx_compatible(struct bio_crypt_= ctx *bc1, if (!bc1) return !bc2; =20 - return bc2 && bc1->bc_key =3D=3D bc2->bc_key; + if (bc1->bc_key) + return bc2 && bc1->bc_key =3D=3D bc2->bc_key; + else + return bc2 && !bc2->bc_key && + bc1->bc_slot.phy_slot =3D=3D bc2->bc_slot.phy_slot && + bc1->bc_slot.data_unit_size_bits =3D=3D bc2->bc_slot.data_unit_si= ze_bits; } =20 bool bio_crypt_rq_ctx_compatible(struct request *rq, struct bio *bio) @@ -260,6 +296,19 @@ bool __blk_crypto_submit_bio(struct bio *bio) return false; } =20 + if (!bc_key) { + /* + * Slot path: the ICE keyslot was pre-programmed by the + * hypervisor. The target device must natively support inline + * encryption; there is no fallback for slot-based crypto. + */ + if (!bdev_get_queue(bdev)->crypto_profile) { + bio_endio_status(bio, BLK_STS_NOTSUPP); + return false; + } + return true; + } + /* * If the device does not natively support the encryption context, try to= use * the fallback if available. diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 938ff536838c..33ae52b77522 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -119,9 +119,28 @@ struct blk_crypto_key { #define BLK_CRYPTO_MAX_IV_SIZE 32 #define BLK_CRYPTO_DUN_ARRAY_SIZE (BLK_CRYPTO_MAX_IV_SIZE / sizeof(u64)) =20 +/** + * struct blk_crypto_slot - physical slot context for slot-based inline cr= ypto + * @phy_slot: Physical ICE keyslot index (already resolved from = virt). + * @data_unit_size_bits: log2 of the encryption data unit size; used by + * __bio_crypt_advance() to increment the DUN correc= tly + * when a bio is split. 0 means unknown/unset. + * + * Used when a bio carries inline crypto context by physical slot index ra= ther + * than by a blk_crypto_key pointer (i.e. bc_key =3D=3D NULL in bio_crypt_= ctx). + * Set by crypto_vblk when building the bio for a GVM VIRTIO_BLK_T_CRYPTO_= IN/OUT + * request; left zeroed for all other bio types. + */ +struct blk_crypto_slot { + unsigned int phy_slot; + unsigned int data_unit_size_bits; +}; + /** * struct bio_crypt_ctx - an inline encryption context * @bc_key: the key, algorithm, and data unit size to use + * @bc_slot: physical slot + data_unit_size_bits for slot-based crypto + * (used when bc_key =3D=3D NULL) * @bc_dun: the data unit number (starting IV) to use * * A bio_crypt_ctx specifies that the contents of the bio will be encrypte= d (for @@ -130,6 +149,7 @@ struct blk_crypto_key { */ struct bio_crypt_ctx { const struct blk_crypto_key *bc_key; + struct blk_crypto_slot bc_slot; u64 bc_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; }; =20 @@ -152,6 +172,11 @@ void bio_crypt_set_ctx(struct bio *bio, const struct b= lk_crypto_key *key, const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], gfp_t gfp_mask); =20 +void bio_crypt_set_ctx_by_slot(struct bio *bio, + const struct blk_crypto_slot *slot, + const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], + gfp_t gfp_mask); + bool bio_crypt_dun_is_contiguous(const struct bio_crypt_ctx *bc, unsigned int bytes, const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]); --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 09DCB47D45D for ; Thu, 27 Aug 2026 16:08:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846919; cv=none; b=UYiS8y6vkF6H6QVpNzIm5uEOT2DWQpaXOK/huLQoutYApbnElVZQDzshca8gCMhoE6WwBX/lw1aQwa2OWBWeHbWI4cARMb9OnwxE7/kqM1wurMKaRMIvG4Sp/4O7qZtaBPFMZA1LuhqitTKpeT/CM9x8sz6bIum2qjxsTO31wYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846919; c=relaxed/simple; bh=64JBdKFV0k5ypJWDkUZi9BoAaRy3vj5flkXzPsq15+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ird4nLCscD52lwmQ9T9F5/IyCK6NWa/Zcd1TXLH8kh9ku/RlziPTuEhvDhwX0eK2AnGBZN3GT/jXWMzLnhGag3ln7OjcUDvSr5hHPTXIJzNhjg8zx1rQF0vIyTqbaozjANyVIjpdBkey50ba25CbYvNmLNAm4NM0no7kWMNT0vI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=pPF1CI7o; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=JYWDEmWH; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="pPF1CI7o"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="JYWDEmWH" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFcWMM3360499 for ; Thu, 27 Aug 2026 16:08:35 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=LltqfmvyZbe c4Bgt7eBZwrXubHQDa7pvwd5LerJQc3I=; b=pPF1CI7opY3gmcOEv1Jilno3v2i VEBF+as3yqfzBh2zg2eYzZiFmFnDo+X6GsLvOvU9SiT4WmrOfQn5cd5TmzH/Coad 26DWBpSBcoxynbm9jm2Z/6zxi16RlVDGJkDYtLkCqKJkef2JOLzhoE8jvzBmCxX+ yxe/HWSTuXXi0lIK8SXphg2qG4dGFy1XZFUoDhLHpVFklJbwQuUrGSVHC7uwxYIz mSKLBkCac+xDJ7N12ZlLJUt58yo7UZ28bF58nk5Jfit+2BHfwFaiMuEGZPNK931j zNMO0o/W/+OZ4keC04GduHPzR580l37NTVf/9210ndWufByfzcqn+ES0lDw== Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gab7t39ek-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:35 +0000 (GMT) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-38dbf293831so120931a91.3 for ; Thu, 27 Aug 2026 09:08:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846915; x=1788451715; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=LltqfmvyZbec4Bgt7eBZwrXubHQDa7pvwd5LerJQc3I=; b=JYWDEmWHlRL+Qb1Rcs+Av2z4Em6v1OOBCQm1HmzDhlrUlH5bIem6+U5WrYRWpSgy83 kinxNXz6o5vvMB4nhRjVrMcXXol14A3iywXqi/cE3cISBm1vCKZ5rOcPx0UcbvgchXvS REMvo2BwieN1CFBxO2x3Uq1tUxKm3eUfkHc47d8hXd3Jf/gqA15Z3Gqob0kPrf2lXFLO s9IPut1gD74U4Xjcr8S50H4haSUYTJTw+fjvHmJXIVtcxL+4t0fol8YAY2+BvskWvIv5 Jx+eyx0B0el7YuyUpgiDvIX0w0/hyRsdO3gUfLdEgOF9C0a5qbTHTDajsfjxy4ZcTE62 OQ0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846915; x=1788451715; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=LltqfmvyZbec4Bgt7eBZwrXubHQDa7pvwd5LerJQc3I=; b=XelNbKvH12Cr6cy3SvcW7IAb6j1ZpgPC2ekVBTu1lHsgJmG+0wMo6noMAJyWZfLFgy BBGXn46NdG+Pf/NWWjzV4DeML46QfPZB2KT79Ab1NOhf2jXvcIwwe33nNT5ilVcUoLOn gDgE/SyJHFgQa/ey3Jk+beq/t4SSxKnTWrzoyTljpjm2s6Sg1kfi+4euFen9HUMG8Muk xJyp5UnGRN8RL/4rXNrmGE361qsaA6hNYUOjw6SkoUxDMRcDRHMiz6MaBdyeHHAMs7nw 8JQ0t0FBigEa2G5bHpnv1slbgdlBc37cDEhwDuKCWTXwnA1wGeR2mYgNm/poUdbGnu6h L2QA== X-Forwarded-Encrypted: i=1; AHgh+RpJ2gJZH0QH9jCK5Cf5E6GZle4bbKjImd52Yozn+6oIApGs8nLpmOXPw9fFARU7eduQvgOT0vt9BxKk2HU=@vger.kernel.org X-Gm-Message-State: AFuF++mT0YXIbJhXO5m/ng8yIqqpjX4cHmZamusAMOHzQfhrn4DBTQFo 7eMVuIlAerXsDGZMR5XsdEpBikkXqSYY8WLLdkEx4+bOO2Nzt12TunUR3nOtNNUz4OAh4/fwYoi ImaU3oX1sfappvMNb56G4EMvQ+04gKbyA7DendmzGpXslpJLaBqz86DLn5G9xIoxbRzQ= X-Gm-Gg: AR+sD11WD7/gVvn7/qKsUTIoOE0BaCblKnaFoA45kWA85uZ31OPonfs2m9gZ9Rybf0K yKPxSJxkaC3cYmEnCnPDV3UHXZX8YN/VvsCdwt/4KvS6H90/en5Bj7NYUAdR8olk1j/2tkmt3MD jYBe9uXn6kgtEzBZGLzi4RgZrhjjf97jJRXZjOJ/UTEEJAdUfOL+YeubY/ZNkoVwGoXvvuyWzi/ Zl+ORD6gqjRH2+OVtOnvsr6DYwIJ0cVGqbx9zsiKyL0aOlo+q38B6zhSCRsuRH676MBYTxTZqB/ 4NH98HyfHmWg97oMuMGfVjWMOlLym8hR8JFxuLxI5ESSZHR5+DQfXHsucKKHZvaih7KVHWHJ54M 1E+etqu+woW/Xy9sH3zQOoWE0Z4NhODVrQKmertIlPYbe6JDga86ivXbiXSM= X-Received: by 2002:a17:90b:4fcc:b0:38d:ef48:b04 with SMTP id 98e67ed59e1d1-396d0f8fbfemr510639a91.10.1787846914820; Thu, 27 Aug 2026 09:08:34 -0700 (PDT) X-Received: by 2002:a17:90b:4fcc:b0:38d:ef48:b04 with SMTP id 98e67ed59e1d1-396d0f8fbfemr510461a91.10.1787846914243; Thu, 27 Aug 2026 09:08:34 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:33 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 06/11] scsi: ufs: core: add slot path to ufshcd_prepare_lrbp_crypto Date: Thu, 27 Aug 2026 09:07:15 -0700 Message-ID: <20260827160806.1295313-7-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Authority-Analysis: v=2.4 cv=X6Bi7mTe c=1 sm=1 tr=0 ts=6a906103 cx=c_pps a=vVfyC5vLCtgYJKYeQD43oA==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=UfCYJ6Unc3kZa_kcAOwA:9 a=rl5im9kqc5Lf4LNbBjHf:22 X-Proofpoint-ORIG-GUID: MF7r4x-aonq_fwWktsFP-ZkjQSsZUYcW X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX0k+IrrNZIQOY 2aytGk9acgesOnebozHyaGpNzHWN/ekWb+Gul5WLxNAaAvbus+QLBwb/VPe0jltmKpjOBY73iMG HFWakIFX02fcX5gKGBmI0qObEDlWrck= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfXxZznmLxMXhR8 8f5ZQiY6EWhZRd/z69Be/UjSBKnLn8mJnWcb+Atzs5J9+Al2BHQdo1tL1M2DwyP8PA+caOMsHs5 bVmiFbj18NVFYnzIO6bCMaKymlV49+d2ZjujGj/wDWKtQG73IlPYw4oWHzP34HwWGIvX0ZyscYx H19oyZy4U+G9UPLh90R1WHNUnjF0WNWEv1geHUrWh7Mq987AYxiaHv/2sfrjy8Wi/EuSwrzIRry HgWqMXLK+cxdATXH48j+KLXIP4afaELMeTpJHIDYQzvwKm15XlkoLIctVUDxFAt71m7v0bFeyZ1 Uh4oMKAvfsYVjMeY4x3ESXli0ikDF6A4GmAaosSr/YxUthTGc7RXFQ9oGigJyWjD3xVmLlF0p/b CoDr04i/kn0lKcXTgTuajgbgdTubPACEy+nJUR89v34vkiOa+7neBHC0Z+iBqoDQe7b05rPsCBv 2IY8FVp0+yY9tlC3p6A== X-Proofpoint-GUID: MF7r4x-aonq_fwWktsFP-ZkjQSsZUYcW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 adultscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 spamscore=0 phishscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan ufshcd_prepare_lrbp_crypto() programs crypto_key_slot in the LRB from rq->crypt_keyslot. With the blk-crypto slot path a bio can carry a pre-programmed physical ICE keyslot index in crypt_ctx->bc_slot rather than a blk_crypto_key pointer. In that case rq->crypt_keyslot is NULL and the existing code incorrectly falls through to the "no encryption" path, leaving crypto_key_slot as -1. Extend the function to handle both cases: when rq->crypt_keyslot is set, derive the slot index via blk_crypto_keyslot_index() as before; when bc_slot.data_unit_size_bits is non-zero, read crypto_key_slot directly from bc_slot.phy_slot. Signed-off-by: linlzhan --- drivers/ufs/core/ufshcd-crypto.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-cry= pto.h index 8f66db94e179..2fc5601c0f76 100644 --- a/drivers/ufs/core/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -15,13 +15,21 @@ static inline void ufshcd_prepare_lrbp_crypto(struct request *rq, struct ufshcd_lrb *lrbp) { - if (!rq || !rq->crypt_keyslot) { + if (!rq) { lrbp->crypto_key_slot =3D -1; return; } =20 - lrbp->crypto_key_slot =3D blk_crypto_keyslot_index(rq->crypt_keyslot); - lrbp->data_unit_num =3D rq->crypt_ctx->bc_dun[0]; + if (rq->crypt_keyslot) { + lrbp->crypto_key_slot =3D blk_crypto_keyslot_index(rq->crypt_keyslot); + lrbp->data_unit_num =3D rq->crypt_ctx->bc_dun[0]; + } else if (rq->crypt_ctx && rq->crypt_ctx->bc_slot.data_unit_size_bits) { + lrbp->crypto_key_slot =3D rq->crypt_ctx->bc_slot.phy_slot; + lrbp->data_unit_num =3D rq->crypt_ctx->bc_dun[0]; + } else { + lrbp->crypto_key_slot =3D -1; + } + } =20 static inline void --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 32A1C48CD7F for ; Thu, 27 Aug 2026 16:08:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846922; cv=none; b=YRv7WS0Nxj0/H+9GWgBTf541YGt4d/PP1Uk3khjVUXgU02YKNgRy0e1th89EjOH2EZ38J33bo27KJH18TQW33OMBUwfwsi28G/Tit0cPmR2mbYnUqjXaxGezy6YxTGqh461kdl0Bw8LTefi22HAx5ux0Gu0HVSkpnv7tUPAmUyE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846922; c=relaxed/simple; bh=XzVRSJskkXzsRQMCF0q2XHzItKnQaDkIqK2bV/uMi6Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RZWrG0bz3UJ1YE4vnViCkHmvP2YotcVGO8pbW6ocbRXAhX+aqeb802v7pMCv15Q0Oaw7XlNEZic+wbIE08UjXiYGasu1jZhGaazHTKUXaTVGQQAFbP/yyelXZ+oT74OpcKXrXTESSLtI2WbLlCsD0diixcQYd21zAQg+XDOh+j4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=oFwTjd6O; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=BCfu1miM; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="oFwTjd6O"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="BCfu1miM" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFcC29164875 for ; Thu, 27 Aug 2026 16:08:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=GQuf/V68eCT XXH2b/XlQO3XYqlyP/kTHk7utlZNkRig=; b=oFwTjd6O46+rn3wQuhLnjLfejRI JzlkxQSt3yFeu41vHuEDRwREWQb/MqlkNuVm1K7rXRrb1LnCdn7kasEpR73XcA4I 0RUsK5WYrYHBR+ekT3kOuxUJTj9DvpOV7EJQJZ7kZTPydi9vTE5SM5FJFJaM4swO 6cx951RiLv1XwxTtlcUdL7qyWC83c9a0lrDN9Ro7St3H1fkKn1PDPGNdgkyYf+n4 0I05RdmD/c3T6KmB5Jo2tG6ZNq9g0uOiMJHwGomEX1zaxpZNwDz3WJFIzCPUKQC5 VUHQzo0KHoD6lNydXTaSoa7h/p4k7EROq3txUc2+bYHsHO/xDvwP/N2vM7Q== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gagjft3dh-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:38 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-3823dcc1647so98947a91.3 for ; Thu, 27 Aug 2026 09:08:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846918; x=1788451718; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GQuf/V68eCTXXH2b/XlQO3XYqlyP/kTHk7utlZNkRig=; b=BCfu1miMC5zWMyNdNUtAtQMyE5suGsZEdFJuLAgWI5rnFdL2ISus8xFh7rhdMUvq4F TsuB8wvnK070wWrup9JILSjFMmNi/+neDxZp1BYQkITBFyEL6Aqag48NrDXLbfTHaAoz kzMEOR8qk+I7sdw7KAiFk+H3WLARPWqsv9guN75zNz4JevcRPwNmr5JaGM4ZdzEeXEC3 riX6YyeX7evE7kkwihuA/Slrtym2mYhCHW7s2xldBNk/rRlv6wDjCiuiX4TdM78Wnnn6 3rtgruYseHPY0QttEjw/KNjmaud54CCWimWebNtzPWn7lN+fKFmhwBgRTvKwbvyJpRcd X4JA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846918; x=1788451718; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=GQuf/V68eCTXXH2b/XlQO3XYqlyP/kTHk7utlZNkRig=; b=h3f3EUYH+JapUgzwBK5KuftEbN3fWyDhUdIB36pR3vAEMGnnmy+UWtvv5XFGUiy1qb gFgHk2oNH1ywVNHfbSF97tDDwsBZ5K9rc96eDU094+RDrfdwNJbdOIuPd3wGWtnnmV/C u/mzxOtWs/wz05kIA7Q9PT2wCMSgaSlnX2Jps3DeyEP5szweRmy4u4Qgudq+nUx9hlSy c+1QfipYvFUKUfaI7i7fwTa2K36mKxejvC1b2c9hMuZ2KjV2XpZO28ywrRtrww9B0Fkm EbeT7eVOlwuBcDIxbrYK55pkmfOzAldD/13RDFSv5To4XvPGXL/GhcN+hlw0xaTsy7N4 pueg== X-Forwarded-Encrypted: i=1; AHgh+RqjbTdMQ9Bfza7LgSpOA8LpFg2315b5TVRkZ/FZPAMxN4llHpA007XijO04DnSuSSfE3u3YfxbUBE7P6T4=@vger.kernel.org X-Gm-Message-State: AFuF++m0pd9rNnVphPvUULCzpfmrQxVeWHPxsscFm6aMdBdFrQWTsQ9s Yw68Xhp8ol9VFu/pGa0OXP1jFq9xedyGaDL9aG1zbak3hFXEVjQVY27EoQlgwZCQCbDljFBl0kN SwFwgNxB2seiDHbk9buwp9+Xq5rsqwlDN4bDqjl/jQR4Zn8QyRK9U/AQCGzHClyLroRI= X-Gm-Gg: AR+sD13TlT5xQ+pIfg0k0ZRI1/l2o3/WU4XM/54uPnPuLGUIMWq2pW8rFpjzGwGVIW5 Z7/HTpSBUnuTRQVS6U8thmW69/dsAfCuT6ryjK9CFQh4yRJY5ch5Sla/uTn4iogvgy/xSzE4Jgj 2R0+Rai21OGhdgSYLmMw8i7ZDrbDUT41RthJ8dDLSsw9fnxCrgvGZKq2od5h7cuTEg/pS5YdHVC PvY1z+XRw7rJxCq6CjmAeVDIc9aw1etRpb8dxJhC2CWR0mXCsfJTaQ+bd7esVPJWgDDyF9wccCv YOecbnRj8E2L6WIoceCceNo72R/zeE0n3pvy3WUXPlFkTxMw+xVbBNypSgdtP9WlvvD9GaQl9Cb odaFE78GjrAypFqPf7zvQjKilMoYh2Bots6stDtB3sAdlKC8iZkaLbJY7SL0= X-Received: by 2002:a17:90b:51c7:b0:38f:5801:dc0e with SMTP id 98e67ed59e1d1-396d0f52b2amr503469a91.15.1787846917371; Thu, 27 Aug 2026 09:08:37 -0700 (PDT) X-Received: by 2002:a17:90b:51c7:b0:38f:5801:dc0e with SMTP id 98e67ed59e1d1-396d0f52b2amr503276a91.15.1787846916655; Thu, 27 Aug 2026 09:08:36 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:36 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 07/11] blk-crypto: move bio_crypt_dun_increment() to the public header Date: Thu, 27 Aug 2026 09:07:16 -0700 Message-ID: <20260827160806.1295313-8-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-ORIG-GUID: mDLjz1kFG4dUxeU3Xus0wM_bRCFLMnza X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX/oEOT8ikskc8 6JEpen5DKvH8zAbcmNQDAIj1M+A+VH3eo7J5vx7Qsy7K6M9BXNJz5MHzwG36FhRcKexb6pKbhAJ Gu99ppNfOCdzPv3qHmzs1g2qpl7vz8mkFj3IeKzWwQTNsDUKTC6lX8O+i2FZXaPpIJO4X3meQCp 2coU7osPEVssJ0OGywumiE4hjD+AIAFxv/jGiwriuMtO+IFVJS4KSroGhYEz/precy2+GiCTiId zn1H1V9z7Xe9kvQa4KW12LvgclxJirjI/FJeWcLO5GK0CxWQBbxAo36Xi5TOf2lA3IoPNJsT5fk iFd7hRrfGOitjdwJ/pTBmZoKn/xPPZlFNefJ1liCYwhvvjSJLNS0rM9GeSUEfjU0d/6QLBpbNFT /oQ+banCFA1zrc5BHZMa6FJ6zwZLPEGy0XkpGOjWmBR44fsUnYdhX8xKU9VpPcg2b34+jONBP2B vNxVxi3rNByuhKkyL/w== X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX72hGSt3ktugN xpqrVuKUibb7insyqwQn2MOjh/XhQe2uBNOETptOJGTkfPafwf6RLPcrK/mEkKB4TPCG5dYz6dx 8N4ea6XMuC6hZz4FaaivVZZT96T2iXw= X-Proofpoint-GUID: mDLjz1kFG4dUxeU3Xus0wM_bRCFLMnza X-Authority-Analysis: v=2.4 cv=dd+wG3Xe c=1 sm=1 tr=0 ts=6a906106 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=Dog9NmGJ06mbJvtOeFoA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 clxscore=1015 bulkscore=0 adultscore=0 suspectscore=0 impostorscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan bio_crypt_dun_increment() is currently declared only in block/blk-crypto-internal.h, which is not accessible to code outside of block/. Drivers that manage inline-encrypted I/O directly need to advance the DUN across bio_vecs within a bio, or across multiple bios in a request, and have no other way to call this function. Move the declaration from block/blk-crypto-internal.h to include/linux/blk-crypto.h alongside the existing bio_crypt_dun_is_contiguous() and blk_crypto_init_key() declarations. The implementation in block/blk-crypto.c is unchanged. Signed-off-by: linlzhan --- block/blk-crypto-internal.h | 3 --- include/linux/blk-crypto.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h index 04035d237f03..32c720aabba7 100644 --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -26,9 +26,6 @@ int blk_crypto_sysfs_register(struct gendisk *disk); =20 void blk_crypto_sysfs_unregister(struct gendisk *disk); =20 -void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], - unsigned int inc); - bool bio_crypt_rq_ctx_compatible(struct request *rq, struct bio *bio); =20 bool bio_crypt_ctx_mergeable(struct bio_crypt_ctx *bc1, unsigned int bc1_b= ytes, diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 33ae52b77522..c9f436b6b2ef 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -181,6 +181,9 @@ bool bio_crypt_dun_is_contiguous(const struct bio_crypt= _ctx *bc, unsigned int bytes, const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]); =20 +void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], + unsigned int inc); + int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *key_bytes, size_t key_size, enum blk_crypto_key_type key_type, --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 C758D49481A for ; Thu, 27 Aug 2026 16:08:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846927; cv=none; b=D2/OpPogOuYkpVIafSgSV7e01cOc92XkywZzmhhAORIEOvTUTDxwuyFJkKHTtGeoU5SqVQn+yQAuwwDpC09ibkPaVTIlWgCHaQuJggidGoILeGEX20Whj2XAHFxKICUKXW5nAgCEP3MQa/VHtQ8gtDmP9TSV0BcD5C1MC9sA5mE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846927; c=relaxed/simple; bh=Dfrg6lE9de3zpyDCOAah5y60csvIaySoJn8fAvjltME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Bc8G3kvwwpFMmgxXwN3R+w4MjVabCJiBC2uZBV2/zqzRpI3bQZvlEigQNv+7L4TppK7lQ6lRFyhDV98T4rBH++ebE5rGTgVWoVSAogk4PCcuTit+yWaXlM75nkoXIso76HtKmt5lmwg5I7Kt1MR7surbMCS5Gc66PHU8oRwEjKA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=pA5RVx75; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Glox0Mke; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="pA5RVx75"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Glox0Mke" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFbhOd1310842 for ; Thu, 27 Aug 2026 16:08:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= fg04UKiEaH0S7rfjN0Lg/gctUU1gmD3apjDNgN4QmkY=; b=pA5RVx75UuOZY5r6 RMJfr6RJYwvQUBLetHCZEdZLlCa0kif9EJN0c/i5eGgkFAmGMln2IkpqaRYvEoWM 3xTr+7d0OX7RsRV6pa6AH9M/kz2FFc5e+cLr46Mds9FRJPqwZZmwqa445tZ4PR5A iTeYcwdUBE0lG1Y7BUMQmD7SIQagJPoyr+19KRYtEUMhmzS1jFCqZnerWAo13bXW 5QkVJFDIUoz8k1/o7AtUS+XNobHDxwrUIAzcd5wTNN2PUbuFYM0m5lfwmZaAspRi FzZnoB7uA1DXcYHq8jz4HPRf49wN2pLTlOhlWomEFJmRz/Gte1FTTHVoS3RdzpnW FiAypg== Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ga8m5kp1e-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:42 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-38e8e864ef0so205691a91.0 for ; Thu, 27 Aug 2026 09:08:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846922; x=1788451722; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=fg04UKiEaH0S7rfjN0Lg/gctUU1gmD3apjDNgN4QmkY=; b=Glox0MkeeIkODAWZXyJwmZNtFpcY/fjEJya1EynOOooVQB9miuCTlTDR1I9sJ3W6xk LTH5a5sqxcR0cEitZpc3AdKX+h9Ml7vx+RduM7cXEbIe7WKN83xF9c102EzVRbHoWy0N aX+5shpO4/su2jAfdFcyrsSjnOREttxDQkTOKXFzCmqrcxBjl5zumkfEt6xsHtUw0PkV tY1UNFTCdX9O/IupuhjjIq8J26EP1i6N9ASuxr/ix5UtLM35WuU0yQR1AjqpSrYRcwqy VTUER4idCT/QPT9V6/V0deeYxlu4KcHqWbWgz1mu6IUrKQGBl6wAmqa8kbOeDQj5qQzz +q1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846922; x=1788451722; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=fg04UKiEaH0S7rfjN0Lg/gctUU1gmD3apjDNgN4QmkY=; b=ImZ3n/CHtpwRbLb4FSGcuK6XK2n4tZjG1GsrjuVAZJ89TPSLgfT3KJFrw+92nnRsG/ VQRLKYpFsmFPN+zo0ACoolcLtQD4AiuPlQKQR7lBDyDc375uNzg8qYQbobyecBysfQDe +QPQUG6DeMbUmxLgunHwsCRQsvsPT98Ox25gEZsHUMJ+WSNwaBYtSuoauEPcKm96SP0j /I3PV11dzBom3/keYQca74HHNuBSFaM/PZax93VjEpYwDEw7m0s+NIY3bWzaKsEVfTao YF3JB6AL2jyDHzGET/rkHLDiUx+4m1Z2rvBehGGBF6WP3kblXIGy7l2RSjo0f4XoW2U9 4C9g== X-Forwarded-Encrypted: i=1; AHgh+RpGY73/hjpPWXHDMVSKzq1e9U0JNgAubOMrvLttG2FU1YyTHw+u9Zxw5QoGhSkPdrR5K6TNuZMaKz4yHaA=@vger.kernel.org X-Gm-Message-State: AFuF++m+8Ud3tKfEgMwL/CbMByAUoi0/Mfge164mRVBvChTK58bap8HV ZuA1JFmm3KPrZJ7zpivSyZBhLjfsgSZEGvqPHyZYZlQqJu+LO6B5k5YNsoNyxjuiA+Fj5i+HFxJ vKVN7EsSypZwAm2O91KMNMqeF7GZGG2TBXy3vSKYOmKJufLZXkI6HDEiY4JEUFWp4AWQ= X-Gm-Gg: AR+sD13yvWdACDfo58ztTalY0NisQIbIDkdu+nGlOOfwXXYlsJUHe6H7s7xlOPKVwAz /E7sdlj5nGeuJGIEgUcIKvq9S+/qKcya/w+SfO81mJGFiOt8bBrwOcQ4o5d8p935IZAh2VwjVb1 WOsbqWitm0rAP10WmVIaOrSejGD11VP/GHBf75sAhi9LztpERyIKKi2dIHyph6Kv/kp7xgkJNly KffmqryHeNa13zl794MwaGKur6z+I8s3F5ewFuU775gupDHnKrgS8Bihv91Bk7CV9cgkvR0ghlv plqFgiqPyw8uoDkTv2+uPWevHuiiRU/3S8C6Tex9kouZ6rUPnImwszGSBSwosD6qrocYcc4m6PA Xzt6V5z+B1m7qg5SZKFOaVhNN6wrcaymNSOrUeIJvMxf/BnHk8D42aJubxBQ= X-Received: by 2002:a17:90b:520f:b0:37c:6130:7a5b with SMTP id 98e67ed59e1d1-396d0ec0d70mr617856a91.8.1787846920214; Thu, 27 Aug 2026 09:08:40 -0700 (PDT) X-Received: by 2002:a17:90b:520f:b0:37c:6130:7a5b with SMTP id 98e67ed59e1d1-396d0ec0d70mr617665a91.8.1787846919411; Thu, 27 Aug 2026 09:08:39 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:39 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 08/11] block: add /dev/blk-crypto-proxy for host-side virtio-blk inline encryption Date: Thu, 27 Aug 2026 09:07:17 -0700 Message-ID: <20260827160806.1295313-9-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-ORIG-GUID: 4Lj-FswvDvBsfghE91pbhsu1uwKwJdAj X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX2cCiPM4OQ/cb 2NjnEvxSg7gPXli+h6XHlm35BwZA/iy3NFodDRL1WEQgO23hZTPqpfEhufMthEa2bQpBmEtHxt4 IND6TqDmrBn0p155pGbbd59fXy8jKZs= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfXw5MEg2OtTOKq oDNMS8UrLcAf4gdgn9ZT2pKX34zZ+6roCT4u7NrSNqR/o+Yu0blvruvyrV1tcG8H60aWSJV/DI+ MP62XZfk5keWxfIASCtOjbw92JCZtN69NrGAtjBiVJms21CKhun2XW2kwGm2Nx4vk/9Ud76WHMe H/QZCso50jkYF1zKplLg/9uCNwd4oWkcqN2hhyhXt77WTdnMtqHAUtHO1wSyB81a+g0Mi7LYGv5 br98uJJDGIaSaUnUdT5hhxfJOQ+v8Qa8FQG5+DE2RT1Ew4BbQ7A4ovRofoOe8GYj0g3uNiKBspl rRqL24MmNCduGzmA6wtUAE5/B9iudVgMCwW4xqtwV7WOann+Yg6CsRU7LgSU1UILP3cL5d/A6VU 55VdtSSmaABQChYUntriyHurrp5ntLgR5DwnAKuopjZf7OPLFt4DXb6/YPmy/LzKkI6CBIwj0Di NMKlEKESO9Ojw1o1RcQ== X-Proofpoint-GUID: 4Lj-FswvDvBsfghE91pbhsu1uwKwJdAj X-Authority-Analysis: v=2.4 cv=SomgLvO0 c=1 sm=1 tr=0 ts=6a90610a cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=WH_6LjaRQCbUvFa_ckcA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1011 phishscore=0 spamscore=0 priorityscore=1501 suspectscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 From: linlzhan A userspace virtio-blk backend receives VIRTIO_BLK_T_CRYPTO_IN/OUT requests from guests that carry a virtual ICE keyslot index and a data unit number. The backend must submit the bio to the host storage controller with the correct inline encryption context, but it has no in-kernel interface to do so. Add /dev/blk-crypto-proxy, a misc character device that bridges a userspace virtio-blk backend to the kernel blk-crypto layer. The interface is three ioctls: BCP_BIND_CONTEXT =E2=80=94 bind a host block device fd and a hypervi= sor VM fd to this file descriptor; the kernel resolves the VM fd to a guest id and holds the bdev reference for the fd lifetime. BCP_GET_CRYPTO_CAPS =E2=80=94 query the bound device's blk_crypto_profi= le capabilities (supported modes, key types, max DUN bytes) and the number of ICE keyslots allocated to the bound VM, so the backend can populate the virtio config space crypto fields. BCP_SUBMIT_IO_BY_VSLOT =E2=80=94 submit an inline-encrypted bio using the virtual slot index supplied by the guest. The kernel resolves virt_slot to a physical ICE keyslot via bcp_slot_virt_ops, calls bio_crypt_set_ctx_by_slot(), and submits the bio synchronously. Large requests are split at data-unit boundaries (BIO_MAX_VECS per bio) to preserve DUN/IV correctness. The implementation follows the block layer's direct-I/O path, with two differences: each bio carries an inline encryption context, and multiple bios are submitted sequentially rather than concurrently now. The driver is hypervisor-agnostic and storage-vendor-agnostic. Two pluggable op-sets registered by platform drivers fill the gaps: bcp_hypervisor_ops =E2=80=94 translate a hypervisor VM fd to an opaque guest_id; implemented by the hypervisor driver. bcp_slot_virt_ops =E2=80=94 map (profile, guest_id, virt_slot) to a physical ICE keyslot; implemented by the platform storage virtualization layer. Both op-sets are RCU-protected singletons; the hot path reads them lock-free. Signed-off-by: linlzhan --- drivers/block/Kconfig | 15 + drivers/block/Makefile | 1 + drivers/block/blk-crypto-proxy.c | 667 ++++++++++++++++++++++++++ include/linux/blk-crypto-proxy.h | 100 ++++ include/uapi/linux/blk-crypto-proxy.h | 122 +++++ 5 files changed, 905 insertions(+) create mode 100644 drivers/block/blk-crypto-proxy.c create mode 100644 include/linux/blk-crypto-proxy.h create mode 100644 include/uapi/linux/blk-crypto-proxy.h diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 7790ee2c700c..48ad79734c09 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -176,6 +176,21 @@ config BLK_DEV_LOOP =20 Most users will answer N here. =20 +config BLK_CRYPTO_PROXY + tristate "Inline encryption proxy for virtio-blk guests" + depends on BLK_INLINE_ENCRYPTION + help + Provides /dev/blk-crypto-proxy, a misc character device that allows a + userspace virtio-blk backend to submit inline-encrypted block I/O + on behalf of guest virtual machines. + + Guests supply a virtual keyslot index and data unit number with + each encrypted request. The host kernel translates the virtual + slot to a physical hardware keyslot and issues the bio to the + storage controller with the correct inline encryption context. + + If unsure, say N. + config BLK_DEV_LOOP_MIN_COUNT int "Number of loop devices to pre-create at init time" depends on BLK_DEV_LOOP diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 079c910d5fc9..636137248d0d 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_BLK_DEV_LOOP) +=3D loop.o obj-$(CONFIG_SUNVDC) +=3D sunvdc.o =20 obj-$(CONFIG_BLK_DEV_NBD) +=3D nbd.o +obj-$(CONFIG_BLK_CRYPTO_PROXY) +=3D blk-crypto-proxy.o obj-$(CONFIG_VIRTIO_BLK) +=3D virtio_blk.o =20 obj-$(CONFIG_VIRTBLK_CRYPTO_VIRTUALIZATION) +=3D virtio_blk_crypto_ext.o diff --git a/drivers/block/blk-crypto-proxy.c b/drivers/block/blk-crypto-pr= oxy.c new file mode 100644 index 000000000000..60722884dbcd --- /dev/null +++ b/drivers/block/blk-crypto-proxy.c @@ -0,0 +1,667 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define pr_fmt(fmt) "blk-crypto-proxy: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct bcp_hypervisor_ops __rcu *g_hypervisor_ops; +static DEFINE_MUTEX(g_hypervisor_ops_lock); + +static const struct bcp_slot_virt_ops __rcu *g_slot_virt_ops; +static DEFINE_MUTEX(g_slot_virt_ops_lock); + +int bcp_register_hypervisor_ops(const struct bcp_hypervisor_ops *ops) +{ + int ret =3D 0; + + mutex_lock(&g_hypervisor_ops_lock); + if (rcu_access_pointer(g_hypervisor_ops)) + ret =3D -EBUSY; + else + rcu_assign_pointer(g_hypervisor_ops, ops); + mutex_unlock(&g_hypervisor_ops_lock); + return ret; +} +EXPORT_SYMBOL_GPL(bcp_register_hypervisor_ops); + +void bcp_unregister_hypervisor_ops(const struct bcp_hypervisor_ops *ops) +{ + mutex_lock(&g_hypervisor_ops_lock); + if (rcu_access_pointer(g_hypervisor_ops) =3D=3D ops) + rcu_assign_pointer(g_hypervisor_ops, NULL); + mutex_unlock(&g_hypervisor_ops_lock); + synchronize_rcu(); +} +EXPORT_SYMBOL_GPL(bcp_unregister_hypervisor_ops); + +int bcp_register_slot_virt_ops(const struct bcp_slot_virt_ops *ops) +{ + int ret =3D 0; + + mutex_lock(&g_slot_virt_ops_lock); + if (rcu_access_pointer(g_slot_virt_ops)) + ret =3D -EBUSY; + else + rcu_assign_pointer(g_slot_virt_ops, ops); + mutex_unlock(&g_slot_virt_ops_lock); + return ret; +} +EXPORT_SYMBOL_GPL(bcp_register_slot_virt_ops); + +void bcp_unregister_slot_virt_ops(const struct bcp_slot_virt_ops *ops) +{ + mutex_lock(&g_slot_virt_ops_lock); + if (rcu_access_pointer(g_slot_virt_ops) =3D=3D ops) + rcu_assign_pointer(g_slot_virt_ops, NULL); + mutex_unlock(&g_slot_virt_ops_lock); + synchronize_rcu(); +} +EXPORT_SYMBOL_GPL(bcp_unregister_slot_virt_ops); + +/** + * struct bcp_ctx - per-fd state for /dev/blk-crypto-proxy + * @bdev_file: file handle for the bound block device; NULL until BCP_BIND= _CONTEXT. + * Published with smp_store_release() so hot-path ioctls can r= ead it + * lock-free via smp_load_acquire() in bcp_ctx_bound(). + * @guest_id: guest identifier resolved from vm_fd at bind time. + * @bdev_writable: block_dev_fd was opened with write access. + * @bind_lock: serializes concurrent BCP_BIND_CONTEXT calls on this fd. + */ +struct bcp_ctx { + struct file *bdev_file; + u32 guest_id; + bool bdev_writable; + struct mutex bind_lock; +}; + +/* + * True once BCP_BIND_CONTEXT has published ctx->bdev_file. The acquire p= airs + * with smp_store_release() in bcp_ioctl_bind_context(), ensuring ctx->gue= st_id + * and ctx->bdev_writable are visible to any caller that observes true. + */ +static bool bcp_ctx_bound(struct bcp_ctx *ctx) +{ + return smp_load_acquire(&ctx->bdev_file) !=3D NULL; +} + +static int bcp_open(struct inode *inode, struct file *file) +{ + struct bcp_ctx *ctx; + + ctx =3D kzalloc_obj(*ctx, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + mutex_init(&ctx->bind_lock); + file->private_data =3D ctx; + return 0; +} + +static int bcp_release(struct inode *inode, struct file *file) +{ + struct bcp_ctx *ctx =3D file->private_data; + + if (ctx) { + if (ctx->bdev_file) + bdev_fput(ctx->bdev_file); + mutex_destroy(&ctx->bind_lock); + kfree(ctx); + file->private_data =3D NULL; + } + return 0; +} + +/* + * Resolve a userspace block device fd to a struct file holding a reference + * to the block device, opened with the same access mode as @fd so that a + * read-only fd cannot gain write access via BCP_SUBMIT_IO_BY_VSLOT. + */ +static struct file *bcp_bdev_from_fd(int fd, bool *writable) +{ + struct file *f; + struct inode *inode; + dev_t dev; + blk_mode_t mode =3D 0; + + f =3D fget(fd); + if (!f) + return ERR_PTR(-EBADF); + inode =3D file_inode(f); + if (!S_ISBLK(inode->i_mode)) { + fput(f); + return ERR_PTR(-ENOTBLK); + } + if (f->f_mode & FMODE_READ) + mode |=3D BLK_OPEN_READ; + if (f->f_mode & FMODE_WRITE) + mode |=3D BLK_OPEN_WRITE; + if (!mode) { + fput(f); + return ERR_PTR(-EACCES); + } + *writable =3D !!(mode & BLK_OPEN_WRITE); + dev =3D inode->i_rdev; + fput(f); + return bdev_file_open_by_dev(dev, mode, NULL, NULL); +} + +static long bcp_ioctl_bind_context(struct file *file, + struct bcp_bind_context_arg __user *argp) +{ + struct bcp_ctx *ctx =3D file->private_data; + struct bcp_bind_context_arg arg; + const struct bcp_hypervisor_ops *hv_ops; + struct file *bdev_file; + u32 guest_id; + bool writable =3D false; + int ret; + + if (!ctx) + return -EINVAL; + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + if (arg.reserved) + return -EINVAL; + + /* + * get_guest_id() may sleep; call it before taking bind_lock. + */ + rcu_read_lock(); + hv_ops =3D rcu_dereference(g_hypervisor_ops); + if (!hv_ops) { + rcu_read_unlock(); + return -EOPNOTSUPP; + } + ret =3D hv_ops->get_guest_id(arg.vm_fd, &guest_id); + rcu_read_unlock(); + if (ret) + return ret; + + /* + * Serialize against concurrent BCP_BIND_CONTEXT calls: two callers + * could both pass the ctx->bdev_file =3D=3D NULL check before either sto= res. + */ + guard(mutex)(&ctx->bind_lock); + + if (ctx->bdev_file) + return -EBUSY; + + bdev_file =3D bcp_bdev_from_fd(arg.block_dev_fd, &writable); + if (IS_ERR(bdev_file)) + return PTR_ERR(bdev_file); + + ctx->guest_id =3D guest_id; + ctx->bdev_writable =3D writable; + /* + * Publish ctx->bdev_file last with a release barrier; bcp_ctx_bound() + * reads it with smp_load_acquire() without taking @bind_lock. + */ + smp_store_release(&ctx->bdev_file, bdev_file); + return 0; +} + +/* + * Maps VIRTIO_BLK_CRYPTO_MODE_* to enum blk_crypto_mode_num. The two ind= ex + * spaces do not coincide, so modes_supported[] must not be copied positio= nally. + * Keep in sync with virtio_blk_crypto_mode_map[] in drivers/block/virtio_= blk.c. + */ +static const enum blk_crypto_mode_num + bcp_virtio_crypto_mode_map[VIRTIO_BLK_CRYPTO_MODE_MAX + 1] =3D { + [VIRTIO_BLK_CRYPTO_MODE_INVALID] =3D BLK_ENCRYPTION_MODE_INVALID, + [VIRTIO_BLK_CRYPTO_MODE_AES_256_XTS] =3D BLK_ENCRYPTION_MODE_AES_256_XTS, +}; + +static long bcp_ioctl_get_crypto_caps(struct file *file, + struct bcp_get_crypto_caps_arg __user *argp) +{ + struct bcp_ctx *ctx =3D file->private_data; + struct bcp_get_crypto_caps_arg arg; + struct block_device *bdev; + u32 modes[VIRTIO_BLK_CRYPTO_MODE_MAX + 1] =3D {0}; + struct blk_crypto_profile *profile; + unsigned int i, n; + u32 cap, written; + + if (!ctx || !bcp_ctx_bound(ctx)) + return -ENXIO; + + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + if (arg.num_modes && !arg.modes_ptr) + return -EINVAL; + + bdev =3D file_bdev(ctx->bdev_file); + profile =3D bdev_get_queue(bdev)->crypto_profile; + if (!profile) + return -EOPNOTSUPP; + + arg.key_types_supported =3D profile->key_types_supported; + /* + * Clamp to 8: the @dun wire field is a single __aligned_u64 so nothing + * upstream can deliver a wider DUN regardless of what the profile claims. + */ + arg.max_dun_bytes =3D min_t(u32, profile->max_dun_bytes_supported, 8); + + /* + * arg.modes_supported[] is indexed by VIRTIO_BLK_CRYPTO_MODE_* (index 0 + * is always 0 per the virtio spec). Translate via the map above; do not + * copy profile->modes_supported[] positionally. + */ + n =3D VIRTIO_BLK_CRYPTO_MODE_MAX + 1; + cap =3D arg.num_modes; + written =3D min_t(u32, cap, n); + + for (i =3D 1; i < n; i++) { + enum blk_crypto_mode_num kmode =3D bcp_virtio_crypto_mode_map[i]; + + if (!kmode) + continue; + modes[i] =3D profile->modes_supported[kmode]; + } + + if (written && + copy_to_user(u64_to_user_ptr(arg.modes_ptr), modes, + written * sizeof(modes[0]))) + return -EFAULT; + arg.num_modes =3D written; + + arg.max_slots =3D 0; + rcu_read_lock(); + { + const struct bcp_slot_virt_ops *sv_ops =3D + rcu_dereference(g_slot_virt_ops); + if (sv_ops) { + int nslots =3D sv_ops->get_guest_slots(profile, ctx->guest_id); + + if (nslots > 0) + arg.max_slots =3D nslots; + } + } + rcu_read_unlock(); + + if (copy_to_user(argp, &arg, sizeof(arg))) + return -EFAULT; + return 0; +} + +/* + * Compute the number of pages needed for up to @want_bytes of iovec data + * starting at cursor (@start_idx, @start_off). The page count is capped = at + * @cap to bound the arithmetic; *bytes_out receives the actual byte count. + */ +static unsigned int bcp_iov_pages_for_bytes(const struct iovec *iov, u32 i= ov_cnt, + u32 start_idx, u64 start_off, + u64 want_bytes, unsigned int cap, + u64 *bytes_out) +{ + u64 pages =3D 0, taken =3D 0; + u32 i; + + for (i =3D start_idx; i < iov_cnt && taken < want_bytes; i++) { + u64 base, len; + + if (i =3D=3D start_idx) { + base =3D (u64)(uintptr_t)iov[i].iov_base + start_off; + len =3D iov[i].iov_len - start_off; + } else { + base =3D (u64)(uintptr_t)iov[i].iov_base; + len =3D iov[i].iov_len; + } + if (len =3D=3D 0) + continue; + if (len > want_bytes - taken) + len =3D want_bytes - taken; + pages +=3D DIV_ROUND_UP(len + offset_in_page(base), PAGE_SIZE); + taken +=3D len; + if (pages >=3D cap) { + *bytes_out =3D taken; + return cap; + } + } + *bytes_out =3D taken; + return (unsigned int)pages; +} + +/* + * Advance cursor (*idx, *off) forward by @bytes within @iov[0..iov_cnt). + */ +static void bcp_iov_advance_cursor(const struct iovec *iov, u32 iov_cnt, + u32 *idx, u64 *off, u64 bytes) +{ + while (bytes > 0 && *idx < iov_cnt) { + u64 seg_remaining =3D iov[*idx].iov_len - *off; + u64 take =3D min_t(u64, seg_remaining, bytes); + + *off +=3D take; + bytes -=3D take; + if (*off =3D=3D iov[*idx].iov_len) { + (*idx)++; + *off =3D 0; + } + } +} + +static long bcp_ioctl_submit_io_by_vslot(struct file *file, + struct bcp_submit_io_by_vslot_arg __user *argp) +{ + struct bcp_ctx *ctx =3D file->private_data; + struct bcp_submit_io_by_vslot_arg arg; + struct block_device *bdev; + struct blk_crypto_profile *profile; + struct iovec *iov =3D NULL; + struct iov_iter iter; + struct blk_crypto_slot slot; + u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; + u64 bytes_done =3D 0; + u64 align, stride; + u64 total_bytes; + u32 seg_idx =3D 0; + u64 seg_off =3D 0; + unsigned int phy_slot; + int ret =3D -EFAULT; + + if (!ctx || !bcp_ctx_bound(ctx)) + return -ENXIO; + + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + if (arg.reserved2) + return -EINVAL; + + bdev =3D file_bdev(ctx->bdev_file); + + if (arg.direction !=3D BCP_DIR_READ && arg.direction !=3D BCP_DIR_WRITE) + return -EINVAL; + /* + * blk_mode_t does not stop submit_bio() from writing; enforce the + * caller's original fd permission explicitly. + */ + if (arg.direction =3D=3D BCP_DIR_WRITE && !ctx->bdev_writable) + return -EACCES; + /* + * bdev_read_only() can change after bind time; submit_bio_noacct()'s + * bio_check_ro() only warns rather than errors in this kernel. + */ + if (arg.direction =3D=3D BCP_DIR_WRITE && bdev_read_only(bdev)) + return -EROFS; + if (arg.flags !=3D BCP_SUBMIT_IO_F_IOV) + return -EINVAL; + if (arg.iov_cnt =3D=3D 0 || arg.iov_cnt > BCP_MAX_IOV) + return -EINVAL; + /* A shift amount >=3D 64 would be undefined behavior. */ + if (arg.data_unit_size_bits >=3D 64) + return -EINVAL; + + profile =3D bdev_get_queue(bdev)->crypto_profile; + if (!profile) + return -EOPNOTSUPP; + + /* Resolve virt_slot =E2=86=92 phy_slot. */ + rcu_read_lock(); + { + const struct bcp_slot_virt_ops *sv_ops =3D + rcu_dereference(g_slot_virt_ops); + if (!sv_ops) { + rcu_read_unlock(); + return -EOPNOTSUPP; + } + ret =3D sv_ops->vslot_to_pslot(profile, ctx->guest_id, + arg.virt_slot, &phy_slot); + } + rcu_read_unlock(); + if (ret) + return ret; + + memset(dun, 0, sizeof(dun)); + dun[0] =3D arg.dun; + + slot.phy_slot =3D phy_slot; + slot.data_unit_size_bits =3D arg.data_unit_size_bits; + + align =3D 1ULL << arg.data_unit_size_bits; + /* + * Split bios at stride (smallest multiple of the data unit size >=3D + * PAGE_SIZE) boundaries so each bio ends on a whole data unit. + * bio_crypt_check_alignment() is skipped for slot-based bios (bc_key + * =3D=3D NULL), so a mid-unit split would silently mis-encrypt/mis-decry= pt. + */ + stride =3D DIV_ROUND_UP(PAGE_SIZE, align) * align; + + /* + * Import the caller's iovec once. import_iovec() validates every + * segment with access_ok(), returns the total byte count, and takes a + * private kernel copy that eliminates TOCTOU from a guest mutating its + * own iovec array mid-ioctl. + */ + ret =3D import_iovec(arg.direction =3D=3D BCP_DIR_READ ? ITER_DEST : ITER= _SOURCE, + (const struct iovec __user *)u64_to_user_ptr(arg.iov_ptr), + arg.iov_cnt, 0, &iov, &iter); + if (ret < 0) + return ret; + total_bytes =3D ret; + + /* + * Reject a misaligned total length up front: bio_crypt_check_alignment() + * is skipped for slot-based bios so nothing downstream will catch it. + */ + if (total_bytes =3D=3D 0 || (total_bytes & (align - 1)) || + (total_bytes & (SECTOR_SIZE - 1))) { + ret =3D -EINVAL; + goto out; + } + + /* + * Fail fast if the request exceeds the device. bio_check_eod() would + * also catch this, but only on the last bio after earlier bios have + * already done real I/O. + */ + { + sector_t nr_sectors =3D total_bytes >> SECTOR_SHIFT; + sector_t maxsector =3D bdev_nr_sectors(bdev); + + if (nr_sectors > maxsector || arg.sector > maxsector - nr_sectors) { + ret =3D -EIO; + goto out; + } + } + + /* + * Reject an out-of-range DUN: slot-based bios skip + * bio_crypt_check_alignment(), so an overflow would silently truncate + * in the hardware DUN field rather than error out. + */ + { + u64 total_units =3D total_bytes >> arg.data_unit_size_bits; + u64 max_dun_used, dun_limit; + + if (check_add_overflow(arg.dun, total_units - 1, &max_dun_used)) { + ret =3D -EINVAL; + goto out; + } + dun_limit =3D profile->max_dun_bytes_supported >=3D 8 ? U64_MAX : + (1ULL << (8 * profile->max_dun_bytes_supported)) - 1; + if (max_dun_used > dun_limit) { + ret =3D -EINVAL; + goto out; + } + } + + /* + * Submit the request as a sequence of bios (submit_bio_wait() per + * bio), each holding at most BIO_MAX_VECS pages. Sequential + * submission avoids DUN/IV correctness concerns across concurrent + * in-flight bios. + */ + while (seg_idx < arg.iov_cnt) { + unsigned int pages_used =3D 0; + u64 bio_bytes =3D 0; + u32 la_idx =3D seg_idx; + u64 la_off =3D seg_off; + u64 remaining_before; + struct bio *bio; + + /* + * Lookahead: count how many whole stride units fit within a + * fresh bio's BIO_MAX_VECS page budget. + */ + for (;;) { + u64 unit_bytes; + unsigned int unit_pages; + + unit_pages =3D bcp_iov_pages_for_bytes(iov, arg.iov_cnt, + la_idx, la_off, stride, + BIO_MAX_VECS + 1, + &unit_bytes); + if (unit_bytes =3D=3D 0) + break; /* only empty segments remain */ + + if (pages_used + unit_pages > BIO_MAX_VECS) { + if (pages_used =3D=3D 0) { + /* data_unit_size_bits too large to fit one unit. */ + ret =3D -EINVAL; + goto out; + } + break; /* finalize this bio; unit deferred to next */ + } + + pages_used +=3D unit_pages; + bio_bytes +=3D unit_bytes; + bcp_iov_advance_cursor(iov, arg.iov_cnt, &la_idx, &la_off, + unit_bytes); + } + + if (bio_bytes =3D=3D 0) + break; + + bio =3D bio_alloc(bdev, pages_used, + arg.direction =3D=3D BCP_DIR_WRITE ? + REQ_OP_WRITE : REQ_OP_READ, + GFP_KERNEL); + if (!bio) { + ret =3D -ENOMEM; + goto out; + } + bio->bi_iter.bi_sector =3D arg.sector + (bytes_done >> SECTOR_SHIFT); + + /* + * Use bio_iov_iter_get_pages() to pin pages into the bio, + * the same as the O_DIRECT path. Truncate the iter to this + * bio's byte budget, then reexpand for the next iteration. + */ + remaining_before =3D iov_iter_count(&iter); + iov_iter_truncate(&iter, bio_bytes); + ret =3D bio_iov_iter_get_pages(bio, &iter, 0, 0); + if (ret < 0) { + bio_put(bio); + goto out; + } + if (iov_iter_count(&iter) !=3D 0) { + /* + * The lookahead verified bio_bytes fits in BIO_MAX_VECS; + * if bio_iov_iter_get_pages() stopped early, its page + * accounting disagreed with bcp_iov_pages_for_bytes(). + */ + bio_put(bio); + ret =3D -EIO; + goto out; + } + iov_iter_reexpand(&iter, remaining_before - bio_bytes); + + /* + * Match __blkdev_direct_IO(): mark pages dirty on reads into + * user-backed memory. + */ + if (arg.direction =3D=3D BCP_DIR_READ && user_backed_iter(&iter)) + bio_set_pages_dirty(bio); + + bcp_iov_advance_cursor(iov, arg.iov_cnt, &seg_idx, &seg_off, + bio_bytes); + + bio_crypt_set_ctx_by_slot(bio, &slot, dun, GFP_KERNEL); + + ret =3D submit_bio_wait(bio); + bio_put(bio); + if (ret) + goto out; + + /* + * Advance dun by this bio's contribution only, not by + * recomputing from arg.dun + bytes_done, to avoid silent + * truncation when bytes_done grows past UINT_MAX data units. + */ + bio_crypt_dun_increment(dun, (unsigned int)(bio_bytes >> arg.data_unit_s= ize_bits)); + bytes_done +=3D bio_bytes; + } + ret =3D 0; + +out: + kfree(iov); + return ret; +} + +static long bcp_ioctl(struct file *file, unsigned int cmd, unsigned long a= rg) +{ + void __user *argp =3D (void __user *)arg; + + switch (cmd) { + case BCP_BIND_CONTEXT: + return bcp_ioctl_bind_context(file, argp); + case BCP_GET_CRYPTO_CAPS: + return bcp_ioctl_get_crypto_caps(file, argp); + case BCP_SUBMIT_IO_BY_VSLOT: + return bcp_ioctl_submit_io_by_vslot(file, argp); + default: + return -ENOTTY; + } +} + +static const struct file_operations bcp_fops =3D { + .owner =3D THIS_MODULE, + .open =3D bcp_open, + .release =3D bcp_release, + .unlocked_ioctl =3D bcp_ioctl, + .compat_ioctl =3D compat_ptr_ioctl, +}; + +static struct miscdevice bcp_misc =3D { + .minor =3D MISC_DYNAMIC_MINOR, + .name =3D "blk-crypto-proxy", + .fops =3D &bcp_fops, +}; + +static int __init blk_crypto_proxy_init(void) +{ + int ret; + + ret =3D misc_register(&bcp_misc); + if (ret) + return ret; + return 0; +} + +static void __exit blk_crypto_proxy_exit(void) +{ + misc_deregister(&bcp_misc); +} + +module_init(blk_crypto_proxy_init); +module_exit(blk_crypto_proxy_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Host-side inline crypto proxy for virtio-blk guests"); diff --git a/include/linux/blk-crypto-proxy.h b/include/linux/blk-crypto-pr= oxy.h new file mode 100644 index 000000000000..6cf1ff0703e9 --- /dev/null +++ b/include/linux/blk-crypto-proxy.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __LINUX_BLK_CRYPTO_PROXY_H +#define __LINUX_BLK_CRYPTO_PROXY_H + +#include +#include + +struct blk_crypto_profile; + +/** + * struct bcp_hypervisor_ops - hypervisor VM identity operations + * + * Translates a hypervisor-specific VM fd to the opaque u32 vm_id used + * throughout blk-crypto-proxy. Register once at module init time. + */ +struct bcp_hypervisor_ops { + /** + * @get_guest_id: Resolve @vm_fd to an opaque guest identifier. + * + * Verify the caller is permitted to act on behalf of the VM and write + * its u32 id to @guest_id_out. The value is passed verbatim to + * bcp_slot_virt_ops callbacks. + * + * Returns 0 on success, -errno on failure. + */ + int (*get_guest_id)(int vm_fd, u32 *guest_id_out); +}; + +/** + * bcp_register_hypervisor_ops() - register the hypervisor op-set + * @ops: op-set to register; must remain valid until unregistered. + * + * Returns 0 on success, -EBUSY if an op-set is already registered. + */ +int bcp_register_hypervisor_ops(const struct bcp_hypervisor_ops *ops); + +/** + * bcp_unregister_hypervisor_ops() - unregister the hypervisor op-set + * @ops: must be the pointer that was passed to bcp_register_hypervisor_op= s(). + * + * Blocks until all in-flight callers have finished, then clears the + * registration. Safe to call from module exit. + */ +void bcp_unregister_hypervisor_ops(const struct bcp_hypervisor_ops *ops); + +/** + * struct bcp_slot_virt_ops - ICE keyslot virtualization operations + * + * Per-VM ICE keyslot accounting and virtual-to-physical slot translation. + * The implementation owns the slot allocation table and is registered once + * at platform driver probe time. + * + * @profile is passed to every callback so an implementation supporting + * multiple storage controllers can distinguish between them. + * + * All callbacks may be called concurrently and must not sleep (called + * under RCU read lock). + */ +struct bcp_slot_virt_ops { + /** + * @get_guest_slots: Return the number of ICE keyslots allocated to @gues= t_id. + * + * Returns the slot count (=E2=89=A5 1) on success, -ENOKEY if @guest_id = is + * not in the allocation table. + */ + int (*get_guest_slots)(struct blk_crypto_profile *profile, u32 guest_id); + + /** + * @vslot_to_pslot: Translate a VM-local virtual slot to a physical slot. + * @guest_id: hypervisor-assigned VM identifier. + * @virt_slot: 0-based slot index within @guest_id's allocation. + * @phy_slot_out: receives the physical ICE keyslot index on success. + * + * Returns 0 on success, -ENOKEY if @guest_id is unknown, -EINVAL if + * @virt_slot >=3D the VM's allocation. + */ + int (*vslot_to_pslot)(struct blk_crypto_profile *profile, + u32 guest_id, u32 virt_slot, + unsigned int *phy_slot_out); +}; + +/** + * bcp_register_slot_virt_ops() - register the slot-virt op-set + * @ops: op-set to register; must remain valid until unregistered. + * + * Returns 0 on success, -EBUSY if an op-set is already registered. + */ +int bcp_register_slot_virt_ops(const struct bcp_slot_virt_ops *ops); + +/** + * bcp_unregister_slot_virt_ops() - unregister the slot-virt op-set + * @ops: must be the pointer passed to bcp_register_slot_virt_ops(). + * + * Blocks until all in-flight callers have finished, then clears the + * registration. Safe to call from module exit. + */ +void bcp_unregister_slot_virt_ops(const struct bcp_slot_virt_ops *ops); + +#endif /* __LINUX_BLK_CRYPTO_PROXY_H */ diff --git a/include/uapi/linux/blk-crypto-proxy.h b/include/uapi/linux/blk= -crypto-proxy.h new file mode 100644 index 000000000000..dc8adc8ef5ed --- /dev/null +++ b/include/uapi/linux/blk-crypto-proxy.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +#ifndef __UAPI_LINUX_BLK_CRYPTO_PROXY_H +#define __UAPI_LINUX_BLK_CRYPTO_PROXY_H + +#include +#include + +#define BCP_DIR_READ 0 +#define BCP_DIR_WRITE 1 + +/* + * BCP_BIND_CONTEXT - bind a host block device and hypervisor VM fd. + * + * Must be called once after open(), before any other ioctl. + * Returns -EBUSY if already bound, -EOPNOTSUPP if no hypervisor op-set + * is registered. + * + * @block_dev_fd: fd of the host block device to bind. + * @vm_fd: hypervisor VM fd identifying the guest. + * @reserved: must be zero. + */ +struct bcp_bind_context_arg { + __s32 block_dev_fd; + __s32 vm_fd; + __u32 reserved; +}; + +/* + * BCP_GET_CRYPTO_CAPS - query crypto capabilities of the bound block devi= ce. + * + * Requires BCP_BIND_CONTEXT; returns -ENXIO otherwise. + * + * @key_types_supported: [out] BLK_CRYPTO_KEY_TYPE_* bitmask. + * @max_dun_bytes: [out] maximum DUN bytes supported. + * @max_slots: [out] maximum ICE keyslots available for the bou= nd VM; + * 0 if the VM is not found in the table. + * @num_modes: [in] capacity of the buffer pointed to by @modes= _ptr, + * in entries. [out] number of entries actual= ly + * written to @modes_ptr (may be less than the + * given capacity; the caller must use this + * value, not its own capacity, to know how m= any + * entries are valid). + * @modes_ptr: [in] pointer to a caller-allocated __u32 array = of + * at least @num_modes (as given) entries. Mu= st + * be non-NULL if @num_modes (as given) is > = 0. + * On return, holds a per-mode data_unit_size + * bitmask array indexed by VIRTIO_BLK_CRYPTO= _MODE_* + * (virtio wire numbering, uapi/linux/virtio_= blk.h) + * -- NOT by enum blk_crypto_mode_num. Index = 0 is + * reserved and always 0, matching struct + * virtio_blk_crypto_modes.modes[]. + * + * @modes_ptr is a pointer + count rather than a fixed-size array embedded= in + * this struct so that sizeof(struct bcp_get_crypto_caps_arg) -- and hence= the + * _IOWR-encoded ioctl number -- does not depend on VIRTIO_BLK_CRYPTO_MODE= _MAX. + * The caller and this kernel may be built against different virtio_blk.h + * versions (and thus different values of that constant); embedding a + * VIRTIO_BLK_CRYPTO_MODE_MAX-sized array directly in this struct would ma= ke + * the ioctl fail to even dispatch (-ENOTTY) whenever the two disagree. + */ + +struct bcp_get_crypto_caps_arg { + __u32 key_types_supported; + __u32 max_dun_bytes; + __u32 max_slots; + __u32 num_modes; + __aligned_u64 modes_ptr; +}; + +/* + * BCP_SUBMIT_IO_BY_VSLOT - submit an encrypted bio using a virtual slot. + * + * The kernel resolves virt_slot to a physical ICE keyslot and submits the + * I/O synchronously. Large requests are split at data-unit boundaries + * (BIO_MAX_VECS pages per bio). Requires BCP_BIND_CONTEXT; returns -ENXIO + * otherwise. + * + * @virt_slot: guest-visible slot index (0-based within the VM's= range). + * @direction: BCP_DIR_READ or BCP_DIR_WRITE. + * @flags: must be BCP_SUBMIT_IO_F_IOV. + * @data_unit_size_bits: log2 of the encryption data unit size in bytes. + * @sector: start sector (512-byte units). + * @dun: data unit number (single 64-bit limb, little-endi= an). + * @iov_ptr: pointer to scatter-gather array of struct bcp_iov= ec. + * @iov_cnt: number of entries in @iov_ptr[]. + * @reserved2: must be zero. + * + * @sector, @dun and @iov_ptr use __aligned_u64 to guarantee identical str= uct + * layout between 32-bit and 64-bit callers, as required by + * .compat_ioctl =3D compat_ptr_ioctl. + */ + +/* Maximum iovec segments per BCP_SUBMIT_IO_BY_VSLOT call (matches UIO_MAX= IOV). */ +#define BCP_MAX_IOV 1024 + +#define BCP_SUBMIT_IO_F_IOV (1U << 0) /* scatter-gather mode; must alwa= ys be set */ + +struct bcp_iovec { + __u64 iov_base; + __u64 iov_len; +}; + +struct bcp_submit_io_by_vslot_arg { + __u32 virt_slot; + __u32 direction; + __u32 flags; + __u32 data_unit_size_bits; + __aligned_u64 sector; + __aligned_u64 dun; + __aligned_u64 iov_ptr; + __u32 iov_cnt; + __u32 reserved2; +}; + +#define BCP_IOC_MAGIC 0xC7 + +#define BCP_BIND_CONTEXT _IOW(BCP_IOC_MAGIC, 1, struct bcp_bind_cont= ext_arg) +#define BCP_GET_CRYPTO_CAPS _IOWR(BCP_IOC_MAGIC, 2, struct bcp_get_cryp= to_caps_arg) +#define BCP_SUBMIT_IO_BY_VSLOT _IOW(BCP_IOC_MAGIC, 3, struct bcp_submit_i= o_by_vslot_arg) + +#endif /* __UAPI_LINUX_BLK_CRYPTO_PROXY_H */ --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 1618C48CD41 for ; Thu, 27 Aug 2026 16:08:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846928; cv=none; b=ASseKZXF+pBmbIQvWJEJx9iClBLEgV/VbRUxDpSpcaO4P3vD7ZJbWftfPJKIlnEbpgBbw91hunethOA9QT7/lwIWAtHfXHzEo9o/sWJDf2Zs98xcaxgclwEtkjwY04CY8rZL5IBSc69WJDNLN9SuCjlSBt4CohIK1cAc7zlzBmA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846928; c=relaxed/simple; bh=I8krKhJahgIEJ7HiEH76lvoj/BYjFhFqiLB5U5WP74A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=K/xrS7SLjJVc3blaoL1dzRzeu1yjJArxKnwqv0EhGSvu+hLAuEOlnFWMKh7nrqAcM6LqMii4GUrb7YwoeJEtjattTqFJCvbAzLYqLi1ZlpVOQaTZwfMwDjllzdM4lFLg8KAg3+26/oKuQuNqQ36k9tXfwQEYj8xlTU4whCxxFUs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=JVwY129Y; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Yf1cJ+Si; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="JVwY129Y"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Yf1cJ+Si" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFbnNm058917 for ; Thu, 27 Aug 2026 16:08:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= IPlM6Y0iVHV+fOjO00taADkuu2MuBiXuc3s9hjMOFU0=; b=JVwY129YOPuk83p1 OS9RZY4wq1W/fBzbVhYuzQ46IQYLJu9nhcJJE3s/iD58RZC46hZDN3V9kJ3WjGOs hWPlvWLjLUQ0T22iu+0H4ntZykCjCuf2OaAcjGenuInkJrWOeCUlLVEKSNUDx9nP B4YyI+t7M/DENNv+8QgnCzMs4sg6DtTTSwdgGZ1PDwXzvXcUJMvvja9rHLz5hsH6 33R0G2Ko8JB+pczAODx9Z9UsnljogPXcdL+eVMH3u50OiGsgNXOr8e7MICq9OOjw gfjl46ekKYQ47F+KzWahu7RUDq5W7u5DRom1anSB+zQ58GtxwMEVTHOOQdTwI/n4 UIvvxA== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gak561ave-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:44 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-396b9ef3070so118385a91.3 for ; Thu, 27 Aug 2026 09:08:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846924; x=1788451724; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=IPlM6Y0iVHV+fOjO00taADkuu2MuBiXuc3s9hjMOFU0=; b=Yf1cJ+SiB3vfFdmzAG8nrRfC1a7IxlnjCVmLy8JBKYEdPsdTohMGFkpcMsCtQBghpZ 9cAjZLQwHNT5bSmqTNW8rvrCfRFLEzrZabhg8CnWtbn4UmL0HZk7lxFp6bmHzjVAp/bd b83Rb6m+G87vIG2v5HozOammRTq6tFcq0lt/Cz3GNkY0EI6iJYMdIPT0kGAGVbwZ+Kyh tyTTRhEdc/sL4j+eN5NkYlqgDWCcua6xKVb6Ms9K4xuN+k23Mh1fsGdg2jcX0jfaNpdm uZ8ZxwpRmp676dCSPddp9/MnR3mTqimC6j/yWVPClaW+FIbWrajMS9s8bEYU/aGO/w5W 2lcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846924; x=1788451724; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=IPlM6Y0iVHV+fOjO00taADkuu2MuBiXuc3s9hjMOFU0=; b=d+Rgs/LK92NI4LvSURP4MWkt+KPfRoOL/+cr3VaTlrJ/0pNj/e7opYdrXwJxXcChjj 0YUFUyAlroNh95tS/aZGZi3Jak0dENUp7g0C1z3+MvHUt9KXUkJsaiX+0a0L7eHSJU3u j6gXosN6H/X4jMRVgIwpjp02EIAx/6PE7xyGkezn7myEiz4mJzrxlPBY7A4b4HEnUxKp zkdXwDh6fuZcL9VM1Ts9X5R5x8usDeKBePRJk5qmkaPMRO9jHd8LH1pjLoyukL3J9au7 8XVkILEgA2N0EAik8ljF2rJZrHVQjrCGn3WMbNWNDskbnaJFwnwxcprAlRaSbo/58LZK ORng== X-Forwarded-Encrypted: i=1; AHgh+RqbnUvlWYVdjN2gWib20jQkoGjbfAUJ4LcQ0vS/jblmxFwM6n4IlsxRX8Y3cq4PJx8uEMgTQIYUeaJ954g=@vger.kernel.org X-Gm-Message-State: AFuF++mI44XLsogEuuyB/hftD97Wxj3SE1sfwJj8ZJoDhB/CCkLgoY2X nqrED1Fn0La0i7TbYTxcS17bzzFXgP8gerEWbSWNiubH8k8Y4Mf8pQc/Oyi3WApeVtn0krAYxlR vNywj0AMLZXvdgOpAzgkv9QJ9kOGbEgYiQm0/teyoswYV+pt52mrMU8lAMgQYFy/2SR8= X-Gm-Gg: AR+sD10/nS1w8jOjuSXMqAIfvF0c/XNgIiuJyseNcoV/BnyMVdJgKhnQrwhyLYopLsn hsjS42Y66BM5SJONx0mSXOigV9K42ByIcb4vVxvKZxXBQ0aXwKUA4h3VAGIG/CiUMaRmSu7fimH dr4Pkk30+QrSDyCwcSleywuXZGGrcFy9L+UfpoGDRMQNT77HV99ioqpL6JU7mix7KbrIpbeco7J wlK6TUCL8dElCAoV8hOnYdkI/oq0Ltv1mHZWhSaD/dehyscXrAyZq32DRFGFsN9S7b7zVcqGQif gkodxdnoD4TuzTdyZtAYXi7R2LsMWY66u/rs5tK2Vuf9IYzocOhj1PSRLJKZHmyiYXNC6fntC3F 9gnR748dsmAxXZN9SaaE1BNkmmwgX+pk6VTHe4tYw+Zh0wilqcpxq9Wgt7eo= X-Received: by 2002:a17:90b:4d0c:b0:37f:c97a:939f with SMTP id 98e67ed59e1d1-396d0dd5069mr450678a91.7.1787846922302; Thu, 27 Aug 2026 09:08:42 -0700 (PDT) X-Received: by 2002:a17:90b:4d0c:b0:37f:c97a:939f with SMTP id 98e67ed59e1d1-396d0dd5069mr450573a91.7.1787846921737; Thu, 27 Aug 2026 09:08:41 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:41 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 09/11] soc: qcom: add ICE keyslot partitioning driver for guest VMs Date: Thu, 27 Aug 2026 09:07:18 -0700 Message-ID: <20260827160806.1295313-10-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX9CLvtAvRNSmW 6TItZNUfPo1D7geSISsxl+m7vc1IRULuAX0xWaAWh/TKqJ3sIzb8vWeRTnqHCvrRwJjEIYyiOuR 0sVVI1ywGyaAHBSXKt5c+TUdoVYCFF0= X-Proofpoint-ORIG-GUID: mjFzdtMr6yAlKGH0_mrCXU6KDs9sbYN1 X-Proofpoint-GUID: mjFzdtMr6yAlKGH0_mrCXU6KDs9sbYN1 X-Authority-Analysis: v=2.4 cv=G+Ms1dk5 c=1 sm=1 tr=0 ts=6a90610c cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=w3opuUzClo5xMoDqJE4A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfXzMycqYdr8dI4 ewFyapY9YdtHWzCP/O1oXeJAKx+faON56qen5nP7mN5JRsMSN24t0ZOZ54nFWncU6879UR9rin/ grE/f/Hm/lzMaCnjxfGqT5PlXXAY0bF5VMYrZ0hEs20DfwktnQeqITSBCJxXePS/Ug4GIfrvaWZ ULXwDuEkPkhCcc8w33YEoHK5NrreSiJhBt9VZkIduMukcR4rZw2DdEhMHg7k+h4Mx1BDqQnRSqo qtX9Mk0POQic5yBgkKZzTB03amH2JQgBJ3zO1VZNba23X+/KltkFgnUAjVFTN7/cBaLImlwQ8/X iVhyToFk3I2y7l9uhLyWl9fl5Y03fhaZnC9mH1zfgzVsgZfkvoabOvAFnZNByFA2AN2+bf1iqsv GHMOrrYtZKN3ejNXXYzqIo6Kh5rGCS2EKDidpx3cwR/veqnfxN1qT1CQyxxD9an90gnGKvux1Rq C+MUsQwIRBKWo27pfhw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 clxscore=1015 bulkscore=0 phishscore=0 spamscore=0 impostorscore=0 malwarescore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 From: linlzhan On Qualcomm platforms the ICE hardware has a fixed number of physical keyslots shared across the host and all guest VMs. A userspace virtio-blk backend handling VIRTIO_BLK_T_CRYPTO_IN/OUT requests needs to translate a guest's virtual keyslot index to the corresponding physical ICE keyslot without letting one VM access another VM's slots. Add QCOM_ICE_SLOTS, a platform driver that implements bcp_slot_virt_ops for the /dev/blk-crypto-proxy device. It parses a qcom,ice-keyslot-map device-tree node describing the per-VM keyslot allocation table, where each child entry maps a guest_id to a contiguous physical slot range [slot_offset .. slot_offset + max_ice_slots). Entry 0 is reserved for the host; guest entries start at index 1 and are excluded from the guest-facing translation so that blk-crypto-proxy cannot accidentally route a guest request into the host's physical keyslots. The driver exposes two callbacks: get_guest_slots() =E2=80=94 return the number of ICE keyslots allocated = to a given guest_id; used by BCP_GET_CRYPTO_CAPS to populate the max_slots field in the virtio config space. vslot_to_pslot() =E2=80=94 translate a (guest_id, virtual-slot) pair to= the corresponding physical ICE keyslot index; used by BCP_SUBMIT_IO_BY_VSLOT before calling bio_crypt_set_ctx_by_slot(). The singleton pointer to the parsed table is RCU-protected; the hot path reads it lock-free. Probe validates that no two VM entries share a guest_id or overlapping physical slot ranges. Note: This patch is submitted for visibility. The keyslot partitioning is based on the current DT-based keyslot allocation with vm_id known. We are aware this may be revised to use a TZ SCM query interface in a future version of this series, submit it RFC for design discussion. Signed-off-by: linlzhan --- drivers/soc/qcom/Kconfig | 18 +++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/qcom_ice_slots.c | 232 ++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/soc/qcom/qcom_ice_slots.c diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 6c632d114d45..e1f383b4dc63 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -294,6 +294,24 @@ endif # Options selected by other drivers from different subsystems must be outs= ide # of the menuconfig if-block: =20 +config QCOM_ICE_SLOTS + tristate "Qualcomm ICE keyslot partitioning for VM guests" + depends on ARCH_QCOM || COMPILE_TEST + depends on BLK_CRYPTO_PROXY + depends on BLK_INLINE_ENCRYPTION + help + Parses the qcom,ice-keyslot-map device-tree node and provides + per-VM ICE keyslot accounting and virtual-to-physical slot + translation for guest VMs sharing ICE hardware on Qualcomm + platforms. + + When enabled, guest virtual keyslot indices are mapped to the + physical ICE keyslot range allocated to each VM, preventing one + VM from accessing another VM's keyslots. + + Say M here when multiple VMs share ICE keyslots on a Qualcomm + platform. If unsure, say N. + config QCOM_INLINE_CRYPTO_ENGINE tristate select QCOM_SCM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 6d4b7546d1fb..952a57554f9d 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_QCOM_LLCC) +=3D llcc-qcom.o obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=3D kryo-l2-accessors.o obj-$(CONFIG_QCOM_ICC_BWMON) +=3D icc-bwmon.o qcom_ice-objs +=3D ice.o +obj-$(CONFIG_QCOM_ICE_SLOTS) +=3D qcom_ice_slots.o obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE) +=3D qcom_ice.o obj-$(CONFIG_QCOM_CRYPTO_VIRT) +=3D crypto_virt.o obj-$(CONFIG_QCOM_PBS) +=3D qcom-pbs.o diff --git a/drivers/soc/qcom/qcom_ice_slots.c b/drivers/soc/qcom/qcom_ice_= slots.c new file mode 100644 index 000000000000..364ac93077c1 --- /dev/null +++ b/drivers/soc/qcom/qcom_ice_slots.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * qcom_ice_slots.c - Qualcomm ICE keyslot partitioning for guest VMs + * + * Implements bcp_slot_virt_ops: translates a (guest_id, virtual-slot) pai= r to + * a physical ICE keyslot index using a per-VM allocation table parsed from + * the device-tree node with compatible =3D "qcom,ice-keyslot-map". + * + * Device-tree layout: + * + * ice_keyslot_map: ice-keyslot-map { + * compatible =3D "qcom,ice-keyslot-map"; + * #address-cells =3D <1>; + * #size-cells =3D <0>; + * + * vm@3 { reg =3D <3>; qcom,max-ice-slots =3D <16>; qcom,ice-slot-= offset =3D <0>; }; + * vm@52 { reg =3D <52>; qcom,max-ice-slots =3D <32>; qcom,ice-slot-= offset =3D <16>; }; + * }; + * + * Each child entry maps a guest (reg =3D guest_id) to a contiguous physic= al keyslot + * range [slot_offset .. slot_offset + max_ice_slots). + * + * Entry 0 is always the host's own reservation. Entries 1+ are guest + * reservations. The host's entry is used by ufs-qcom to size its + * blk_crypto_profile; it is excluded from the guest-facing translation ta= ble + * so that blk-crypto-proxy can never accidentally route a guest request i= nto + * the host's physical keyslots. + * + * The ufs-qcom driver reads the host slot info and validates all entries + * against the hardware slot count directly via the OF API, with no symbol + * dependency on this module. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define QCOM_ICE_SLOTS_MAX_ENTRIES 8 + +struct qcom_ice_slot_entry { + u32 guest_id; + u32 max_slots; + u32 slot_offset; +}; + +struct qcom_ice_slots { + struct qcom_ice_slot_entry entries[QCOM_ICE_SLOTS_MAX_ENTRIES]; + unsigned int num_entries; +}; + +/* + * There is at most one qcom,ice-keyslot-map platform node per SoC. A sin= gle + * global pointer is set at probe time and cleared at remove time. The + * hot-path read (from bcp_slot_virt_ops callbacks) is protected by RCU; + * probe/remove serialise via the platform driver guarantee. + */ +static struct qcom_ice_slots __rcu *g_ice_slots; + +static struct qcom_ice_slots *virt_lookup(struct blk_crypto_profile *profi= le) +{ + /* Single UFS controller: profile argument is not needed. */ + return rcu_dereference(g_ice_slots); +} + +static int qcom_ice_slots_get_guest_slots(struct blk_crypto_profile *profi= le, + u32 guest_id) +{ + struct qcom_ice_slots *virt =3D virt_lookup(profile); + unsigned int i; + + if (!virt) + return -ENOKEY; + + /* entries[0] is the host; guest entries start at index 1. */ + for (i =3D 1; i < virt->num_entries; i++) { + if (virt->entries[i].guest_id =3D=3D guest_id) + return virt->entries[i].max_slots; + } + return -ENOKEY; +} + +static int qcom_ice_slots_vslot_to_pslot(struct blk_crypto_profile *profil= e, + u32 guest_id, u32 virt_slot, + unsigned int *phy_slot_out) +{ + struct qcom_ice_slots *virt =3D virt_lookup(profile); + unsigned int i; + + if (!virt) + return -ENOKEY; + + for (i =3D 1; i < virt->num_entries; i++) { + if (virt->entries[i].guest_id !=3D guest_id) + continue; + if (virt_slot >=3D virt->entries[i].max_slots) + return -EINVAL; + *phy_slot_out =3D virt->entries[i].slot_offset + virt_slot; + return 0; + } + return -ENOKEY; +} + +static const struct bcp_slot_virt_ops qcom_slot_virt_ops =3D { + .get_guest_slots =3D qcom_ice_slots_get_guest_slots, + .vslot_to_pslot =3D qcom_ice_slots_vslot_to_pslot, +}; + +static int qcom_ice_slots_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct device_node *child; + struct qcom_ice_slots *virt; + unsigned int idx =3D 0, total_slots =3D 0; + int ret =3D 0; + + virt =3D devm_kzalloc(dev, sizeof(*virt), GFP_KERNEL); + if (!virt) + return -ENOMEM; + + for_each_child_of_node(dev->of_node, child) { + u32 guest_id, max_slots, slot_offset; + unsigned int j; + + if (idx >=3D QCOM_ICE_SLOTS_MAX_ENTRIES) { + dev_err(dev, "too many vm entries (> %u)\n", + QCOM_ICE_SLOTS_MAX_ENTRIES); + ret =3D -EINVAL; + of_node_put(child); + goto err_free; + } + + if (of_property_read_u32(child, "reg", &guest_id)) + continue; + if (of_property_read_u32(child, "qcom,max-ice-slots", &max_slots)) + continue; + if (of_property_read_u32(child, "qcom,ice-slot-offset", &slot_offset)) { + dev_err(dev, "missing qcom,ice-slot-offset for guest_id=3D%u\n", + guest_id); + ret =3D -EINVAL; + of_node_put(child); + goto err_free; + } + + if (idx > 0 && + slot_offset < + virt->entries[idx - 1].slot_offset + + virt->entries[idx - 1].max_slots) { + dev_err(dev, "slot overlap: guest_id=3D%u overlaps guest_id=3D%u\n", + guest_id, virt->entries[idx - 1].guest_id); + ret =3D -EINVAL; + of_node_put(child); + goto err_free; + } + + for (j =3D 0; j < idx; j++) { + if (virt->entries[j].guest_id =3D=3D guest_id) { + dev_err(dev, "duplicate guest_id=3D%u\n", guest_id); + ret =3D -EINVAL; + of_node_put(child); + goto err_free; + } + } + + virt->entries[idx].guest_id =3D guest_id; + virt->entries[idx].max_slots =3D max_slots; + virt->entries[idx].slot_offset =3D slot_offset; + total_slots +=3D max_slots; + idx++; + } + + if (idx =3D=3D 0) { + dev_err(dev, "no VM entries found in qcom,ice-keyslot-map\n"); + ret =3D -EINVAL; + goto err_free; + } + + virt->num_entries =3D idx; + + /* + * Publish the singleton. From this point on, bcp_slot_virt_ops + * callbacks can resolve virt via rcu_dereference(g_ice_slots). + */ + rcu_assign_pointer(g_ice_slots, virt); + + ret =3D bcp_register_slot_virt_ops(&qcom_slot_virt_ops); + if (ret) { + dev_err(dev, "failed to register slot_virt_ops: %d\n", ret); + goto err_free; + } + + dev_info(dev, "registered: %u VMs, %u total ICE slots\n", + idx, total_slots); + return 0; + +err_free: + return ret; +} + +static void qcom_ice_slots_remove(struct platform_device *pdev) +{ + bcp_unregister_slot_virt_ops(&qcom_slot_virt_ops); + /* + * Clear the singleton under RCU so that any concurrent ioctl that + * already took the read lock and is mid-lookup sees either the old + * valid pointer or NULL, never a freed pointer. + */ + rcu_assign_pointer(g_ice_slots, NULL); + synchronize_rcu(); +} + +static const struct of_device_id qcom_ice_slots_of_match[] =3D { + { .compatible =3D "qcom,ice-keyslot-map" }, + {} +}; +MODULE_DEVICE_TABLE(of, qcom_ice_slots_of_match); + +static struct platform_driver qcom_ice_slots_driver =3D { + .probe =3D qcom_ice_slots_probe, + .remove =3D qcom_ice_slots_remove, + .driver =3D { + .name =3D "qcom-ice-slots", + .of_match_table =3D qcom_ice_slots_of_match, + }, +}; +module_platform_driver(qcom_ice_slots_driver); + +MODULE_DESCRIPTION("Qualcomm ICE keyslot partitioning for guest VMs"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 DEA0548CD52 for ; Thu, 27 Aug 2026 16:08:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846929; cv=none; b=KfoJvJhFeznDSipRE5QaoNm7LvpCwRqeCwtwzjus4ML+7e1k0vkO8fWLLSslTXLfecMV6BYoVA7AzfYSZR5N3feNMBHHqXcnOSdC6M2wWmGlnMajbz4fXBfFJC8VFkOeM7oufx/Yi2MWbOyNaGTy+/gh/WofE3pyExnTM2CKtt0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846929; c=relaxed/simple; bh=oEtNN5KbRNMq2h6V0CnWjra0k2iO7Ns7CsfkpVo5D98=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J7mBDpWjH7Poae97PegeEs3PCl050pmAktFAuSMkCTa9c1oRR2IQQ7jGPoqjBAt8Qr1DHXB6t+ilAAdhgeIcVWfZSDNdNJvww+Ywjk9DUYdabhPR10e5dvy8130oPzd9HhyrLrm1YRxbi6pC/GT4akX3a5k2pCk92oc1FmNcWFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=IfYIo5+k; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=AykN1gel; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="IfYIo5+k"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="AykN1gel" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFbrY5297090 for ; Thu, 27 Aug 2026 16:08:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= HqmAgGVZ9+r6xr3Nv5npOlTiLJ6Hzk9Y3TXQVd3sS28=; b=IfYIo5+kqfBeFtH0 9uxPPIAJR780978nDcAC6P/1YM8DV6C5OpsrJZjy5TSFsc2PiuTSLr0Ir5FncXMt 9mo+/bkHeLBlgNUxW8gfskKFe1R153+UvqnVyl8WcE49lOz86p0I3d8iZWJ4DfRu 36SFyc0GUxgPnzrCU5BSFyOfeJOVMTd/zLo3nqOIHRVlLBffFhJDWyUtRjDB3dDY fYWwZkudddJhWwLehMItDyJoCcZX2WQpXz2oQsqyzaHAODMcdU3Jp+6vNIkE+Xmj KOFlbY1fPe/4lbXKjdsV0lMWD4URv8h0QuoCHVANrTtFGxp0BBUsSYSMLEBZfwEu GFFIMw== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gam6fh45x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:45 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-388cfc4848dso107069a91.3 for ; Thu, 27 Aug 2026 09:08:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846925; x=1788451725; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=HqmAgGVZ9+r6xr3Nv5npOlTiLJ6Hzk9Y3TXQVd3sS28=; b=AykN1gelGBfBRZb2WKIs1o069CiCOjXNYERGWXir1RobUL/0W67+b+1bXqvHKT0l7X AbEAhjOnpHB2aDgvAbmLuFQbvSBq0lIXt5Siizjuzg8dUZwk7+Qt3Cjj6+IBDeADvXIl zNIqyUhthbQIRJRXvhQLBTGVmADIL9JRqTb/ORTxyOnElLDOMhvJSpbpf4J3kuKiJPlv QCUjS+jlGKDVi8q0h0PqhlktKvO+dWjIUOgyaK6lXfZhsRqBAulEbViFS2+bq1UHGocL zKbFYAhIg7l2ri7qyxmP1MEOzbnROz9MMAUxsQsVB3LBjg5UTE+dWFUPlZA20PoY+q0H oVww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846925; x=1788451725; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=HqmAgGVZ9+r6xr3Nv5npOlTiLJ6Hzk9Y3TXQVd3sS28=; b=aF8cNeu/+SRVfKbn0SO8XENq7CgJF8U/M/Qspg9M3DyFQxS3hvqEPDqgoCXIwKxrdR bz6AjpvhrXgE9nrTGoGKlhblDd0At7Cu8WhS+her1QYRNC10HCk2Ly5LjjZtyiqIfLiC 0+XDWBRt73B+8JwEJk2w5lTkRNw35nM+8/MV4ER7LZQ3e99O9SHb+jNC3GLjNds2YY5O bcELt+g2Vy4rR30OCHfPK1rv6J2+UZsLSURIp+dA1Di7ZnzA6mvAjykkCsupWw/Jt8SF HNs7Xu9IT+0+MGZ3wWIPmf23q8chm4mlGr0wGTE5jcTvyIVMWaXL9IRazQMFMDgzoB3w YTtw== X-Forwarded-Encrypted: i=1; AHgh+RrJjJjYEhepT0Cg4S3TSzaL1KBETP+WkO5bBUbCc6/BlIqX7TN11IrgtUs+inehlfdSQQRGZyUQIk/+1dg=@vger.kernel.org X-Gm-Message-State: AFuF++lkXW/D8XzrkgMRlQlshtmatGeCrHmCy0c1Ln+N93oiS2PM/o54 M+j/fOpSrMoJa3PzNnSJAOliDOPUde/vdkMBCiZ/0zVndoE6TGsUHajfvaw7vyWb1YLL0q34bMW K4Bn6yMbko1uRZHih6MY1lDT1EuZDJI3qU4gpTxG9CrrcSWg5AcrsQlm0MVoYxF9yn+8= X-Gm-Gg: AR+sD13O9hY+oVSEa6u1kOuEkV9Hosq6/clSE3ITiiuS7aejTEw43YerSLLNKw2XgtH Cp66fMX/ep7S1V5TdcbM92rn9NCt/WcqADFhDyc+jAei6s2MBs8ZiYdmDd6RSfK3di1j+jncqQO q+BkG3fYE8hVFgYCAqxFAhoxPvMGOVGID1RP6AElAbExIvWYuXhTY7gKP4nle9khnBzK/GAVMkK WKNFgUPjphUEVEfsSZ0arHq7lcaD7YoeSH2k/PTA/L3jtiuvy7LQlbd4YLQZGM+nS+TqNH7foZn b1KzQgRCe2u98erKIVjLOn8Bn+iWWCpMJNiOgBIdOKpmIN6R5tXoACKPcA8HojvG7F32Tfyl65M 3SI5GE0f4CSkw01pp5LbrTne+hiQEJq5590R+obfGkTdhLvjurIkugzT9WUE= X-Received: by 2002:a17:90b:2d82:b0:393:194d:5366 with SMTP id 98e67ed59e1d1-396d0f6f8bfmr551940a91.10.1787846924582; Thu, 27 Aug 2026 09:08:44 -0700 (PDT) X-Received: by 2002:a17:90b:2d82:b0:393:194d:5366 with SMTP id 98e67ed59e1d1-396d0f6f8bfmr551806a91.10.1787846924033; Thu, 27 Aug 2026 09:08:44 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:43 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 10/11] blk-crypto: add slot_offset to blk_crypto_profile Date: Thu, 27 Aug 2026 09:07:19 -0700 Message-ID: <20260827160806.1295313-11-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX+BlONjXenPCI rQKPYo243NmZbvQId2+xcsturr0KRQAM/B1vzUIoxpP/wn5b0cNFRnAEX1Sl6YmZ5zEDfIrE4JU Yb+QGkFieXt4pFPvyA5TBPN9HpEUHfo= X-Proofpoint-GUID: 9FENkV1VFroIy4LSBqsSd59jkmQ23RXC X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX0NEO8/KcomFC 2uO4clGkvPUZmH0RYmDldXgiwS54LBWQmu5KvmDGvEPxnJEtgo0Vp/SGLabfwl24qJ/KOQ2DioQ XmXVegYm7q3CCXrxpiUEnRVWl2Zz0LE9VuqwEu9kMM6tvPuHnaaalA7zyRg2jY0DagM9MQ/dQ8m olXa47+M7wgvWupQg3XuOF2d/p8j7/nysdq3BCmdIxa/4h1N9NIgTbFdC+aNbBq6/2gnusckLAo VWUs1RGmxM1ZwiVzJh2xOGCiVs/EeFTV7r1ArY9NvEd6WmdhKLLl2ER4Mgieh1eVykn12eW0Bf0 tquWLukzmZs/5oJXvEcPNVJA3yx1c/DgglJdxRWSmxp4SOQyHIb7Mfp/dZ+z8xVxS73ZV95KIUM QDKtvd6V+ffeY1e1UchgwbWVUS0I0QJc2eERjyqG2sWjSDl8C8hbkNm9KlGs6c75hhnyINWGceR 4f2dNBoWEH98JiE8c5A== X-Authority-Analysis: v=2.4 cv=eIgjSnp1 c=1 sm=1 tr=0 ts=6a90610d cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=cA43FAKIMfXQIL9lPwMA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-ORIG-GUID: 9FENkV1VFroIy4LSBqsSd59jkmQ23RXC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 clxscore=1015 impostorscore=0 malwarescore=0 bulkscore=0 phishscore=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 From: linlzhan On platforms where ICE keyslots are partitioned across the host and guest VMs, the host's physical keyslot range does not necessarily start at slot 0. blk_crypto_keyslot_index() currently returns a 0-based array index, which is wrong for such configurations =E2=80=94 hardware programming requires the physical slot number, not the array position. Add an unsigned int slot_offset field to struct blk_crypto_profile. It defaults to zero (no change for existing drivers) and is set by storage drivers that share ICE hardware across guests. Update blk_crypto_keyslot_index() to add slot_offset to the array index so that callers always receive the correct physical ICE keyslot number to program into hardware. Signed-off-by: linlzhan --- block/blk-crypto-profile.c | 7 ++++--- include/linux/blk-crypto-profile.h | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index 53126c091b0b..64202d64a018 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -218,14 +218,15 @@ blk_crypto_find_and_grab_keyslot(struct blk_crypto_pr= ofile *profile, } =20 /** - * blk_crypto_keyslot_index() - Get the index of a keyslot + * blk_crypto_keyslot_index() - Get the physical index of a keyslot * @slot: a keyslot that blk_crypto_get_keyslot() returned * - * Return: the 0-based index of the keyslot within the device's keyslots. + * Return: the physical ICE keyslot index, i.e. the 0-based position of @s= lot + * within the profile's keyslot array plus @slot->profile->slot_offset. */ unsigned int blk_crypto_keyslot_index(struct blk_crypto_keyslot *slot) { - return slot - slot->profile->slots; + return (slot - slot->profile->slots) + slot->profile->slot_offset; } EXPORT_SYMBOL_GPL(blk_crypto_keyslot_index); =20 diff --git a/include/linux/blk-crypto-profile.h b/include/linux/blk-crypto-= profile.h index 4f39e9cd7576..a9bdc05abfa3 100644 --- a/include/linux/blk-crypto-profile.h +++ b/include/linux/blk-crypto-profile.h @@ -162,6 +162,15 @@ struct blk_crypto_profile { */ struct device *dev; =20 + /** + * @slot_offset: offset added to the slot array index to obtain the + * physical ICE keyslot number. Zero in the common case. Set to a + * non-zero value by storage drivers that share ICE hardware across + * multiple guests, where the host's keyslots do not start at physical + * slot 0. + */ + unsigned int slot_offset; + /* private: The following fields shouldn't be accessed by drivers. */ =20 /* Number of keyslots, or 0 if not applicable */ --=20 2.34.1 From nobody Sun Sep 27 00:36:54 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 959654949F0 for ; Thu, 27 Aug 2026 16:08:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846930; cv=none; b=r+jzoIqUYH12bkepVj9xIm02X7mq3XPCzXEpd9XtizJw0qRwXEHEtVuBU5D/rHi0UaG31gpF2nIWbK4pxCi9H3YrMO8BTp8rFQTkw6zb+AXWJUA1VaJyeMkaLwyDeqRonw+LSCftxvPB7zr8f9ZTCdzaaSZwrXysV2ZLoGU4v9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787846930; c=relaxed/simple; bh=FOQ8uDheGL0RiZyjVAqiRMkhp79Dx5PmAY0sqwohPSE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h0jgF+cn8ovOF1m8bBp2dpscESL7XbunoHiV43i4vpLs43w0lvQbx04KsbhYkxHiG0Zakvj7vbKZCkKZ6SPgrH2Jh94CbCgg9HssvXgBBth2AUT59s4TeoxwLfkJfHXxRlKbE0pHdTyNAQryRuadbaJ3qM57o3TSWvIFjvaHxis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=ngeJ6rmb; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=JsPxNEQs; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="ngeJ6rmb"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="JsPxNEQs" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67RFbhYD865953 for ; Thu, 27 Aug 2026 16:08:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=Gw7Hc5+BlXa fOfOrerU1qnVYYtDHdeXg75QOvio0igY=; b=ngeJ6rmb3+FSRoyW59SrAQKyeBy e0tQQsPJHDCRlxDA2TpQOzKZqQMuSYR0lvNxHQQtzxrhSKYCQUnBMzJI1s7F/cC/ JSVIjvTjHdA1xdr8jElpBGflgaxLFmO08iyP4Id+Y9HvfRSaASv1UmyzDG6yKuoS CHaeGAmrHbXD3csWQXIKMPLkpC2+8fpeovuDbKHudegJBPAkhzLl4sDXj95gcmZp ywejjJY4AhokfhCdLAH76cdmz5mijD6wMh1W2UDf26kmKNhN0kIBQQDz/Qo1jr9R 1t7Q37QVvD7o5Nt/759glFLvhoRc5FmY07a3S44l7cXPRcbsD0Mqb8IGTaw== Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gapgv8m94-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 27 Aug 2026 16:08:47 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-3968dfff779so2181010a91.1 for ; Thu, 27 Aug 2026 09:08:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787846927; x=1788451727; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Gw7Hc5+BlXafOfOrerU1qnVYYtDHdeXg75QOvio0igY=; b=JsPxNEQsCWB6dBXDFHW/KCK7b2m/fW+Dq3iCc0zJ3/z9vqOzh4QBt7+zw/4PnLgLuK BS+beXEKp60u8eKTTeLZ4fFMKDvEo6FverjBCa0xxlIyb/jkHZ5fECeKnrXTz+j/7Ann wqy/+FYWJEuuwp9ejEgIszpyTLEvtl7Z8UHIuA3iilK6H3T/GhFGIcp97EJlDv8cQafQ otfxp5dpQqOWXX57AnWbxkczxQZFQB17oOMb7BPgppc9u8YmBEAh89BsRp7/P/OX+aAF 7RhBehI95qSmlz4moJn/TKyHhMlIy0zlVaYxjQgk5ByZh8MnO0tQKEl1XnOtb004VLPR YdRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787846927; x=1788451727; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Gw7Hc5+BlXafOfOrerU1qnVYYtDHdeXg75QOvio0igY=; b=fmoBjmFdV7lK6idTVSLqucruFBy8cjaURCrJqxzGqVAu7PYmz6lYircJyhGJNnZtKt H/C3ZENMJqqdTKLZXeuEqmkC8oH4N4DhgT+Uo0hsNKxxpHn3fPMfwDfx4RGoGkeEKFMF 7kdDSSpYMUdD3B9/gVheOKiJA9XEBrvGp/8176DdnXentBjCLII1aO6747iuaDVwizRZ 1WjS5dPzD76JFWhtRHTwKUTK8PYwtNoIO8I78I5R59yAkpmXdPiocZzwdzAIpO1cGBXy Y2xRClAcm9GPBkEbS8HRTz0O7mAz5D5aYoBSoxwJglbQUWGCGQP4p191Z2dijQVZZpFy l/zw== X-Forwarded-Encrypted: i=1; AHgh+Ro2Tn3T6rwBKvHMeEWvBiJvNzknvQq59/Po7YGS8PWEbQQwhlSK6hNmNkR88jiQxzhnIg/RutOaqzNz8g4=@vger.kernel.org X-Gm-Message-State: AFuF++llFd3hiK+aftcaAVXoSPIdyxGj69X7NN1hstSOSsTfRwsIXQen Y9XNXwOHQ61RcKtQVFoeAtRWyTD89drW1WcBgM8jCK2ghT2fqA+8E4bLVMNTNejXX62dFJsv3ws tZ7kxvwQ5cn9gy0k7WZlrqAx9UMPmeRv6EY621mHfAbRdYz6FyymsOcaOZyry2mtW/gU= X-Gm-Gg: AR+sD11X1yUt+Jg6bm8vIPXXE4SprxGhTcEoz8vXwn7QKiPRB4vJE9SvI7OhMqJ2TM4 wa6O6qyAAAe1tn9FOTxdy8HnzuCXg4NC45M6XNNlxHyOteCU9zHczsD4xl4LrztqH9v+OdMnqFS UDNveX7I7mUnZJnt8M7O+krK5mn3NaeJ9L1azsUujJaF8aTrRtxF+Iex6NK4ICdGoXdtePFXmjp yhT7U4rKYLoom9NCAFVHUjQQrf9+VbShjkAMpSPtjhDi4Euf+26zXb1y2sEeRRJ3HzJozM0rVEV u1Km6R0qmzLy1dvyXbecmCvPWM/wjm+/+8mLKcKpe8n9cUtfiEzQBXw+6ioqBkdnaHXG75QnnJb ikt9w2EsEFbP8YXpGmeNOpuP4hWQda2fxGvob6Vsprwp/X6Vo6l2WKMykAbs= X-Received: by 2002:a17:90b:1dce:b0:38e:9ca8:e99 with SMTP id 98e67ed59e1d1-396d0eba0c5mr359746a91.5.1787846927060; Thu, 27 Aug 2026 09:08:47 -0700 (PDT) X-Received: by 2002:a17:90b:1dce:b0:38e:9ca8:e99 with SMTP id 98e67ed59e1d1-396d0eba0c5mr359631a91.5.1787846926458; Thu, 27 Aug 2026 09:08:46 -0700 (PDT) Received: from u24-san1p10108.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-396b0fd9085sm3245892a91.12.2026.08.27.09.08.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2026 09:08:46 -0700 (PDT) From: Linlin Zhang To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com, jasowangio@gmail.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linux-block@vger.kernel.org, linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org, virtualization@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com, mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org, bvanassche@acm.org, alim.akhtar@samsung.com, avri.altman@sandisk.com, stefanha@redhat.com, pbonzini@redhat.com, eperezma@redhat.com, xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 11/11] scsi: ufs: ufs-qcom: support ICE keyslot partitioning for guest VMs Date: Thu, 27 Aug 2026 09:07:20 -0700 Message-ID: <20260827160806.1295313-12-linlin.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> References: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com> 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 X-Proofpoint-ORIG-GUID: fISEa9CiJWpxapbfgsXFCuhUk_TxZNP1 X-Proofpoint-GUID: fISEa9CiJWpxapbfgsXFCuhUk_TxZNP1 X-Authority-Analysis: v=2.4 cv=FpU1OWrq c=1 sm=1 tr=0 ts=6a90610f cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=JYp8KDb2vCoCEuGobkYCKw==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=Ui157SQb00ZPLHfqI5IA:9 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX9s29tSGaekwC 0DYavBnczHjvFTkOnOMYzalhQO6AaJ8K38ukTNhBeYR9x/xke1e+b5b/sSLXhJ793qjsoCDNYGo UIMfShAArfmFwsNIsAggc1tORkNAWzmU4DznYpw4EKE73fgQoFIvXjPMWaGla3RPnOeKTVp9zg/ fXvUUyqXffRWahxCkygfu/s4FdD4fHpQc43WClb8ARijdN8MwxP5CGAa4AQ45yxxHcXpkrIQwTm THKZe8ib/zNeTqS+JWk617hK9WrwLrqyhB4Aom528KhJYC8cuzzRRVfi5Rd5nEwWd1j8Xgcp+Fp NLTeiq3i/JheytdnUk3W3u/aArNG8JPqx4LXdstLkbHRQ+iO33qTssnUWFNeHrzdN3sz95tZSzB tQ8DZpvCwzR8GFBRcmhuSXBdEIqMJ1xjeNTW3xSbNYftPqHnfrrwlwmw9EA51qTxTRni/cc1QwP IUX3BTFi/qgDeq4J5YQ== X-Proofpoint-Spam-Info: AW1haW4tMjYwODI3MDEzNiBTYWx0ZWRfX+oKtAlzQNjdT MqKHvQoEh3tUrEvaCpXPZM5DAogh02KDSF6Ed2+qvouCD+b1HaJGs4+xMtvkaZYdhaOIVHyOknd 84FLFMlJSj8Q1pTgMtioOQ+RKnOo/pc= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-27_07,2026-08-27_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1011 adultscore=0 suspectscore=0 impostorscore=0 phishscore=0 spamscore=0 bulkscore=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608270136 Content-Type: text/plain; charset="utf-8" From: linlzhan On Qualcomm platforms where UFS inline encryption is shared between the host and guest VMs, the ICE hardware keyslots must be partitioned so that each VM operates only within its own physical slot range. Without this, the host's blk_crypto_profile would manage all hardware slots, conflicting with slots already allocated to guests. Add ufs_qcom_ice_parse_slot_table() to read the qcom,ice-keyslot-map device-tree node. The function parses all child entries and validates that no entry's slot range or the combined total exceeds the hardware slot count from REG_UFS_CCAP. The first child entry is taken as the host's own reservation; its slot count and offset are returned to the caller. In ufs_qcom_ice_init(), use the parsed host reservation to initialize the blk_crypto_profile with only the host's slot count rather than the full hardware range. Set profile->slot_offset so that blk_crypto_keyslot_index() returns the correct physical ICE slot number when programming hardware. If no qcom,ice-keyslot-map node is present, the existing behaviour (profile manages all slots) is preserved. Note: This patch is submitted for visibility. The ufs-qcom driver gets its max_slots and slot_offset based on the the current DT-based keyslot mechanis. we are aware this may need to be replaced by a TZ SCM interface, submit it RFC for design discussion. Signed-off-by: linlzhan --- drivers/ufs/host/ufs-qcom.c | 91 ++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 62396212a0a7..0611ab50f4cc 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -163,6 +163,74 @@ static inline void ufs_qcom_ice_enable(struct ufs_qcom= _host *host) qcom_ice_enable(host->ice); } =20 +/** + * ufs_qcom_ice_parse_slot_table() - parse qcom,ice-keyslot-map DT node + * @dev: UFS controller device + * @hw_max_slots: total physical ICE keyslots reported by REG_UFS_CCAP + * @num_slots: receives host max_ice_slots (0 =3D no partitioning) + * @slot_offset: receives host ice-slot-offset + * + * Parses the qcom,ice-keyslot-map device-tree node. The first child entry + * is the host's own reservation; subsequent children are guest reservatio= ns. + * Validates that no entry's range exceeds @hw_max_slots and that the sum = of + * all entries does not exceed @hw_max_slots. + * + * If no qcom,ice-keyslot-map phandle is present, sets @num_slots to 0 and + * returns 0. Returns -EINVAL if any entry or the total exceeds @hw_max_s= lots. + */ +static int ufs_qcom_ice_parse_slot_table(struct device *dev, + unsigned int hw_max_slots, + unsigned int *num_slots, + unsigned int *slot_offset) +{ + struct device_node *slots_np, *child; + unsigned int total_slots =3D 0; + bool first =3D true; + int ret =3D 0; + + *num_slots =3D 0; + *slot_offset =3D 0; + + slots_np =3D of_parse_phandle(dev->of_node, "qcom,ice-keyslot-map", 0); + if (!slots_np) + return 0; + + for_each_child_of_node(slots_np, child) { + u32 off, max; + + if (of_property_read_u32(child, "qcom,ice-slot-offset", &off) || + of_property_read_u32(child, "qcom,max-ice-slots", &max)) + continue; + + if (off + max > hw_max_slots) { + dev_err(dev, + "ice-keyslot-map: slots [%u..%u) exceed hw max %u\n", + off, off + max, hw_max_slots); + of_node_put(child); + ret =3D -EINVAL; + break; + } + + if (first) { + *num_slots =3D max; + *slot_offset =3D off; + first =3D false; + } + total_slots +=3D max; + } + + of_node_put(slots_np); + + if (!ret && total_slots > hw_max_slots) { + dev_err(dev, + "ice-keyslot-map: total slots %u exceed hw max %u\n", + total_slots, hw_max_slots); + ret =3D -EINVAL; + } + + return ret; +} + static const struct blk_crypto_ll_ops ufs_qcom_crypto_ops; /* forward decl= */ =20 static int ufs_qcom_ice_init(struct ufs_qcom_host *host) @@ -173,6 +241,8 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host) struct qcom_ice *ice; union ufs_crypto_capabilities caps; union ufs_crypto_cap_entry cap; + unsigned int num_slots, slot_offset; + unsigned int hw_max_slots; int err; int i; =20 @@ -192,7 +262,23 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *hos= t) caps.reg_val =3D cpu_to_le32(ufshcd_readl(hba, REG_UFS_CCAP)); =20 /* The number of keyslots supported is (CFGC+1) */ - err =3D devm_blk_crypto_profile_init(dev, profile, caps.config_count + 1); + hw_max_slots =3D caps.config_count + 1; + + /* + * Parse the qcom,ice-keyslot-map DT node: validate all entries against + * the hardware slot count and read the host's own reservation. If no + * partitioning is configured (num_slots =3D=3D 0), the profile manages t= he + * full hardware slot range. + */ + err =3D ufs_qcom_ice_parse_slot_table(dev, hw_max_slots, + &num_slots, &slot_offset); + if (err) { + dev_err(dev, "failed to parse ICE slot table: %d\n", err); + return err; + } + + err =3D devm_blk_crypto_profile_init(dev, profile, + num_slots ? num_slots : hw_max_slots); if (err) return err; =20 @@ -201,6 +287,9 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host) profile->key_types_supported =3D qcom_ice_get_supported_key_type(ice); profile->dev =3D dev; =20 + if (num_slots) + profile->slot_offset =3D slot_offset; + /* * Currently this driver only supports AES-256-XTS. All known versions * of ICE support it, but to be safe make sure it is really declared in --=20 2.34.1