From patchwork Wed Jan 31 17:43:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 194884 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp2053301dyb; Wed, 31 Jan 2024 09:44:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IG2bkIQGdXRWO6oHV9kKOWgxriZYDvnxJCDr4DIR7AnDjpxZ8Zsu6bz29eqQv0Ee7ExeXJO X-Received: by 2002:a05:620a:a59:b0:783:d0ef:49ba with SMTP id j25-20020a05620a0a5900b00783d0ef49bamr133878qka.18.1706723096841; Wed, 31 Jan 2024 09:44:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706723096; cv=pass; d=google.com; s=arc-20160816; b=Xg8r8axRn0pQ0rVpjKTxhRl1nQuH1dlHJZ8D2VQ4/2ALTkq0ubOQ9yX7c6QJKmMkIv bDJ43GtqG/uM0uK6GvEp8fEne6cQtlsUfKgp3XA47dNbJhQwK/YwnBQB0reVsSdPQ3ix kEO3JoUYeBIyURQaj4zNHeBu7v+XSwe7CNpSMXkzIgB+RDuxRIf1i4H2YTe5TGDweQN4 beZ8S0BUUXd3i6YUPBgabndy9gvJABxzTQUj95ADyUda2abWlbTjjvBlDqrRYpp2hg3V EwxTmFHEI1XVvgm5+MHP46sQl88LyQZ8YiwkL6s4d3F25ilXaaxJWiSs0M2AnHoFweM4 ETxA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=cHCmvQ4HM3HYtffO/xIE+CYy/jMxpzrFI5HM00j5Odk=; fh=AOhpejl7BNo03dypZw2nxxw/SgorbkQ/IO9SNGGL57w=; b=m5LdezBH7tMGdPux8+zZgP7MlxUXpkJs7yQ2F3+vZHaSnq8Z/Jtu4lleRtdwajJ3WO sjNkdwZjIteVxGXvAoEu88fKXl3eU2IO8Lm9ehXiTy0xayyNo/g6sv4Mw0Lp83+Ej2zS noYrnExRsAg0sD/v3KgCJB72AV5JkLrHokOUSGPe/yGbzZiBxMRDJwAFrLOYWddzRUrM INr7gpHWiGY1poAZU25baPikCmYcwaBy0EtS/vRkjTAZYTAxoA/0razDe8oPfuQOTxqu +PrCr/2V15FBtFE04JZwa4iJ05APRqzO/I3saOoJ9mA9z9O06TMU67Y7bb8XB2H9jpc5 QtTQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VrNEXOcW; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-46923-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-46923-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org X-Forwarded-Encrypted: i=1; AJvYcCW59z7IV8BUIq2qKVGs/XVMdQb4gkadNsxzZxj9WVCx/egLn5EaZjRk4NWCo+YW9iJ7iLLLrFu4yREMYWsNf8XabhpOdg== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id j21-20020a05620a147500b007812e5a9151si6167159qkl.549.2024.01.31.09.44.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jan 2024 09:44:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-46923-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VrNEXOcW; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-46923-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-46923-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 924F11C2549C for ; Wed, 31 Jan 2024 17:44:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DC9C412FF79; Wed, 31 Jan 2024 17:44:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="VrNEXOcW" Received: from mail-ed1-f44.google.com (mail-ed1-f44.google.com [209.85.208.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12A7D12F580 for ; Wed, 31 Jan 2024 17:44:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706723050; cv=none; b=ndghu8HNautfNfZtr8FGgX7KJ9OYjthQNQ1iCQ8LwpuJ5eXf7u6wY24t+M9ckAARUxzkFJbPBF+Bg66CF50NeG5n3VmCEzfcXsXYpA8ZqCwxVVJ86kPdO+MfwbT546Qi75QiQgQ1a9l33/jP4sGPpxBE1cbxo2WlpuQPYsfC7Us= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706723050; c=relaxed/simple; bh=VSk1r76xIi4SMeq0I2cI7qMzmqTAXAADCa74sT2EN4w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ug+42roZFmyDq9BXhVJLOn4i/qO+ToNwfZMyeXPFYHASfDhAQhiu3csDtJ7qiyJLqCQVoMr+9jzP87LLqd6Bh69coz7p1EU/wrpQuCyvsSbZFVpulR3MtEz304WQhSTjvtwaZJB4hhjMBa0vy0hrjPy3BLkV7WtjRXXHucgTS2Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=VrNEXOcW; arc=none smtp.client-ip=209.85.208.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-ed1-f44.google.com with SMTP id 4fb4d7f45d1cf-55817a12ad8so1805a12.2 for ; Wed, 31 Jan 2024 09:44:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1706723046; x=1707327846; 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; bh=cHCmvQ4HM3HYtffO/xIE+CYy/jMxpzrFI5HM00j5Odk=; b=VrNEXOcWoaLkqto0DOZcoCS01+0CziPzB66kE9b3hyUICZto7bDQpgFBjpx1enpgAW YlrUBmBemYK8SQmOYClBNyRDAqjzf71O05BnMgmSrkQbA73Bt/q0HuPd3e5zR4gTv9n+ DjhXRJ9CwTbxmuJ6og+8T025w8xapZ6/9FqRcm0+AVYWKJAt3inS/OHOvdgBaGroaNDX 0cGQS3AI2aM8cualcUT1u5ECXLa6OSh0nTNaLYC4FyXT055nHbJz4IP68wlFx0KB0XUu UvPYUm8Tf3LJtlyKk9LvSpkAkIQek14inAUiqJP9Mgh29YvNfRHqkEy+qGLD0zr//WqD kmVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706723046; x=1707327846; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cHCmvQ4HM3HYtffO/xIE+CYy/jMxpzrFI5HM00j5Odk=; b=mELmJ3asO2ffE1jLBBMgJwCK+SsGsAgsk27mskHPI1fStFsEj57WQUL4pgCV23aez9 VXCry54IQVNIv/mJHLaERa/qX8u8u8tY007WHEiUlLrgOI6daJtPVrut8QkF43uORziP o/bE81zLLTx+KDpHKbrSQKQB9768W1fhJktJFd1KvULduhFM9wMo11ifp7hsDW1S5YNK GCAKOTtL1bQatUO8YP1g+XXGLWPlvQ+FIXARXI3u9pynDMGZBaejOZ3oBKEvVZZioGv+ /VrwIeu51X0SFBTjvYwSsHmIEhf4/6m1h8lqio/WXVjWscN1FHVwUjq4Vgn8GnbnAfDH Pvew== X-Gm-Message-State: AOJu0YyatuCDddZsgE+3OwNBY899biKdq7oX+j0XbnDWP30f4UkyqiWX fp7qmaebbEkVO7kqeYp1QHZamuZoICkY1PDqZRiX7HPufHo1r982fndVGqa8DDTWgG829mXl4SD u X-Received: by 2002:a50:cd4b:0:b0:55f:6b8:b2fc with SMTP id d11-20020a50cd4b000000b0055f06b8b2fcmr1807622edj.2.1706723045922; Wed, 31 Jan 2024 09:44:05 -0800 (PST) Received: from localhost.localdomain (h-217-31-164-171.A175.priv.bahnhof.se. [217.31.164.171]) by smtp.gmail.com with ESMTPSA id o11-20020a056402444b00b0055d3d1653b3sm5712985edb.31.2024.01.31.09.44.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jan 2024 09:44:05 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, op-tee@lists.trustedfirmware.org Cc: Shyam Saini , Ulf Hansson , Jerome Forissier , Sumit Garg , Ilias Apalodimas , Bart Van Assche , Randy Dunlap , Ard Biesheuvel , Arnd Bergmann , Greg Kroah-Hartman , Jens Wiklander , Tomas Winkler , Alexander Usyskin Subject: [PATCH v2 2/3] mmc: block: register RPMB partition with the RPMB subsystem Date: Wed, 31 Jan 2024 18:43:46 +0100 Message-Id: <20240131174347.510961-3-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240131174347.510961-1-jens.wiklander@linaro.org> References: <20240131174347.510961-1-jens.wiklander@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789628877865015311 X-GMAIL-MSGID: 1789628877865015311 Register eMMC RPMB partition with the RPMB subsystem and provide an implementation for the RPMB access operations abstracting the actual multi step process. Add callbacks for getting and putting the needed resources, that is, the RPMB data and the RPMB disk. Add a callback to extract the needed device information at registration to avoid accessing the struct mmc_card at a later stage as we're not holding a reference counter for this struct. Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Jens Wiklander --- drivers/mmc/core/block.c | 177 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 32d49100dff5..5286e0b3a5a2 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include @@ -163,6 +165,7 @@ struct mmc_rpmb_data { int id; unsigned int part_index; struct mmc_blk_data *md; + struct rpmb_dev *rdev; struct list_head node; }; @@ -2707,6 +2710,169 @@ static void mmc_blk_rpmb_device_release(struct device *dev) kfree(rpmb); } +static void rpmb_op_mmc_get_resources(struct device *dev) +{ + struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); + + /* + * When the MMC card is removed rpmb_dev_unregister() is called + * from mmc_blk_remove_rpmb_part(). That removes references to the + * devices in struct mmc_rpmb_data and rpmb->md. Since struct + * rpmb_dev can still reach those structs we must hold a reference + * until struct rpmb_dev also is released. + * + * This is analogous to what's done in mmc_rpmb_chrdev_open() and + * mmc_rpmb_chrdev_release() below. + */ + get_device(dev); + mmc_blk_get(rpmb->md->disk); +} + +static void rpmb_op_mmc_put_resources(struct device *dev) +{ + struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); + + mmc_blk_put(rpmb->md); + put_device(dev); +} + +static struct mmc_blk_ioc_data **alloc_idata(struct mmc_rpmb_data *rpmb, + unsigned int cmd_count) +{ + struct mmc_blk_ioc_data **idata; + unsigned int n; + + idata = kcalloc(cmd_count, sizeof(*idata), GFP_KERNEL); + if (!idata) + return NULL; + + for (n = 0; n < cmd_count; n++) { + idata[n] = kcalloc(1, sizeof(**idata), GFP_KERNEL); + if (!idata[n]) { + kfree(idata); + return NULL; + } + idata[n]->rpmb = rpmb; + } + + return idata; +} + +static void set_idata(struct mmc_blk_ioc_data *idata, u32 opcode, + int write_flag, u8 *buf, unsigned int buf_bytes) +{ + idata->ic.opcode = opcode; + idata->ic.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + idata->ic.write_flag = write_flag; + idata->ic.blksz = sizeof(struct rpmb_frame); + idata->ic.blocks = buf_bytes / idata->ic.blksz; + idata->buf = buf; + idata->buf_bytes = buf_bytes; +} + +static void free_idata(struct mmc_blk_ioc_data **idata, unsigned int cmd_count) +{ + unsigned int n; + + for (n = 0; n < cmd_count; n++) + kfree(idata[n]); + kfree(idata); +} + +static int rpmb_op_mmc_route_frames(struct device *dev, bool write, u8 *req, + unsigned int req_len, u8 *resp, + unsigned int resp_len) +{ + struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); + struct mmc_blk_data *md = rpmb->md; + struct mmc_blk_ioc_data **idata; + unsigned int cmd_count; + struct request *rq; + int ret; + + if (write) + cmd_count = 3; + else + cmd_count = 2; + + if (IS_ERR(md->queue.card)) + return PTR_ERR(md->queue.card); + + idata = alloc_idata(rpmb, cmd_count); + if (!idata) + return -ENOMEM; + + if (write) { + struct rpmb_frame *frm = (struct rpmb_frame *)resp; + + /* Send write request frame(s) */ + set_idata(idata[0], MMC_WRITE_MULTIPLE_BLOCK, + 1 | MMC_CMD23_ARG_REL_WR, req, req_len); + + /* Send result request frame */ + memset(frm, 0, sizeof(*frm)); + frm->req_resp = cpu_to_be16(RPMB_RESULT_READ); + set_idata(idata[1], MMC_WRITE_MULTIPLE_BLOCK, 1, resp, + resp_len); + + /* Read response frame */ + set_idata(idata[2], MMC_READ_MULTIPLE_BLOCK, 0, resp, resp_len); + } else { + /* Send write request frame(s) */ + set_idata(idata[0], MMC_WRITE_MULTIPLE_BLOCK, 1, req, req_len); + + /* Read response frame */ + set_idata(idata[1], MMC_READ_MULTIPLE_BLOCK, 0, resp, resp_len); + } + + rq = blk_mq_alloc_request(md->queue.queue, REQ_OP_DRV_OUT, 0); + if (IS_ERR(rq)) { + ret = PTR_ERR(rq); + goto out; + } + + req_to_mmc_queue_req(rq)->drv_op = MMC_DRV_OP_IOCTL_RPMB; + req_to_mmc_queue_req(rq)->drv_op_result = -EIO; + req_to_mmc_queue_req(rq)->drv_op_data = idata; + req_to_mmc_queue_req(rq)->ioc_count = cmd_count; + blk_execute_rq(rq, false); + ret = req_to_mmc_queue_req(rq)->drv_op_result; + + blk_mq_free_request(rq); + +out: + free_idata(idata, cmd_count); + return ret; +} + +static int rpmb_op_mmc_set_dev_info(struct device *dev, struct rpmb_dev *rdev) +{ + struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); + struct mmc_card *card = rpmb->md->queue.card; + unsigned int n; + u32 cid[4]; + + for (n = 0; n < 4; n++) + cid[n] = be32_to_cpu(card->raw_cid[n]); + + rdev->dev_id = kmemdup(cid, sizeof(cid), GFP_KERNEL); + if (!rdev->dev_id) + return -ENOMEM; + rdev->dev_id_len = sizeof(cid); + rdev->reliable_wr_count = card->ext_csd.raw_rpmb_size_mult; + rdev->capacity = card->ext_csd.rel_sectors; + + return 0; +} + +static struct rpmb_ops rpmb_mmc_ops = { + .type = RPMB_TYPE_EMMC, + .get_resources = rpmb_op_mmc_get_resources, + .put_resources = rpmb_op_mmc_put_resources, + .route_frames = rpmb_op_mmc_route_frames, + .set_dev_info = rpmb_op_mmc_set_dev_info, +}; + static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, struct mmc_blk_data *md, unsigned int part_index, @@ -2751,6 +2917,14 @@ static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, goto out_put_device; } + rpmb->rdev = rpmb_dev_register(&rpmb->dev, &rpmb_mmc_ops); + if (IS_ERR(rpmb->rdev)) { + pr_err("%s: could not register RPMB device\n", rpmb_name); + ret = PTR_ERR(rpmb->rdev); + rpmb->rdev = NULL; + goto out_cdev_device_del; + } + list_add(&rpmb->node, &md->rpmbs); string_get_size((u64)size, 512, STRING_UNITS_2, @@ -2762,6 +2936,8 @@ static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, return 0; +out_cdev_device_del: + cdev_device_del(&rpmb->chrdev, &rpmb->dev); out_put_device: put_device(&rpmb->dev); return ret; @@ -2770,6 +2946,7 @@ static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, static void mmc_blk_remove_rpmb_part(struct mmc_rpmb_data *rpmb) { + rpmb_dev_unregister(rpmb->rdev); cdev_device_del(&rpmb->chrdev, &rpmb->dev); put_device(&rpmb->dev); }