From patchwork Wed Mar 5 13:04:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002846 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A1AF5C282E5 for ; Wed, 5 Mar 2025 14:33:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=BvA69GRM940nbh4WvjTd5eG8jH1Ow0PBoCzHHS2i3Ls=; b=oJqCGKgcNR+h/eM12LKRKdSJt7 TQmK9lnToo0SWOqNdj5D9cR8NSGuLDZ5fjMEX9h3YI0fjxZC8t1ujFjkiP+6G+t5IDs1gIj8GpbO5 +i0V0oFr3OkhNJ519udXQ9Muqj7sS+zbGFX3CK8fUV83xZ6w0qkdigorMYzkaLr3BDZ6dx03BOGkP MmNPqU6SB/gJtrzp9XWCCkj0JiFU1GfpckgAxslHcXzK/zNYKx2jOQm8kegTE/KWMqQdV7lmCRC9c RmbzwX+M6jhG3jfQgUXx2/EguWbwgUavJCBkwfbyJ4nG6NHN5fP3sOAi6/R5rzecAin5KjBnYPASo 51Qdn4kQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tppob-00000008MZ1-3HoF; Wed, 05 Mar 2025 14:33:41 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSW-000000087pp-0xvH for linux-arm-kernel@bombadil.infradead.org; Wed, 05 Mar 2025 13:06:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=BvA69GRM940nbh4WvjTd5eG8jH1Ow0PBoCzHHS2i3Ls=; b=bHlyUaK/fcslgDBCMsBnVkhDWV s6nrIVDyomuLtA+j1ZoGgAerDn1YG+9+O+Zk9U352NcIx/nDNPcImlxhOxq0Ayfs5pV0xK5acrMul oooEVDj+m/foH4dIKjOh2KCKyOHZiBZfe5V0G3iHiO14U6DkhyHb2ATNwdpm7pFfdwZ3Aze+ONTu/ 4PNT2aIeTy1Zi2XCxr2HCKpIoJJVm0K6QBcA1fTF5nZUZQeHxnHkYgLUMYx3QbMd3ia2WGZ+M6iK7 wmf8lBzrUAbX3gcEi8VJjQ4MstpzkmrJd11DaL6RX+CasQwqBgXs4JYAtlAAPpfSRmKrk0zC3Jp9j BnWvjipw==; Received: from mail-ed1-x52e.google.com ([2a00:1450:4864:20::52e]) by casper.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSS-00000005Xbq-3EID for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:06:47 +0000 Received: by mail-ed1-x52e.google.com with SMTP id 4fb4d7f45d1cf-5e535e6739bso6042662a12.1 for ; Wed, 05 Mar 2025 05:06:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180002; x=1741784802; darn=lists.infradead.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=BvA69GRM940nbh4WvjTd5eG8jH1Ow0PBoCzHHS2i3Ls=; b=zCBHJuRXDoSzOI6CHdVsOQf4lVUORUd/p+AkzSon/d0Hu7Fk/sD+cFgdRoszXijkj4 BVuFkZ56wUb+2pU0//4mti1A5iY+tUsEz+f14YMcL+8ayfgw31IU2o2IArSvV+hgINqM 6zRXXNsnaHzxZzOVGAwPc2QVY1Tbb6/uvoRLozC0PUXL06kEqvUt98+u3chEF50oca4e em0Z89kLFAkVAX8ux7oemYn9N/BaqyF9vfFp6Rnda0r2+wSdg0b5eAS2pVl6YBw7JZxP lXiJCmwhVfehgVJumQ2i2/tj+74e11hzdbOvTKCd5n//32A1laYitcEGB6ge7SKDyJ+w LW9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180002; x=1741784802; 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=BvA69GRM940nbh4WvjTd5eG8jH1Ow0PBoCzHHS2i3Ls=; b=xKtJdfMfkEo463jbIyPMd0AS5dlCII1TZJGtryly503cAs6LSssoeqD7OqB1LAu3oD FquY8sXDGoBoFDRBarNkUgTVxrkFy+yuNrd1BXqECkADMeDQO39reMTa1/P6wLUJHzWw wngb/XXkjzDGUg7hLbTy9rtKMJc7UuaYbflGsxSENxeOvILxf03mRGfeUTNAcHf1coH5 4shVmH+jxxIK4hY5K7b+3g9Kqv0dkAJbnW6SKevNe05SN/uukuWl9/4yt/RGKwDQ0+3K lw50XQlzfPa26FJ91bTP7uhQcfuD1pVXjNTnbYxar3VwHv/3eOYQxy2GHtHUReI0Bo80 KhgQ== X-Forwarded-Encrypted: i=1; AJvYcCWtADKVtD+hke+m1FZvID5pwCBpg+CH563JQb5Zb7WMh6ypbByQZBn923l7DpyLEHBToNnE2LTiu1FvshsZxmvh@lists.infradead.org X-Gm-Message-State: AOJu0YwT34uFmRmFy25YEHaJPwZGxx2vHQKIKZeh1Kf2omKzqpw7lR2r ykQLGgg07ug5DNRRufXxpi8hPlJwktCZ7v4827cP2cKQNqHiQ2W+0R6KZpvt+yU= X-Gm-Gg: ASbGncuWS3v54l+UenGE7ye+HAblYTcyws7pXPDHfxFoYgyf3DjBRN4l2i6qfPyuw7U 5RBWNocIM7URm+WXdchWrBPozTjbPfbaR1yScpkU0n9PKqUYmBfl8YBk9wWhc+LZiOOzjXx2qHX m6KTaV23kFPwMn18JOURYT1B0f7Xa4lTDr+n8fSouZl+xKta40rIdEWmZae1MpXIbuPWUt+d+L/ qx7xsGKPyQB7DvlhklYAfoLn0ngdzdXnFBC1WqQYgvu9Rjt28eLfuh1jVJ5o3EeZ+sVtl5rnkBL i3WnrB89/Mtfx46dxWtAxTlACZ1dybD0d6oUe3IW6jZp+3uARFgaLxawKY+jzdYWHpzzYSiHIk9 nVa37Zlr6sp/xArB1yFq7yA== X-Google-Smtp-Source: AGHT+IEjtiBAYCTH0+e95UXzOpV6Qk/1lP6TuM4iQbwFmlqCq9fGF9wURhaIIhsi+UMHMk8/oJkTeQ== X-Received: by 2002:a50:c8cd:0:b0:5e5:bcd6:4ad8 with SMTP id 4fb4d7f45d1cf-5e5bcd64d5amr155764a12.9.1741180002364; Wed, 05 Mar 2025 05:06:42 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:41 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 01/10] tee: tee_device_alloc(): copy dma_mask from parent device Date: Wed, 5 Mar 2025 14:04:07 +0100 Message-ID: <20250305130634.1850178-2-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_130644_837439_3CE9F887 X-CRM114-Status: GOOD ( 10.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org If a parent device is supplied to tee_device_alloc(), copy the dma_mask field into the new device. This avoids future warnings when mapping a DMA-buf for the device. Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index d113679b1e2d..685afcaa3ea1 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -922,6 +922,8 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc, teedev->dev.class = &tee_class; teedev->dev.release = tee_release_device; teedev->dev.parent = dev; + if (dev) + teedev->dev.dma_mask = dev->dma_mask; teedev->dev.devt = MKDEV(MAJOR(tee_devt), teedev->id); From patchwork Wed Mar 5 13:04:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002701 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 81366C19F32 for ; Wed, 5 Mar 2025 13:28:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=g64carhpN86lM7kPnuUc7tjq3kR3ZxlKeoOmJi6Slgs=; b=nPqfdzu2IWN7M/MZ98W3Mp4oF8 kv2TwYSSaxbDyrIBJxWv4PJxKRQIEJ+OCTuCvcxriKknN+zOrXbi6/FcrwZyeV0jj1X3Oql/zPC3K xzfVPWhJHN2RPIYP9+1++5kv+p45/J7TY2vdMj+YwLmGyUzSh1KwnVXA+fiEzgmxp5lYxGY4MuTkR 341rDPRndseMaMyk4Cr+6X7k0de2xsVKs61E3UlCa7t9zZmPmiLysVZJdPrfab5HeR6trgRvT1xsw uERyojTwJZBZ0pM6D5qfJt7hObTfWeoSpXb+NkyC9b7OBIJ4U2d2lWFqVlHGVEsHGJ2Tafle4NADB L9XkXfLg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpomx-00000008Bpo-2ysy; Wed, 05 Mar 2025 13:27:55 +0000 Received: from mail-ed1-f52.google.com ([209.85.208.52]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSV-000000087pO-0GKW for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:06:48 +0000 Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-5dca468c5e4so593721a12.1 for ; Wed, 05 Mar 2025 05:06:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180005; x=1741784805; darn=lists.infradead.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=g64carhpN86lM7kPnuUc7tjq3kR3ZxlKeoOmJi6Slgs=; b=NLrIQqaRHaOiB3A8w8rDIFDoK4jXiz/L14aoGF7/ztMyzv5ZoEuzhNlptcd1vVEEL2 1oz/sY8RYNmIX/vYIBCTK+YCYg9v++yfAlN0ONH4J/eB+Fao6tjiNmJmqC50BonDPfjD 2wL5Lh7Z3so+x5/UCYBpyeiRHlirhUUi5Eu3r/ppYMBM1CBjvJ7EklJpQcQ+eWGLaOpJ kZJkePInHOvIp5ADAss7AWg4rgAhORfDN46kYyl0p7wa4kSGFCYpUqhd51mF8o+C9GvW hPTv6LuPxCVsK4iAu/h8pksA596WtHhhEqNYOJRMkRPao4HTj9USnGOsMiBu16tPkkT+ QURg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180005; x=1741784805; 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=g64carhpN86lM7kPnuUc7tjq3kR3ZxlKeoOmJi6Slgs=; b=ZzRkHb54/MetCS3FHmFSZ80tNUBcV1Is9Qz3GdncwXPsYKqF8LZfTHGQVBrUD4fdPw WDTiVZ4TR8tvqOmBo+DA93q8WEQBU90fmE6pRU37CHMiPQmYle6LtyjHHNau34+EJZhx Z8+DG35dtzIYGRBI3lMdKR2b+CRRoh3GpS/OQdvm3N/hdUgGJ7n9yxlh8Cy3G1WIsHsh hPBb/P3UUcCrnfrF9da0KWN19DbCvIq+7ta/f+lksYReYaVnB+y6vO7/hD/eqq5Yxkos H+pHBcJYc4YdyHQyz26CULVW/MizWoYhS0UyIUCsuYfY5lsAeHooH50Dg2tyVyjclULr vkNw== X-Forwarded-Encrypted: i=1; AJvYcCWtAriqos2aZzHZbWbny2qTniooNEAb3ensOvAHl2KtQWMuHIePlT9ZMkm8a6gZEdz34nmc3Ro+2LLFZwOf1oCo@lists.infradead.org X-Gm-Message-State: AOJu0YwDCGAsbVaDzGBgW7Oc5dZLjQmL2ql68c6DyF0OpM5hISAeTrSA fy3C55Q/ZlXYj6HeGqYq+3vRNLCEhJ7gfEBlFpYCsUzWVErLAga/USV8HzU8n+Y= X-Gm-Gg: ASbGncv1Ov98bGfkoriuFFTercTUzNNPrqeEiT4atTotPifH0HjJanFrnruBn4QW1oU xjMp/MrmdyEFGCC2ibahoEl5XGS9Sgb+TskNGqIJuzD9Xq5U+7xW7fRkKZOq5/bRLz1XdUxcd3m qb1iq5OJ5ekLu5ieSn+uw4aj+FMQcrFHgNFDaZ88vRhuqX12/xZJKI/YxIWrC6hO1Ioesd+Ers5 amncEqzR1manNZuHnPqQSNw+uxHbhwekIGmoHRqHGRcb7vVVTBNaAULyuP/RCdmXov8QkyZqQRI haz198kCXiF3S2sjDzyDfcwhq0/xFxfM7agZMjfLGmRffikbjKMCkZ1gNNL7jcPeejpa3SPbgEy 9yYp4+O59XyXdfYO4sGRoXw== X-Google-Smtp-Source: AGHT+IHAJQdH7f8KJt+R2ffDvxbc7sUQ+b3jomBMCSiokLRmAxj8briZ+1p+KDuEOOHd7BerJyZSMw== X-Received: by 2002:a05:6402:5203:b0:5e1:9725:bb3e with SMTP id 4fb4d7f45d1cf-5e59f4869femr3345168a12.28.1741180005006; Wed, 05 Mar 2025 05:06:45 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:44 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 02/10] optee: pass parent device to tee_device_alloc() Date: Wed, 5 Mar 2025 14:04:08 +0100 Message-ID: <20250305130634.1850178-3-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_050647_106604_C763EB14 X-CRM114-Status: GOOD ( 13.83 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org During probing of the OP-TEE driver, pass the parent device to tee_device_alloc() so the dma_mask of the new devices can be updated accordingly. Signed-off-by: Jens Wiklander --- drivers/tee/optee/ffa_abi.c | 8 ++++---- drivers/tee/optee/smc_abi.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index f3af5666bb11..4ca1d5161b82 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -914,16 +914,16 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) (sec_caps & OPTEE_FFA_SEC_CAP_RPMB_PROBE)) optee->in_kernel_rpmb_routing = true; - teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool, - optee); + teedev = tee_device_alloc(&optee_ffa_clnt_desc, &ffa_dev->dev, + optee->pool, optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); goto err_free_pool; } optee->teedev = teedev; - teedev = tee_device_alloc(&optee_ffa_supp_desc, NULL, optee->pool, - optee); + teedev = tee_device_alloc(&optee_ffa_supp_desc, &ffa_dev->dev, + optee->pool, optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); goto err_unreg_teedev; diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index f0c3ac1103bb..165fadd9abc9 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1691,14 +1691,14 @@ static int optee_probe(struct platform_device *pdev) (sec_caps & OPTEE_SMC_SEC_CAP_RPMB_PROBE)) optee->in_kernel_rpmb_routing = true; - teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee); + teedev = tee_device_alloc(&optee_clnt_desc, &pdev->dev, pool, optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); goto err_free_optee; } optee->teedev = teedev; - teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee); + teedev = tee_device_alloc(&optee_supp_desc, &pdev->dev, pool, optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); goto err_unreg_teedev; From patchwork Wed Mar 5 13:04:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0137BC19F32 for ; Wed, 5 Mar 2025 13:33:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=tnKwjJ1FVLv4umx37hI66Bb7z/WCUlz7TSg/JWGf0qo=; b=kuZXIgX3Pb9ed4vivFew1GJ5Cn V6wPa+aLgP/QWfvP3TvhzMcaxd+boW4mn6KstoiociR7VrphH1AorEk/3Y+FcuV0n3fnjxjnb9BtB alE4BM/AZivk1SnFbB94R8IPKmCxdN3HOi4unJ1Ne8ecZT8TlSDK7yUZkndcZPyHuct6821nsuySL qRFQle95VZzp92LmfXue80oUVJXPlz+s6WkhQCF61+3W2YxOgvqNmHATsaEtqr+UBVtR2si+gNq2G Y7fOoInT/T2J3QAtkdqkfvt65tcdnqK7P1UljZU6z0Kj8uXSuqFEogsB2FOE6+avs4/RdRyoZFDUQ 7UiUKM6Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tporf-00000008CPY-1EcY; Wed, 05 Mar 2025 13:32:47 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSd-000000087s7-0F9d for linux-arm-kernel@bombadil.infradead.org; Wed, 05 Mar 2025 13:06:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=tnKwjJ1FVLv4umx37hI66Bb7z/WCUlz7TSg/JWGf0qo=; b=GYrY/clUL5UB3jM47HcJag9PU5 rGl4FF8ubw6uqxtXklIIRc4JsZW1UCd435s8oQuHlYKyLKpKMRSuE2UWnQ1n9kX7KFsHF3eXUtWV4 XtSfvm7sNchOhQ7FZ+DAgDfMY9mAEwQi1RsRdCJZTDo8cA80B2eJ89PFaYgF57QeHidP2ZVnIhlLT PHtPAkXz72H8wiPT+vP0Z+W4mOZaH/zxZgb2Jv1R0vjSTUKhzx6jUZxUo6tA6a2lTKh/GFqvQLS2U vTDoILvcjVBKxGhqWkfNEmZ/cYHux4fxTdlZosWmtkiE/GPDvxEh8AI+DoF5O6DFjfqdUJL6UO5PT z7EJGwFQ==; Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by desiato.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSZ-00000000XR8-46co for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:06:53 +0000 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-5e4ad1d67bdso10763071a12.2 for ; Wed, 05 Mar 2025 05:06:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180009; x=1741784809; darn=lists.infradead.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=tnKwjJ1FVLv4umx37hI66Bb7z/WCUlz7TSg/JWGf0qo=; b=kK/XHZs4iIOaXPQxjwP+Uyt8LF+JYCMdfshnrG3+xI0HX722Sl/7kS9cwfOMaiJyW1 WWrwmCWPw0XAK2keghx+j1n85t8RVBy0J7bYxaDiijhzQ3Xh7iohGumKcwgQUu12PX2R Xe1KDezN5tlZs4mMOpedrU/VhbTF8iq/TYG/k+rnXnK0gkDK/N/rxZxUPCesS6GWHgnQ F7lBhrUAT6YmGXbn3aUU6eqRq5kY9VlkRVg85T90DlwsYuBec+iFTy7+9O60SgNOZoAb FU/N14gJLHtHIvTYZAYCImkCwJJTWJmWexwS7V2bI7Gaxi6oUMTo+Xt8aCBK8P7jUjqv 5j6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180009; x=1741784809; 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=tnKwjJ1FVLv4umx37hI66Bb7z/WCUlz7TSg/JWGf0qo=; b=VWvwUgmBL0mXHZ6J3wFM9FH46JdKhJXi0ANM7TMiC0oJ5wiTC5pbMZ55cByFenoxG6 YQMhdNbqHprJ2ofWlsLWygqtal29q9j0B7JXwlsEhLehY5B1LbstEoBo5NHXI/08JSdx Z8KCidy4igoLHIac04F/jj+vTBD3HMC9hnkS5roQLjQ582YhGv8PCYdMiQAM2TOm9cAZ YxN4rAqppaE8GYdnZNNOAGSSpbckHdhzK8DT7eAZIoHAtH4rYbq76ji4+oakc6wjq2+n tfSJ+NFiumyJ4kxn63mW3R/xZd6zESuVJGleVoEEC+lsDVc6QND9+oU1Fhsh8ib3RfwW Sbwg== X-Forwarded-Encrypted: i=1; AJvYcCWbg172vIGhCBJsK53qDzwb3F3C/HiLPyVKG58WtDBJ0iD0DF7gyU8sqVVi5e0U/eKklR70IRprD2Syv4vOwuH8@lists.infradead.org X-Gm-Message-State: AOJu0YzQ46/EJ/iV93fuUQzIxcwcFxanOoywlA1Nh30KyeGKFS7Smhp7 v3DnC1dW4+AaiSGF/beFPc2qyMsYmfCU3TD1R8VcnPbUuNV/osBt4ukaqoMKlSM= X-Gm-Gg: ASbGncuxnKo0kN/XsmsGaNg2A74FHMajKkSu7AN3YhQ4yF5U9GXBqZxECXMk2JNebsa TFqI56Ojtbnapz0HqzRaI0ZScay1/KqCL1NZeXxxV5k7ibC7FdQx6FYT7BetfPlC9k9mh/zKCXN XKlsJqgwy830KkwUmXHcHy5OiM6Q4CW6SsLPtsc8CRJzyE0ufV4yBAblkwxYRCtNq66kuM+b3qd 8hR0u09D/HyRDLbf92e2j+XR7CjaJhqxzms95nBKMQlRmC1vi1t7Fk4dfDItkIDgCHIxnNUcPJK EY7lDI/A7IQVe0SaqtZhIA95dJaqztjjKGJobNmz106xCRJzO7yNmCEoqR3vPlt42kuwFSK/9v6 ggempDUeWOodQ0YJFljZsxA== X-Google-Smtp-Source: AGHT+IFkv93UBCNyDTbp+dhfIHJd1mUccVi9lWn9kUXL6jjZpjjTaG6v7cqJg4o/sMmedLPajLbIUA== X-Received: by 2002:a05:6402:2714:b0:5e5:437b:74a7 with SMTP id 4fb4d7f45d1cf-5e59f37c457mr2370034a12.8.1741180008509; Wed, 05 Mar 2025 05:06:48 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:46 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 03/10] optee: account for direction while converting parameters Date: Wed, 5 Mar 2025 14:04:09 +0100 Message-ID: <20250305130634.1850178-4-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_130652_262574_D9A5A964 X-CRM114-Status: GOOD ( 24.22 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The OP-TEE backend driver has two internal function pointers to convert between the subsystem type struct tee_param and the OP-TEE type struct optee_msg_param. The conversion is done from one of the types to the other, which is then involved in some operation and finally converted back to the original type. When converting to prepare the parameters for the operation, all fields must be taken into account, but then converting back, it's enough to update only out-values and out-sizes. So, an update_out parameter is added to the conversion functions to tell if all or only some fields must be copied. This is needed in a later patch where it might get confusing when converting back in from_msg_param() callback since an allocated restricted SHM can be using the sec_world_id of the used restricted memory pool and that doesn't translate back well. Signed-off-by: Jens Wiklander --- drivers/tee/optee/call.c | 10 ++-- drivers/tee/optee/ffa_abi.c | 43 +++++++++++++---- drivers/tee/optee/optee_private.h | 42 +++++++++++------ drivers/tee/optee/rpc.c | 31 +++++++++---- drivers/tee/optee/smc_abi.c | 76 +++++++++++++++++++++++-------- 5 files changed, 144 insertions(+), 58 deletions(-) diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index 16eb953e14bb..f1533b894726 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx, export_uuid(msg_arg->params[1].u.octets, &client_uuid); rc = optee->ops->to_msg_param(optee, msg_arg->params + 2, - arg->num_params, param); + arg->num_params, param, + false /*!update_out*/); if (rc) goto out; @@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx, } if (optee->ops->from_msg_param(optee, param, arg->num_params, - msg_arg->params + 2)) { + msg_arg->params + 2, + true /*update_out*/)) { arg->ret = TEEC_ERROR_COMMUNICATION; arg->ret_origin = TEEC_ORIGIN_COMMS; /* Close session again to avoid leakage */ @@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg, msg_arg->cancel_id = arg->cancel_id; rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params, - param); + param, false /*!update_out*/); if (rc) goto out; @@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg, } if (optee->ops->from_msg_param(optee, param, arg->num_params, - msg_arg->params)) { + msg_arg->params, true /*update_out*/)) { msg_arg->ret = TEEC_ERROR_COMMUNICATION; msg_arg->ret_origin = TEEC_ORIGIN_COMMS; } diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index 4ca1d5161b82..e4b08cd195f3 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id) */ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p, - u32 attr, const struct optee_msg_param *mp) + u32 attr, const struct optee_msg_param *mp, + bool update_out) { struct tee_shm *shm = NULL; u64 offs_high = 0; u64 offs_low = 0; + if (update_out) { + if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT) + return; + goto out; + } + p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT; - p->u.memref.size = mp->u.fmem.size; if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID) shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id); @@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p, offs_high = mp->u.fmem.offs_high; } p->u.memref.shm_offs = offs_low | offs_high << 32; +out: + p->u.memref.size = mp->u.fmem.size; } /** @@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p, * @params: subsystem internal parameter representation * @num_params: number of elements in the parameter arrays * @msg_params: OPTEE_MSG parameters + * @update_out: update parameter for output only * * Returns 0 on success or <0 on failure */ static int optee_ffa_from_msg_param(struct optee *optee, struct tee_param *params, size_t num_params, - const struct optee_msg_param *msg_params) + const struct optee_msg_param *msg_params, + bool update_out) { size_t n; @@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee, switch (attr) { case OPTEE_MSG_ATTR_TYPE_NONE: + if (update_out) + break; p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; memset(&p->u, 0, sizeof(p->u)); break; case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT: case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT: case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT: - optee_from_msg_param_value(p, attr, mp); + optee_from_msg_param_value(p, attr, mp, update_out); break; case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT: case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT: case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT: - from_msg_param_ffa_mem(optee, p, attr, mp); + from_msg_param_ffa_mem(optee, p, attr, mp, update_out); break; default: return -EINVAL; @@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee, } static int to_msg_param_ffa_mem(struct optee_msg_param *mp, - const struct tee_param *p) + const struct tee_param *p, bool update_out) { struct tee_shm *shm = p->u.memref.shm; + if (update_out) { + if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT) + return 0; + goto out; + } + mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr - TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; @@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp, memset(&mp->u, 0, sizeof(mp->u)); mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID; } +out: mp->u.fmem.size = p->u.memref.size; return 0; @@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp, * @optee: main service struct * @msg_params: OPTEE_MSG parameters * @num_params: number of elements in the parameter arrays - * @params: subsystem itnernal parameter representation + * @params: subsystem internal parameter representation + * @update_out: update parameter for output only * Returns 0 on success or <0 on failure */ static int optee_ffa_to_msg_param(struct optee *optee, struct optee_msg_param *msg_params, size_t num_params, - const struct tee_param *params) + const struct tee_param *params, + bool update_out) { size_t n; @@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee, switch (p->attr) { case TEE_IOCTL_PARAM_ATTR_TYPE_NONE: + if (update_out) + break; mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; memset(&mp->u, 0, sizeof(mp->u)); break; case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: - optee_to_msg_param_value(mp, p); + optee_to_msg_param_value(mp, p, update_out); break; case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: - if (to_msg_param_ffa_mem(mp, p)) + if (to_msg_param_ffa_mem(mp, p, update_out)) return -EINVAL; break; default: diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index dc0f355ef72a..20eda508dbac 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -185,10 +185,12 @@ struct optee_ops { bool system_thread); int (*to_msg_param)(struct optee *optee, struct optee_msg_param *msg_params, - size_t num_params, const struct tee_param *params); + size_t num_params, const struct tee_param *params, + bool update_out); int (*from_msg_param)(struct optee *optee, struct tee_param *params, size_t num_params, - const struct optee_msg_param *msg_params); + const struct optee_msg_param *msg_params, + bool update_out); }; /** @@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx); void optee_release_supp(struct tee_context *ctx); static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr, - const struct optee_msg_param *mp) + const struct optee_msg_param *mp, + bool update_out) { - p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT + - attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; - p->u.value.a = mp->u.value.a; - p->u.value.b = mp->u.value.b; - p->u.value.c = mp->u.value.c; + if (!update_out) + p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT + + attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; + + if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT || + attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) { + p->u.value.a = mp->u.value.a; + p->u.value.b = mp->u.value.b; + p->u.value.c = mp->u.value.c; + } } static inline void optee_to_msg_param_value(struct optee_msg_param *mp, - const struct tee_param *p) + const struct tee_param *p, + bool update_out) { - mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr - - TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; - mp->u.value.a = p->u.value.a; - mp->u.value.b = p->u.value.b; - mp->u.value.c = p->u.value.c; + if (!update_out) + mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr - + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + + if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || + p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) { + mp->u.value.a = p->u.value.a; + mp->u.value.b = p->u.value.b; + mp->u.value.c = p->u.value.c; + } } void optee_cq_init(struct optee_call_queue *cq, int thread_count); diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index ebbbd42b0e3e..580e6b9b0606 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, } if (optee->ops->from_msg_param(optee, params, arg->num_params, - arg->params)) + arg->params, false /*!update_out*/)) goto bad; for (i = 0; i < arg->num_params; i++) { @@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, } else { params[3].u.value.a = msg.len; if (optee->ops->to_msg_param(optee, arg->params, - arg->num_params, params)) + arg->num_params, params, + true /*update_out*/)) arg->ret = TEEC_ERROR_BAD_PARAMETERS; else arg->ret = TEEC_SUCCESS; @@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg) static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee, struct optee_msg_arg *arg) { + bool update_out = false; struct tee_param *params; arg->ret_origin = TEEC_ORIGIN_COMMS; @@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee, } if (optee->ops->from_msg_param(optee, params, arg->num_params, - arg->params)) { + arg->params, update_out)) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; goto out; } arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params); + /* + * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a + * value type, but the output is a memref type. + */ + if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC) + update_out = true; if (optee->ops->to_msg_param(optee, arg->params, arg->num_params, - params)) + params, update_out)) arg->ret = TEEC_ERROR_BAD_PARAMETERS; out: kfree(params); @@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx, if (arg->num_params != ARRAY_SIZE(params) || optee->ops->from_msg_param(optee, params, arg->num_params, - arg->params) || + arg->params, false /*!update_out*/) || params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; return; @@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx, params[0].u.value.b = 0; params[0].u.value.c = 0; if (optee->ops->to_msg_param(optee, arg->params, - arg->num_params, params)) { + arg->num_params, params, + true /*update_out*/)) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; return; } @@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx, if (arg->num_params != ARRAY_SIZE(params) || optee->ops->from_msg_param(optee, params, arg->num_params, - arg->params) || + arg->params, false /*!update_out*/) || params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; @@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx, params[0].u.value.b = rdev->descr.capacity; params[0].u.value.c = rdev->descr.reliable_wr_count; if (optee->ops->to_msg_param(optee, arg->params, - arg->num_params, params)) { + arg->num_params, params, + true /*update_out*/)) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; return; } @@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx, if (arg->num_params != ARRAY_SIZE(params) || optee->ops->from_msg_param(optee, params, arg->num_params, - arg->params) || + arg->params, false /*!update_out*/) || params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; @@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx, goto out; } if (optee->ops->to_msg_param(optee, arg->params, - arg->num_params, params)) { + arg->num_params, params, + true /*update_out*/)) { arg->ret = TEEC_ERROR_BAD_PARAMETERS; goto out; } diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index 165fadd9abc9..cfdae266548b 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu) */ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr, - const struct optee_msg_param *mp) + const struct optee_msg_param *mp, + bool update_out) { struct tee_shm *shm; phys_addr_t pa; int rc; + if (update_out) { + if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT) + return 0; + goto out; + } + p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; - p->u.memref.size = mp->u.tmem.size; shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref; if (!shm) { p->u.memref.shm_offs = 0; p->u.memref.shm = NULL; - return 0; + goto out; } rc = tee_shm_get_pa(shm, 0, &pa); @@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr, p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa; p->u.memref.shm = shm; - +out: + p->u.memref.size = mp->u.tmem.size; return 0; } static void from_msg_param_reg_mem(struct tee_param *p, u32 attr, - const struct optee_msg_param *mp) + const struct optee_msg_param *mp, + bool update_out) { struct tee_shm *shm; + if (update_out) { + if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT) + return; + goto out; + } + p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; - p->u.memref.size = mp->u.rmem.size; shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref; if (shm) { @@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr, p->u.memref.shm_offs = 0; p->u.memref.shm = NULL; } +out: + p->u.memref.size = mp->u.rmem.size; } /** @@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr, * @params: subsystem internal parameter representation * @num_params: number of elements in the parameter arrays * @msg_params: OPTEE_MSG parameters + * @update_out: update parameter for output only * Returns 0 on success or <0 on failure */ static int optee_from_msg_param(struct optee *optee, struct tee_param *params, size_t num_params, - const struct optee_msg_param *msg_params) + const struct optee_msg_param *msg_params, + bool update_out) { int rc; size_t n; @@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params, switch (attr) { case OPTEE_MSG_ATTR_TYPE_NONE: + if (update_out) + break; p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; memset(&p->u, 0, sizeof(p->u)); break; case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT: case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT: case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT: - optee_from_msg_param_value(p, attr, mp); + optee_from_msg_param_value(p, attr, mp, update_out); break; case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: - rc = from_msg_param_tmp_mem(p, attr, mp); + rc = from_msg_param_tmp_mem(p, attr, mp, update_out); if (rc) return rc; break; case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: - from_msg_param_reg_mem(p, attr, mp); + from_msg_param_reg_mem(p, attr, mp, update_out); break; default: @@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params, } static int to_msg_param_tmp_mem(struct optee_msg_param *mp, - const struct tee_param *p) + const struct tee_param *p, bool update_out) { int rc; phys_addr_t pa; + if (update_out) { + if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT) + return 0; + goto out; + } + mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr - TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm; - mp->u.tmem.size = p->u.memref.size; if (!p->u.memref.shm) { mp->u.tmem.buf_ptr = 0; - return 0; + goto out; } rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa); @@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp, mp->u.tmem.buf_ptr = pa; mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED << OPTEE_MSG_ATTR_CACHE_SHIFT; - +out: + mp->u.tmem.size = p->u.memref.size; return 0; } static int to_msg_param_reg_mem(struct optee_msg_param *mp, - const struct tee_param *p) + const struct tee_param *p, bool update_out) { + if (update_out) { + if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT) + return 0; + goto out; + } + mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr - TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm; - mp->u.rmem.size = p->u.memref.size; mp->u.rmem.offs = p->u.memref.shm_offs; +out: + mp->u.rmem.size = p->u.memref.size; return 0; } @@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp, * @msg_params: OPTEE_MSG parameters * @num_params: number of elements in the parameter arrays * @params: subsystem itnernal parameter representation + * @update_out: update parameter for output only * Returns 0 on success or <0 on failure */ static int optee_to_msg_param(struct optee *optee, struct optee_msg_param *msg_params, - size_t num_params, const struct tee_param *params) + size_t num_params, const struct tee_param *params, + bool update_out) { int rc; size_t n; @@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee, switch (p->attr) { case TEE_IOCTL_PARAM_ATTR_TYPE_NONE: + if (update_out) + break; mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; memset(&mp->u, 0, sizeof(mp->u)); break; case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: - optee_to_msg_param_value(mp, p); + optee_to_msg_param_value(mp, p, update_out); break; case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: if (tee_shm_is_dynamic(p->u.memref.shm)) - rc = to_msg_param_reg_mem(mp, p); + rc = to_msg_param_reg_mem(mp, p, update_out); else - rc = to_msg_param_tmp_mem(mp, p); + rc = to_msg_param_tmp_mem(mp, p, update_out); if (rc) return rc; break; From patchwork Wed Mar 5 13:04:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002712 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DC0A4C19F32 for ; Wed, 5 Mar 2025 13:31:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=nSDQWd9UZqV/STl4BJjbppPEGE1hH0ufO/G2aXdmVa4=; b=PA2ZHR6JAQIs34bZGdi2j3tZSV 0xSJKuwXq3UiZvwewHijObHY5zf1ey+VzAVatzvG4iRpsitP+6Qf7OZhU3F+CJyWsXDxASEsIvqBZ J3Ze+h/DxQIHNcCu5ofKdgzcojr5yOQbOXis1cl0RhyNzDCVLoXlm9KcyRfA4eIHrOHYvjS9FkKC8 nulsoTg+It/giuMWTcmovl+sdOZE5u9ZP800Yos4O7ErAJzV03wuz4kJrjgeHFQJdwqDoO4n+9AbU nwEXtKXz726TEWnzKOUX1i8kcD0AroRczXnt4MlgQyZiqamnesB478DDXYz1BDIzCIQGPUZnYtjZ0 hm2xHxXA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpoq6-00000008CDU-2HEK; Wed, 05 Mar 2025 13:31:10 +0000 Received: from mail-ed1-x52a.google.com ([2a00:1450:4864:20::52a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSb-000000087rX-0wgV for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:06:54 +0000 Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-5e4f5cc3172so8501218a12.0 for ; Wed, 05 Mar 2025 05:06:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180012; x=1741784812; darn=lists.infradead.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=nSDQWd9UZqV/STl4BJjbppPEGE1hH0ufO/G2aXdmVa4=; b=M9u5rJZYbnT6lx7KU0nVGt20rlxfzZa6JTUJayEqF5lBHJ+eDE61Uhtav06BsriAAB QpJIHD+SCV+2yaAT9LAXwGsaexK2lBSAN7LMmSFBRYkoCLXY7pNE5DwzZGdp8OKyVn6n XthcBH7qkI1/wycga885xgX6h0MfWblnjtw+WiWMYPxYSX6BKP9gywsFLs67qW978VNC WGtiIEBYTM6Uul4C9KCn8yajwVRLDzz6AbyMPszg+9nd/C5qf18yF4JMopnq7EQGx7XM n380/vDkm9fTjjCINJeP37LFg34luW619nBaCeEmmEU7tI2HdGLBGAtRWHhRgI73KVrV D4hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180012; x=1741784812; 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=nSDQWd9UZqV/STl4BJjbppPEGE1hH0ufO/G2aXdmVa4=; b=rBgkUFgOmyEeac1Klz2eqpWiA/AunzQ7Im/eZOaY/svXGnLAFu5c78DHL5jK6S+dsY ib3ghShF93RgkkeXh1w9fcd/WxpfzAMeR5Bli8VPjh9Lp+4g1Sr/ENQnla2vfpyfb+cK /535U73OGWlFrvtWxkgQ2T+MqG21lWukqNFn+rXKaIAyex2KtKg3fww9Ekr0zBUDiM1A kuUjQXHExkO/TBdAD+6HiMEEPAShl23XsSMQZH7ogWTchwfOrgpo4x71ijBRPkx6rHPs HKAGx3TBN56jEOO1NHPrROPBlkH+HV5eG4pBIM54naAwtCJjLHxMDfOdFRal52r67rKT KWYg== X-Forwarded-Encrypted: i=1; AJvYcCV9vUg4Fx1yZbBHovRn5NJZHHg25AyewvwP8m3dG4ddwcauLOgas/X4adgXA0YNfcC2FSE/6af9jdzdnM1ZPLCX@lists.infradead.org X-Gm-Message-State: AOJu0Yz3w3dAjT1z5R738VbprfFcxcjpvSbKaMgUm4903PL9TkjgL4f0 tqtRPlNTTFB8+9sQJABU/dW9tx3kwsRWPZ311yd4liX5gfGzGCEh6IrtQLgGjaQ= X-Gm-Gg: ASbGnctnncyAT/t3D6PHeCdgnj6f+LugFBunQvh8ZZpKBLjTmMKyXq5DLeebiNTTKn3 P6fGiDkgIWfXqURQq8DY+nIwODdg0kCXQXCpIhVNO5a5nVTTzDKZ4VrKz3Tuuzs2ZrNTY9avLid eOeVfSAZqzNe92N7hktGTSMc4OdbPrP8Hzo+9FemnKkYxvorwq9XLFl4MY1FKw9isQhvozcdasa pmgH2xPBNgckSHPZjb4C9rf36ToXAaWRLx9dz2h8l9F02ihkYsQAS6vjv7llzuhrIYvKT4EacfL kqDGWKPo7qhJLS5wIR2U85fhjZ2TOE8jFuc32JcEuzI4Cd9A275E4oAHOfABVmmr8b0eBGHAG4Q gnEAf/71LxnttsO86d2i7MA== X-Google-Smtp-Source: AGHT+IGkGSDzVVBlXNvlMiIDvRWPvOOiytk/N/ekI3zhjISEo1QkiAr9cRPlUfo3MPWV5GHTdd4Z6g== X-Received: by 2002:a05:6402:13d3:b0:5dc:81b3:5e1a with SMTP id 4fb4d7f45d1cf-5e59f3864ebmr2662502a12.7.1741180011312; Wed, 05 Mar 2025 05:06:51 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:50 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 04/10] optee: sync secure world ABI headers Date: Wed, 5 Mar 2025 14:04:10 +0100 Message-ID: <20250305130634.1850178-5-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_050653_280380_39BB3B88 X-CRM114-Status: GOOD ( 19.64 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update the header files describing the secure world ABI, both with and without FF-A. The ABI is extended to deal with restricted memory, but as usual backward compatible. Signed-off-by: Jens Wiklander --- drivers/tee/optee/optee_ffa.h | 27 ++++++++++--- drivers/tee/optee/optee_msg.h | 65 ++++++++++++++++++++++++++++++-- drivers/tee/optee/optee_smc.h | 71 ++++++++++++++++++++++++++++++++++- 3 files changed, 154 insertions(+), 9 deletions(-) diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h index 257735ae5b56..7bd037200343 100644 --- a/drivers/tee/optee/optee_ffa.h +++ b/drivers/tee/optee/optee_ffa.h @@ -81,7 +81,7 @@ * as the second MSG arg struct for * OPTEE_FFA_YIELDING_CALL_WITH_ARG. * Bit[31:8]: Reserved (MBZ) - * w5: Bitfield of secure world capabilities OPTEE_FFA_SEC_CAP_* below, + * w5: Bitfield of OP-TEE capabilities OPTEE_FFA_SEC_CAP_* * w6: The maximum secure world notification number * w7: Not used (MBZ) */ @@ -94,6 +94,8 @@ #define OPTEE_FFA_SEC_CAP_ASYNC_NOTIF BIT(1) /* OP-TEE supports probing for RPMB device if needed */ #define OPTEE_FFA_SEC_CAP_RPMB_PROBE BIT(2) +/* OP-TEE supports Restricted Memory for secure data path */ +#define OPTEE_FFA_SEC_CAP_RSTMEM BIT(3) #define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2) @@ -108,7 +110,7 @@ * * Return register usage: * w3: Error code, 0 on success - * w4-w7: Note used (MBZ) + * w4-w7: Not used (MBZ) */ #define OPTEE_FFA_UNREGISTER_SHM OPTEE_FFA_BLOCKING_CALL(3) @@ -119,16 +121,31 @@ * Call register usage: * w3: Service ID, OPTEE_FFA_ENABLE_ASYNC_NOTIF * w4: Notification value to request bottom half processing, should be - * less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE. + * less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE * w5-w7: Not used (MBZ) * * Return register usage: * w3: Error code, 0 on success - * w4-w7: Note used (MBZ) + * w4-w7: Not used (MBZ) */ #define OPTEE_FFA_ENABLE_ASYNC_NOTIF OPTEE_FFA_BLOCKING_CALL(5) -#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE 64 +#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE 64 + +/* + * Release Restricted memory + * + * Call register usage: + * w3: Service ID, OPTEE_FFA_RECLAIM_RSTMEM + * w4: Shared memory handle, lower bits + * w5: Shared memory handle, higher bits + * w6-w7: Not used (MBZ) + * + * Return register usage: + * w3: Error code, 0 on success + * w4-w7: Note used (MBZ) + */ +#define OPTEE_FFA_RELEASE_RSTMEM OPTEE_FFA_BLOCKING_CALL(8) /* * Call with struct optee_msg_arg as argument in the supplied shared memory diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h index e8840a82b983..1b558526e7d9 100644 --- a/drivers/tee/optee/optee_msg.h +++ b/drivers/tee/optee/optee_msg.h @@ -133,13 +133,13 @@ struct optee_msg_param_rmem { }; /** - * struct optee_msg_param_fmem - ffa memory reference parameter + * struct optee_msg_param_fmem - FF-A memory reference parameter * @offs_lower: Lower bits of offset into shared memory reference * @offs_upper: Upper bits of offset into shared memory reference * @internal_offs: Internal offset into the first page of shared memory * reference * @size: Size of the buffer - * @global_id: Global identifier of Shared memory + * @global_id: Global identifier of the shared memory */ struct optee_msg_param_fmem { u32 offs_low; @@ -165,7 +165,7 @@ struct optee_msg_param_value { * @attr: attributes * @tmem: parameter by temporary memory reference * @rmem: parameter by registered memory reference - * @fmem: parameter by ffa registered memory reference + * @fmem: parameter by FF-A registered memory reference * @value: parameter by opaque value * @octets: parameter by octet string * @@ -296,6 +296,18 @@ struct optee_msg_arg { */ #define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001 +/* + * Values used in OPTEE_MSG_CMD_LEND_RSTMEM below + * OPTEE_MSG_RSTMEM_RESERVED Reserved + * OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY Secure Video Playback + * OPTEE_MSG_RSTMEM_TRUSTED_UI Trused UI + * OPTEE_MSG_RSTMEM_SECURE_VIDEO_RECORD Secure Video Recording + */ +#define OPTEE_MSG_RSTMEM_RESERVED 0 +#define OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY 1 +#define OPTEE_MSG_RSTMEM_TRUSTED_UI 2 +#define OPTEE_MSG_RSTMEM_SECURE_VIDEO_RECORD 3 + /* * Do a secure call with struct optee_msg_arg as argument * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd @@ -337,6 +349,49 @@ struct optee_msg_arg { * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is * normal world unable to process asynchronous notifications. Typically * used when the driver is shut down. + * + * OPTEE_MSG_CMD_LEND_RSTMEM lends restricted memory. The passed normal + * physical memory is restricted from normal world access. The memory + * should be unmapped prior to this call since it becomes inaccessible + * during the request. + * Parameters are passed as: + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + * [in] param[0].u.value.a OPTEE_MSG_RSTMEM_* defined above + * [in] param[1].attr OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + * [in] param[1].u.tmem.buf_ptr physical address + * [in] param[1].u.tmem.size size + * [in] param[1].u.tmem.shm_ref holds restricted memory reference + * + * OPTEE_MSG_CMD_RECLAIM_RSTMEM reclaims a previously lent restricted + * memory reference. The physical memory is accessible by the normal world + * after this function has return and can be mapped again. The information + * is passed as: + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + * [in] param[0].u.value.a holds restricted memory cookie + * + * OPTEE_MSG_CMD_GET_RSTMEM_CONFIG get configuration for a specific + * restricted memory use case. Parameters are passed as: + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_VALUE_INOUT + * [in] param[0].value.a OPTEE_MSG_RSTMEM_* + * [in] param[1].attr OPTEE_MSG_ATTR_TYPE_{R,F}MEM_OUTPUT + * [in] param[1].u.{r,f}mem Buffer or NULL + * [in] param[1].u.{r,f}mem.size Provided size of buffer or 0 for query + * output for the restricted use case: + * [out] param[0].value.a Minimal size of SDP memory + * [out] param[0].value.b Required alignment of size and start of + * restricted memory + * [out] param[1].{r,f}mem.size Size of output data + * [out] param[1].{r,f}mem If non-NULL, contains an array of + * uint16_t holding endpoints that + * must be included when lending + * memory for this use case + * + * OPTEE_MSG_CMD_ASSIGN_RSTMEM assigns use-case to restricted memory + * previously lent using the FFA_LEND framework ABI. Parameters are passed + * as: + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + * [in] param[0].u.value.a holds restricted memory cookie + * [in] param[0].u.value.b OPTEE_MSG_RSTMEM_* defined above */ #define OPTEE_MSG_CMD_OPEN_SESSION 0 #define OPTEE_MSG_CMD_INVOKE_COMMAND 1 @@ -346,6 +401,10 @@ struct optee_msg_arg { #define OPTEE_MSG_CMD_UNREGISTER_SHM 5 #define OPTEE_MSG_CMD_DO_BOTTOM_HALF 6 #define OPTEE_MSG_CMD_STOP_ASYNC_NOTIF 7 +#define OPTEE_MSG_CMD_LEND_RSTMEM 8 +#define OPTEE_MSG_CMD_RECLAIM_RSTMEM 9 +#define OPTEE_MSG_CMD_GET_RSTMEM_CONFIG 10 +#define OPTEE_MSG_CMD_ASSIGN_RSTMEM 11 #define OPTEE_MSG_FUNCID_CALL_WITH_ARG 0x0004 #endif /* _OPTEE_MSG_H */ diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 879426300821..abc379ce190c 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -264,7 +264,6 @@ struct optee_smc_get_shm_config_result { #define OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM BIT(0) /* Secure world can communicate via previously unregistered shared memory */ #define OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM BIT(1) - /* * Secure world supports commands "register/unregister shared memory", * secure world accepts command buffers located in any parts of non-secure RAM @@ -280,6 +279,10 @@ struct optee_smc_get_shm_config_result { #define OPTEE_SMC_SEC_CAP_RPC_ARG BIT(6) /* Secure world supports probing for RPMB device if needed */ #define OPTEE_SMC_SEC_CAP_RPMB_PROBE BIT(7) +/* Secure world supports Secure Data Path */ +#define OPTEE_SMC_SEC_CAP_SDP BIT(8) +/* Secure world supports dynamic restricted memory */ +#define OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM BIT(9) #define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9 #define OPTEE_SMC_EXCHANGE_CAPABILITIES \ @@ -451,6 +454,72 @@ struct optee_smc_disable_shm_cache_result { /* See OPTEE_SMC_CALL_WITH_REGD_ARG above */ #define OPTEE_SMC_FUNCID_CALL_WITH_REGD_ARG 19 +/* + * Get Secure Data Path memory config + * + * Returns the Secure Data Path memory config. + * + * Call register usage: + * a0 SMC Function ID, OPTEE_SMC_GET_SDP_CONFIG + * a2-6 Not used, must be zero + * a7 Hypervisor Client ID register + * + * Have config return register usage: + * a0 OPTEE_SMC_RETURN_OK + * a1 Physical address of start of SDP memory + * a2 Size of SDP memory + * a3 Not used + * a4-7 Preserved + * + * Not available register usage: + * a0 OPTEE_SMC_RETURN_ENOTAVAIL + * a1-3 Not used + * a4-7 Preserved + */ +#define OPTEE_SMC_FUNCID_GET_SDP_CONFIG 20 +#define OPTEE_SMC_GET_SDP_CONFIG \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SDP_CONFIG) + +struct optee_smc_get_sdp_config_result { + unsigned long status; + unsigned long start; + unsigned long size; + unsigned long flags; +}; + +/* + * Get Secure Data Path dynamic memory config + * + * Returns the Secure Data Path dynamic memory config. + * + * Call register usage: + * a0 SMC Function ID, OPTEE_SMC_GET_DYN_SHM_CONFIG + * a2-6 Not used, must be zero + * a7 Hypervisor Client ID register + * + * Have config return register usage: + * a0 OPTEE_SMC_RETURN_OK + * a1 Minamal size of SDP memory + * a2 Required alignment of size and start of registered SDP memory + * a3 Not used + * a4-7 Preserved + * + * Not available register usage: + * a0 OPTEE_SMC_RETURN_ENOTAVAIL + * a1-3 Not used + * a4-7 Preserved + */ + +#define OPTEE_SMC_FUNCID_GET_DYN_SDP_CONFIG 21 +#define OPTEE_SMC_GET_DYN_SDP_CONFIG \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_DYN_SDP_CONFIG) + +struct optee_smc_get_dyn_sdp_config_result { + unsigned long status; + unsigned long size; + unsigned long align; + unsigned long flags; +}; /* * Resume from RPC (for example after processing a foreign interrupt) From patchwork Wed Mar 5 13:04:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002714 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 97AD7C19F32 for ; Wed, 5 Mar 2025 13:34:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4A2RMjc7+ET06/OLz7LUVQUp9/M2mVREMhZjdI+mgFg=; b=WZ1EeXIujMmtC+JOidOmCOxkXi AVGwJzT9GBoaFENp2n3/ZmxykVLsXAL+p+oHox5MAUc1Ebf2s05ovuOfLwOAdEddTAFOGTau2VEh5 VaDSZgY5IJ0VjnHoRLPjyuFT/oXuTEb5P83pAro9al+HNwkNPjL9SrV2XbzCU70kJuDf7lFeh3K8L d2lavlpYMAZIjbBxXMxb9j9i6QJ1LE1a3GlgtfMrMKP0vSqJIlVfP1poZJ7dItA0wZNM3GgZFklbV emNjS3IooyxJMQpUCc3QL8evrquuHJVBFC8scFEZ2I/iNThbWbFO1vCYMgwcQG5gYoNIp+1u9MRG+ 0KAV/9eg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpotF-00000008CoV-0cJO; Wed, 05 Mar 2025 13:34:25 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSg-000000087tA-41n8 for linux-arm-kernel@bombadil.infradead.org; Wed, 05 Mar 2025 13:06:59 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=4A2RMjc7+ET06/OLz7LUVQUp9/M2mVREMhZjdI+mgFg=; b=AmukVbYYbyQaMObQG/CDMgYP9M 20GOgmDCMrNA8iObpmapBZkWIdhb5W26Rn6eWoENjGltWU8iBqP7jrtokmRB3mwEjIUASm4vU+ymJ yFmLA5mtv4xHdzwp+4MgYCnw/pXI3UojKPg9AffVo50CdIMCi+C0cfKa/VD+O04IlnQ1CIt3DYnYA KY4cE+NjI7smD+w+NHBBXqp62QtQSwyt4oqyVrIHBbDCDqXLgsbh84BW39DlrPdHkktF9/wJwNPVZ dSfQOS3FHYk4vmTZUfcKkpa1hyIgsO4ijh+1YXDoOZZu7pOUp91K5CPeg8sgzXMJ/9gCsMvZRAB9x g8Kv9Pyg==; Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by desiato.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSd-00000000XRr-4A5E for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:06:57 +0000 Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-5e4ce6e3b8cso1311526a12.1 for ; Wed, 05 Mar 2025 05:06:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180014; x=1741784814; darn=lists.infradead.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=4A2RMjc7+ET06/OLz7LUVQUp9/M2mVREMhZjdI+mgFg=; b=OKAmQKOpLg2uBoFc8c+qrsVy70Li+VorKumTVEc+5S0Rm8upZZJMKb/PkilqaKKWHe Cp0Y9Y3tbxzpylS9yzPqGWAShJiEdv5kKlHBzd7eYHJ+lYXUoojRhStcqJTBQdoCv1PN wCZ99O6jZnzfiUfFXZjUCvLPc5iav0NPyI8Wr6zPtsLHminWGmNUaQ0Yk7OGFS21K2lS 5IRNbqH4c14eBdYgppI64AShyijhfYIzUwm7I6W0/QaSv3i8huBWvxG7g2k4utNnjO/9 AHE75ksxJwklZN9xiPiAWOucISVqdH/ARvH4PbgmJBeh4HLp7cNdg7uK2fcyFW81Zsm2 SLww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180014; x=1741784814; 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=4A2RMjc7+ET06/OLz7LUVQUp9/M2mVREMhZjdI+mgFg=; b=vXgqutMAAcFR9iykdbxa437SEW/a7eIemz8CXgsBoVTZY2v2kuT3b09alKUDD6XdS4 mFNkGTlUOkwerJoUnPS+QB0w/OSSVo2CD0+Ug1FVZjFCER4AsFMUQ9ZiJ/Wib58u434U v7jqA4AeReszPcTz1+iIueWsjarYizdIK6gCF5oXT11iqB9p8dDsyR5BkoXGFn7biQua HwaK1/3xnN4yHLAo/oWbzS+1K2uQ8ePDq5kNClTFmb+HSsMJTNJLa+RnspNPg7aW343Q 7IgY9kFFbjJuMhXflaZiRYWtEfAn61SmYLz+vWbJyzDJF+quQxutwn4ooAsjoenvR00a vs2w== X-Forwarded-Encrypted: i=1; AJvYcCUWP0/pZuYKdSXs3ERILD743xvNK56AX/h2Wy9FyIDEM4rnmSu3r4Mqn1rAnNucPKaryCXMWpwJqemP9KTEfaX9@lists.infradead.org X-Gm-Message-State: AOJu0Yx7tluGD8HlbDADlPWHS/3wBqrX0eAOrOYS8XhOgef9OsU6UYik +F71s14zEa0f8yNb8XDkILCvA4mT/wMomh9t7thFO/AUT4fuIUwthWB5I2cYCrw= X-Gm-Gg: ASbGnctDysn+Yau1LJ/zpSmfCJNXeJhCcpxYtuhO8FsVapJMJvn/c9+NhsWr6pZ7A/x jBfmLRqiHtIdi1roWo9DF037/jHF/FLbsC+myEgIcRz3nurcvTtGJ+N3L+AQhgu9okHim7IbYyT n4HFFSz1RQYVmo2q/V5QTnPrS1HVFqF+FDnOq5AUZ4YfMzQWlSYWU/3i/u5dsUIYVc+iMl4nEfM sw1ZJ2NaR8N6ecRAp34omu2yw/td0wC4t0ReXT75dR/8L29j2euqTnu7UlREY2nLshoP5j/ts+2 KJ9U+R817b985LCB6RPkRtKa1yANVQV9AoTFYgI1G2j/Ol3OSQ4HFyNQDZKZuXfdSlRhCvFWeWv 8pqa2HOvifxImlr2SBR4p8w== X-Google-Smtp-Source: AGHT+IFwVg2fe30YJ6NhkeUa+m2OUhrYsSvmDZcpiLEWIsMefC5Un9QvScvwsJSP1T5LTCC7FAF7Mw== X-Received: by 2002:a05:6402:2742:b0:5dc:eb2:570d with SMTP id 4fb4d7f45d1cf-5e59f0dc9d3mr3049042a12.2.1741180014215; Wed, 05 Mar 2025 05:06:54 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:53 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 05/10] tee: implement restricted DMA-heap Date: Wed, 5 Mar 2025 14:04:11 +0100 Message-ID: <20250305130634.1850178-6-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_130656_213728_F54E903B X-CRM114-Status: GOOD ( 23.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Implement DMA heap for restricted DMA-buf allocation in the TEE subsystem. Restricted memory refers to memory buffers behind a hardware enforced firewall. It is not accessible to the kernel during normal circumstances but rather only accessible to certain hardware IPs or CPUs executing in higher or differently privileged mode than the kernel itself. This interface allows to allocate and manage such restricted memory buffers via interaction with a TEE implementation. The restricted memory is allocated for a specific use-case, like Secure Video Playback, Trusted UI, or Secure Video Recording where certain hardware devices can access the memory. The DMA-heaps are enabled explicitly by the TEE backend driver. The TEE backend drivers needs to implement restricted memory pool to manage the restricted memory. Signed-off-by: Jens Wiklander --- drivers/tee/Makefile | 1 + drivers/tee/tee_heap.c | 470 ++++++++++++++++++++++++++++++++++++++ drivers/tee/tee_private.h | 6 + include/linux/tee_core.h | 62 +++++ 4 files changed, 539 insertions(+) create mode 100644 drivers/tee/tee_heap.c diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile index 5488cba30bd2..949a6a79fb06 100644 --- a/drivers/tee/Makefile +++ b/drivers/tee/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEE) += tee.o tee-objs += tee_core.o +tee-objs += tee_heap.o tee-objs += tee_shm.o tee-objs += tee_shm_pool.o obj-$(CONFIG_OPTEE) += optee/ diff --git a/drivers/tee/tee_heap.c b/drivers/tee/tee_heap.c new file mode 100644 index 000000000000..476ab2e27260 --- /dev/null +++ b/drivers/tee/tee_heap.c @@ -0,0 +1,470 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tee_private.h" + +struct tee_dma_heap { + struct dma_heap *heap; + enum tee_dma_heap_id id; + struct tee_rstmem_pool *pool; + struct tee_device *teedev; + /* Protects pool and teedev above */ + struct mutex mu; +}; + +struct tee_heap_buffer { + struct tee_rstmem_pool *pool; + struct tee_device *teedev; + size_t size; + size_t offs; + struct sg_table table; +}; + +struct tee_heap_attachment { + struct sg_table table; + struct device *dev; +}; + +struct tee_rstmem_static_pool { + struct tee_rstmem_pool pool; + struct gen_pool *gen_pool; + phys_addr_t pa_base; +}; + +#if !IS_MODULE(CONFIG_TEE) && IS_ENABLED(CONFIG_DMABUF_HEAPS) +static DEFINE_XARRAY_ALLOC(tee_dma_heap); + +static int copy_sg_table(struct sg_table *dst, struct sg_table *src) +{ + struct scatterlist *dst_sg; + struct scatterlist *src_sg; + int ret; + int i; + + ret = sg_alloc_table(dst, src->orig_nents, GFP_KERNEL); + if (ret) + return ret; + + dst_sg = dst->sgl; + for_each_sgtable_sg(src, src_sg, i) { + sg_set_page(dst_sg, sg_page(src_sg), src_sg->length, + src_sg->offset); + dst_sg = sg_next(dst_sg); + } + + return 0; +} + +static int tee_heap_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct tee_heap_buffer *buf = dmabuf->priv; + struct tee_heap_attachment *a; + int ret; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + ret = copy_sg_table(&a->table, &buf->table); + if (ret) { + kfree(a); + return ret; + } + + a->dev = attachment->dev; + attachment->priv = a; + + return 0; +} + +static void tee_heap_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct tee_heap_attachment *a = attachment->priv; + + sg_free_table(&a->table); + kfree(a); +} + +static struct sg_table * +tee_heap_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct tee_heap_attachment *a = attachment->priv; + int ret; + + ret = dma_map_sgtable(attachment->dev, &a->table, direction, + DMA_ATTR_SKIP_CPU_SYNC); + if (ret) + return ERR_PTR(ret); + + return &a->table; +} + +static void tee_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ + struct tee_heap_attachment *a = attachment->priv; + + WARN_ON(&a->table != table); + + dma_unmap_sgtable(attachment->dev, table, direction, + DMA_ATTR_SKIP_CPU_SYNC); +} + +static void tee_heap_buf_free(struct dma_buf *dmabuf) +{ + struct tee_heap_buffer *buf = dmabuf->priv; + struct tee_device *teedev = buf->teedev; + + buf->pool->ops->free(buf->pool, &buf->table); + tee_device_put(teedev); +} + +static const struct dma_buf_ops tee_heap_buf_ops = { + .attach = tee_heap_attach, + .detach = tee_heap_detach, + .map_dma_buf = tee_heap_map_dma_buf, + .unmap_dma_buf = tee_heap_unmap_dma_buf, + .release = tee_heap_buf_free, +}; + +static struct dma_buf *tee_dma_heap_alloc(struct dma_heap *heap, + unsigned long len, u32 fd_flags, + u64 heap_flags) +{ + struct tee_dma_heap *h = dma_heap_get_drvdata(heap); + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct tee_device *teedev = NULL; + struct tee_heap_buffer *buf; + struct tee_rstmem_pool *pool; + struct dma_buf *dmabuf; + int rc; + + mutex_lock(&h->mu); + if (tee_device_get(h->teedev)) { + teedev = h->teedev; + pool = h->pool; + } + mutex_unlock(&h->mu); + + if (!teedev) + return ERR_PTR(-EINVAL); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) { + dmabuf = ERR_PTR(-ENOMEM); + goto err; + } + buf->size = len; + buf->pool = pool; + buf->teedev = teedev; + + rc = pool->ops->alloc(pool, &buf->table, len, &buf->offs); + if (rc) { + dmabuf = ERR_PTR(rc); + goto err_kfree; + } + + exp_info.ops = &tee_heap_buf_ops; + exp_info.size = len; + exp_info.priv = buf; + exp_info.flags = fd_flags; + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) + goto err_rstmem_free; + + return dmabuf; + +err_rstmem_free: + pool->ops->free(pool, &buf->table); +err_kfree: + kfree(buf); +err: + tee_device_put(h->teedev); + return dmabuf; +} + +static const struct dma_heap_ops tee_dma_heap_ops = { + .allocate = tee_dma_heap_alloc, +}; + +static const char *heap_id_2_name(enum tee_dma_heap_id id) +{ + switch (id) { + case TEE_DMA_HEAP_SECURE_VIDEO_PLAY: + return "restricted,secure-video"; + case TEE_DMA_HEAP_TRUSTED_UI: + return "restricted,trusted-ui"; + case TEE_DMA_HEAP_SECURE_VIDEO_RECORD: + return "restricted,secure-video-record"; + default: + return NULL; + } +} + +static int alloc_dma_heap(struct tee_device *teedev, enum tee_dma_heap_id id, + struct tee_rstmem_pool *pool) +{ + struct dma_heap_export_info exp_info = { + .ops = &tee_dma_heap_ops, + .name = heap_id_2_name(id), + }; + struct tee_dma_heap *h; + int rc; + + if (!exp_info.name) + return -EINVAL; + + if (xa_reserve(&tee_dma_heap, id, GFP_KERNEL)) { + if (!xa_load(&tee_dma_heap, id)) + return -EEXIST; + return -ENOMEM; + } + + h = kzalloc(sizeof(*h), GFP_KERNEL); + if (!h) + return -ENOMEM; + h->id = id; + h->teedev = teedev; + h->pool = pool; + mutex_init(&h->mu); + + exp_info.priv = h; + h->heap = dma_heap_add(&exp_info); + if (IS_ERR(h->heap)) { + rc = PTR_ERR(h->heap); + kfree(h); + + return rc; + } + + /* "can't fail" due to the call to xa_reserve() above */ + return WARN(xa_store(&tee_dma_heap, id, h, GFP_KERNEL), + "xa_store() failed"); +} + +int tee_device_register_dma_heap(struct tee_device *teedev, + enum tee_dma_heap_id id, + struct tee_rstmem_pool *pool) +{ + struct tee_dma_heap *h; + int rc; + + h = xa_load(&tee_dma_heap, id); + if (h) { + mutex_lock(&h->mu); + if (h->teedev) { + rc = -EBUSY; + } else { + h->teedev = teedev; + h->pool = pool; + rc = 0; + } + mutex_unlock(&h->mu); + } else { + rc = alloc_dma_heap(teedev, id, pool); + } + + if (rc) + dev_err(&teedev->dev, "can't register DMA heap id %d (%s)\n", + id, heap_id_2_name(id)); + + return rc; +} + +void tee_device_unregister_all_dma_heaps(struct tee_device *teedev) +{ + struct tee_rstmem_pool *pool; + struct tee_dma_heap *h; + u_long i; + + xa_for_each(&tee_dma_heap, i, h) { + if (h) { + pool = NULL; + mutex_lock(&h->mu); + if (h->teedev == teedev) { + pool = h->pool; + h->teedev = NULL; + h->pool = NULL; + } + mutex_unlock(&h->mu); + if (pool) + pool->ops->destroy_pool(pool); + } + } +} +EXPORT_SYMBOL_GPL(tee_device_unregister_all_dma_heaps); + +int tee_heap_update_from_dma_buf(struct tee_device *teedev, + struct dma_buf *dmabuf, size_t *offset, + struct tee_shm *shm, + struct tee_shm **parent_shm) +{ + struct tee_heap_buffer *buf; + int rc; + + /* The DMA-buf must be from our heap */ + if (dmabuf->ops != &tee_heap_buf_ops) + return -EINVAL; + + buf = dmabuf->priv; + /* The buffer must be from the same teedev */ + if (buf->teedev != teedev) + return -EINVAL; + + shm->size = buf->size; + + rc = buf->pool->ops->update_shm(buf->pool, &buf->table, buf->offs, shm, + parent_shm); + if (!rc && *parent_shm) + *offset = buf->offs; + + return rc; +} +#else +int tee_device_register_dma_heap(struct tee_device *teedev __always_unused, + enum tee_dma_heap_id id __always_unused, + struct tee_rstmem_pool *pool __always_unused) +{ + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tee_device_register_dma_heap); + +void +tee_device_unregister_all_dma_heaps(struct tee_device *teedev __always_unused) +{ +} +EXPORT_SYMBOL_GPL(tee_device_unregister_all_dma_heaps); + +int tee_heap_update_from_dma_buf(struct tee_device *teedev __always_unused, + struct dma_buf *dmabuf __always_unused, + size_t *offset __always_unused, + struct tee_shm *shm __always_unused, + struct tee_shm **parent_shm __always_unused) +{ + return -EINVAL; +} +#endif + +static struct tee_rstmem_static_pool * +to_rstmem_static_pool(struct tee_rstmem_pool *pool) +{ + return container_of(pool, struct tee_rstmem_static_pool, pool); +} + +static int rstmem_pool_op_static_alloc(struct tee_rstmem_pool *pool, + struct sg_table *sgt, size_t size, + size_t *offs) +{ + struct tee_rstmem_static_pool *stp = to_rstmem_static_pool(pool); + phys_addr_t pa; + int ret; + + pa = gen_pool_alloc(stp->gen_pool, size); + if (!pa) + return -ENOMEM; + + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (ret) { + gen_pool_free(stp->gen_pool, pa, size); + return ret; + } + + sg_set_page(sgt->sgl, phys_to_page(pa), size, 0); + *offs = pa - stp->pa_base; + + return 0; +} + +static void rstmem_pool_op_static_free(struct tee_rstmem_pool *pool, + struct sg_table *sgt) +{ + struct tee_rstmem_static_pool *stp = to_rstmem_static_pool(pool); + struct scatterlist *sg; + int i; + + for_each_sgtable_sg(sgt, sg, i) + gen_pool_free(stp->gen_pool, sg_phys(sg), sg->length); + sg_free_table(sgt); +} + +static int rstmem_pool_op_static_update_shm(struct tee_rstmem_pool *pool, + struct sg_table *sgt, size_t offs, + struct tee_shm *shm, + struct tee_shm **parent_shm) +{ + struct tee_rstmem_static_pool *stp = to_rstmem_static_pool(pool); + + shm->paddr = stp->pa_base + offs; + *parent_shm = NULL; + + return 0; +} + +static void rstmem_pool_op_static_destroy_pool(struct tee_rstmem_pool *pool) +{ + struct tee_rstmem_static_pool *stp = to_rstmem_static_pool(pool); + + gen_pool_destroy(stp->gen_pool); + kfree(stp); +} + +static struct tee_rstmem_pool_ops rstmem_pool_ops_static = { + .alloc = rstmem_pool_op_static_alloc, + .free = rstmem_pool_op_static_free, + .update_shm = rstmem_pool_op_static_update_shm, + .destroy_pool = rstmem_pool_op_static_destroy_pool, +}; + +struct tee_rstmem_pool *tee_rstmem_static_pool_alloc(phys_addr_t paddr, + size_t size) +{ + const size_t page_mask = PAGE_SIZE - 1; + struct tee_rstmem_static_pool *stp; + int rc; + + /* Check it's page aligned */ + if ((paddr | size) & page_mask) + return ERR_PTR(-EINVAL); + + stp = kzalloc(sizeof(*stp), GFP_KERNEL); + if (!stp) + return ERR_PTR(-ENOMEM); + + stp->gen_pool = gen_pool_create(PAGE_SHIFT, -1); + if (!stp->gen_pool) { + rc = -ENOMEM; + goto err_free; + } + + rc = gen_pool_add(stp->gen_pool, paddr, size, -1); + if (rc) + goto err_free_pool; + + stp->pool.ops = &rstmem_pool_ops_static; + stp->pa_base = paddr; + return &stp->pool; + +err_free_pool: + gen_pool_destroy(stp->gen_pool); +err_free: + kfree(stp); + + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(tee_rstmem_static_pool_alloc); diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h index 9bc50605227c..6c6ff5d5eed2 100644 --- a/drivers/tee/tee_private.h +++ b/drivers/tee/tee_private.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -24,4 +25,9 @@ struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size); struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, unsigned long addr, size_t length); +int tee_heap_update_from_dma_buf(struct tee_device *teedev, + struct dma_buf *dmabuf, size_t *offset, + struct tee_shm *shm, + struct tee_shm **parent_shm); + #endif /*TEE_PRIVATE_H*/ diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h index a38494d6b5f4..16ef078247ae 100644 --- a/include/linux/tee_core.h +++ b/include/linux/tee_core.h @@ -8,9 +8,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -30,6 +32,12 @@ #define TEE_DEVICE_FLAG_REGISTERED 0x1 #define TEE_MAX_DEV_NAME_LEN 32 +enum tee_dma_heap_id { + TEE_DMA_HEAP_SECURE_VIDEO_PLAY = 1, + TEE_DMA_HEAP_TRUSTED_UI, + TEE_DMA_HEAP_SECURE_VIDEO_RECORD, +}; + /** * struct tee_device - TEE Device representation * @name: name of device @@ -116,6 +124,33 @@ struct tee_desc { u32 flags; }; +/** + * struct tee_rstmem_pool - restricted memory pool + * @ops: operations + * + * This is an abstract interface where this struct is expected to be + * embedded in another struct specific to the implementation. + */ +struct tee_rstmem_pool { + const struct tee_rstmem_pool_ops *ops; +}; + +/** + * struct tee_rstmem_pool_ops - restricted memory pool operations + * @alloc: called when allocating restricted memory + * @free: called when freeing restricted memory + * @destroy_pool: called when destroying the pool + */ +struct tee_rstmem_pool_ops { + int (*alloc)(struct tee_rstmem_pool *pool, struct sg_table *sgt, + size_t size, size_t *offs); + void (*free)(struct tee_rstmem_pool *pool, struct sg_table *sgt); + int (*update_shm)(struct tee_rstmem_pool *pool, struct sg_table *sgt, + size_t offs, struct tee_shm *shm, + struct tee_shm **parent_shm); + void (*destroy_pool)(struct tee_rstmem_pool *pool); +}; + /** * tee_device_alloc() - Allocate a new struct tee_device instance * @teedesc: Descriptor for this driver @@ -154,6 +189,11 @@ int tee_device_register(struct tee_device *teedev); */ void tee_device_unregister(struct tee_device *teedev); +int tee_device_register_dma_heap(struct tee_device *teedev, + enum tee_dma_heap_id id, + struct tee_rstmem_pool *pool); +void tee_device_unregister_all_dma_heaps(struct tee_device *teedev); + /** * tee_device_set_dev_groups() - Set device attribute groups * @teedev: Device to register @@ -229,6 +269,28 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool) pool->ops->destroy_pool(pool); } +/** + * tee_rstmem_static_pool_alloc() - Create a restricted memory manager + * @paddr: Physical address of start of pool + * @size: Size in bytes of the pool + * + * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure. + */ +struct tee_rstmem_pool *tee_rstmem_static_pool_alloc(phys_addr_t paddr, + size_t size); + +/** + * tee_rstmem_pool_free() - Free a restricted memory pool + * @pool: The restricted memory pool to free + * + * There must be no remaining restricted memory allocated from this pool + * when this function is called. + */ +static inline void tee_rstmem_pool_free(struct tee_rstmem_pool *pool) +{ + pool->ops->destroy_pool(pool); +} + /** * tee_get_drvdata() - Return driver_data pointer * @returns the driver_data pointer supplied to tee_register(). From patchwork Wed Mar 5 13:04:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002722 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ADF5BC282EC for ; Wed, 5 Mar 2025 13:37:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=5CcAD/p05b1IVvXLEIrs8hiPkLvSkxniC6dMT97HxMQ=; b=Lu9RX+Ju7IyZ+ohmP/wMfb4SLB mW9vXkMYOZyKwwM5oJSzMYBN7vKmL/sMzzgyzvFFslqJJVylYLNblD0UkpGa+ISBsmeRVdzJnRevq 0dddou52hhkMnMoqZ3PbnFcPb/cQmBGFo8VoK2gxC8XxiACYKK9v8QXt5Wa9H4sMuZxRmkZXgyubN DY0Mdn5bgjOFOWc/VtrDYGE3AgOADQRwx+vvBJRd8OWr5fr5MihBzSuBKz4ic9EGXxsMuI6wMX7w1 tyUsR7HH6Uvc3JW/FxWiP6znKRcpoi1wqSpRyIgjF47xom/waEuavJ/UbwNiBrlfcI7AEDqj8VJmw FGVNvcMQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpowN-00000008D8N-49tp; Wed, 05 Mar 2025 13:37:40 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSk-000000087u5-15d9 for linux-arm-kernel@bombadil.infradead.org; Wed, 05 Mar 2025 13:07:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=5CcAD/p05b1IVvXLEIrs8hiPkLvSkxniC6dMT97HxMQ=; b=UqCckbPkp+XDYnNttPyoWLIDTt bdjzM67jUDR2F6NNp6USEIb7OW1EKNLqtDyk0ElWkPCuSXZFaissU0lBrTO5B8rqbEUyBl+L54xe6 B4P+3hMp1Nj2m0QUVxPsDwWLJ4z5OZYqTapIBru3FLqvqioUV7LRNz5Q5Cgbg8DmNPS395iPQEw2X QDQc/J1X2SMvZOjSxzhj3QIpFIM1yvVlW+ArXXmVjyTEWDUXE0fINGN832KDh+dllqp82zacloeh6 2bj3k/g4Ab8cT6DUljIzP2/p9cGU8AgooMuTD7Uy1kZPCysXFfNiNEJ0tGoGSi7BpzW9ACy30G31P Z/gJgDNg==; Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by casper.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSh-00000005XfQ-0Jf4 for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:07:01 +0000 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-5e0b70fb1daso11838248a12.1 for ; Wed, 05 Mar 2025 05:06:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180017; x=1741784817; darn=lists.infradead.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=5CcAD/p05b1IVvXLEIrs8hiPkLvSkxniC6dMT97HxMQ=; b=HMMlWDPsGl6q2AhtET6vvD1RuyZan3udjjHG0kwtKz52h30krgI/7Tng/g4UMKknQD GlZ5AWBBGN0xj2sPC73MnTb6x9sKpGiaE/S+taffz2kyurFB9k1nbBkxx7yLIfL2u3Ue 5Am1e5sN1FT1OBnTmkb/h4grLMel7rO5p/p1jp5LgT5O8Rfsff6TomMoGbzdI8MisgkA Is6JtZ4xOfny9aFEhYgV14mBR4PUdRIpERCRzD4hCPijfLZqJUZFN5UAGgNWbEUzspAS VXiGrh3YYC0Ze/YgaxUAQnYYGzY67plOto+O3AqMT7NzcUJDHGrA4gYchSNh8Q4upyId T3jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180017; x=1741784817; 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=5CcAD/p05b1IVvXLEIrs8hiPkLvSkxniC6dMT97HxMQ=; b=pXA2DLf8g8S83nWHCBxUk7b3kQeuy6k0q8r0YadWRORZxbpU/YSs+bxJrT7YCOSw4O EPwkS6BLUxE1seqjm9BPijh0VPBv5sXMLpuMZAEa7ve09S7iEHSJMH/Aju7eqoZVbYpY xy2fGY3a6nkPbKbLSxXgsI6bhxvB8ZHIhHz3Lneaj/zmOLKQ/wVTqpGxUyGvp4uIm2MS G7CYZ2tt8U/oRrq2o06BPnjB0Kw3sIdi4TgOLV4gX8J7S1rUMLEr6hlUnF/LuLoAfSF0 Co2a5/QHgTIu6HAkgc+VeQALDW3eSu8nt0kaUuhvaBwvxNTZAIlPHkbDpc0vSsii9EaY t2/A== X-Forwarded-Encrypted: i=1; AJvYcCXbBFzC5RqoPMjwCrzgPQc/zwvLrLatRq4WZQ+bhCQhrjsYdciaui3GjJs4op91wlwVN/OBWjcXOentaGk24zAE@lists.infradead.org X-Gm-Message-State: AOJu0YyTfDxsu+rXvx/zYjAawUjUIutkGeegaISf81kn3rimy+1EYg4L E7jKBmaJK+EkQBBR+zq4MAP+GgfTf4AqIDgxrCQjB+oj4QIvdpny1ehav7zBkvU= X-Gm-Gg: ASbGnctaOeLXDelkPZ2FM62pFgJ+A1SOs+eWnvnT4T3tUjLehso57ANtc5ni+9uz3Py pkgWgHeBsIrdnwdCVsnZYafgG+u9aRE2w9npblPoWaS175CTSk6Wa2ws7R5y5ZgLvu4uSz5fafa zy9omuF5beIWB6oinkT5SQSAGTi0FCez8PTZluyAkWoCZomUiLTESlWq+8nTGfxCvowD0OMp/14 /G3PO6YFwTTTOxWlacPyPbmOu8ES1mss3zVRKjTVtWfedC6lcbZHfYFV30JuypFO6sYrHtU3Lxj 76WNzJ7NwWJKOANkb/Pqu29EYrjIwOwzWXKk4MDezO0Mo14xMGmc0VM++Rsi6zykFqvQu1oG8MW Pd0RbwjTGMvyRQ2jLPJVNmQ== X-Google-Smtp-Source: AGHT+IG3cgo4lt4+QBuBPJp4MiDy4EL2BqrtziPjGxQujndCvzWUBDgOAl5gJF76QqdWuudAiJRjUg== X-Received: by 2002:a05:6402:1e92:b0:5d9:82bc:ad06 with SMTP id 4fb4d7f45d1cf-5e59f386d7dmr2815278a12.3.1741180016471; Wed, 05 Mar 2025 05:06:56 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:55 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Etienne Carriere , Jens Wiklander Subject: [PATCH v6 06/10] tee: new ioctl to a register tee_shm from a dmabuf file descriptor Date: Wed, 5 Mar 2025 14:04:12 +0100 Message-ID: <20250305130634.1850178-7-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_130659_134936_D015CD73 X-CRM114-Status: GOOD ( 27.97 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Etienne Carriere Enable userspace to create a tee_shm object that refers to a dmabuf reference. Userspace registers the dmabuf file descriptor as in a tee_shm object. The registration is completed with a tee_shm file descriptor returned to userspace. Userspace is free to close the dmabuf file descriptor now since all the resources are now held via the tee_shm object. Closing the tee_shm file descriptor will release all resources used by the tee_shm object. This change only support dmabuf references that relates to physically contiguous memory buffers. New tee_shm flag to identify tee_shm objects built from a registered dmabuf, TEE_SHM_DMA_BUF. Signed-off-by: Etienne Carriere Signed-off-by: Olivier Masse Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 145 ++++++++++++++++++++++++++----------- drivers/tee/tee_private.h | 1 + drivers/tee/tee_shm.c | 146 ++++++++++++++++++++++++++++++++++++-- include/linux/tee_core.h | 1 + include/linux/tee_drv.h | 10 +++ include/uapi/linux/tee.h | 29 ++++++++ 6 files changed, 288 insertions(+), 44 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 685afcaa3ea1..3a71643766d5 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -353,6 +353,103 @@ tee_ioctl_shm_register(struct tee_context *ctx, return ret; } +static int +tee_ioctl_shm_register_fd(struct tee_context *ctx, + struct tee_ioctl_shm_register_fd_data __user *udata) +{ + struct tee_ioctl_shm_register_fd_data data; + struct tee_shm *shm; + long ret; + + if (copy_from_user(&data, udata, sizeof(data))) + return -EFAULT; + + /* Currently no input flags are supported */ + if (data.flags) + return -EINVAL; + + shm = tee_shm_register_fd(ctx, data.fd); + if (IS_ERR(shm)) + return -EINVAL; + + data.id = shm->id; + data.flags = shm->flags; + data.size = shm->size; + + if (copy_to_user(udata, &data, sizeof(data))) + ret = -EFAULT; + else + ret = tee_shm_get_fd(shm); + + /* + * When user space closes the file descriptor the shared memory + * should be freed or if tee_shm_get_fd() failed then it will + * be freed immediately. + */ + tee_shm_put(shm); + return ret; +} + +static int param_from_user_memref(struct tee_context *ctx, + struct tee_param_memref *memref, + struct tee_ioctl_param *ip) +{ + struct tee_shm *shm; + size_t offs = 0; + + /* + * If a NULL pointer is passed to a TA in the TEE, + * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL + * indicating a NULL memory reference. + */ + if (ip->c != TEE_MEMREF_NULL) { + /* + * If we fail to get a pointer to a shared + * memory object (and increase the ref count) + * from an identifier we return an error. All + * pointers that has been added in params have + * an increased ref count. It's the callers + * responibility to do tee_shm_put() on all + * resolved pointers. + */ + shm = tee_shm_get_from_id(ctx, ip->c); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + /* + * Ensure offset + size does not overflow + * offset and does not overflow the size of + * the referred shared memory object. + */ + if ((ip->a + ip->b) < ip->a || + (ip->a + ip->b) > shm->size) { + tee_shm_put(shm); + return -EINVAL; + } + + if (shm->flags & TEE_SHM_DMA_BUF) { + struct tee_shm *parent_shm; + + parent_shm = tee_shm_get_parent_shm(shm, &offs); + if (parent_shm) { + tee_shm_put(shm); + shm = parent_shm; + } + } + } else if (ctx->cap_memref_null) { + /* Pass NULL pointer to OP-TEE */ + shm = NULL; + } else { + return -EINVAL; + } + + memref->shm_offs = ip->a + offs; + memref->size = ip->b; + memref->shm = shm; + + return 0; +} + static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t num_params, struct tee_ioctl_param __user *uparams) @@ -360,8 +457,8 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t n; for (n = 0; n < num_params; n++) { - struct tee_shm *shm; struct tee_ioctl_param ip; + int rc; if (copy_from_user(&ip, uparams + n, sizeof(ip))) return -EFAULT; @@ -384,45 +481,10 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: - /* - * If a NULL pointer is passed to a TA in the TEE, - * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL - * indicating a NULL memory reference. - */ - if (ip.c != TEE_MEMREF_NULL) { - /* - * If we fail to get a pointer to a shared - * memory object (and increase the ref count) - * from an identifier we return an error. All - * pointers that has been added in params have - * an increased ref count. It's the callers - * responibility to do tee_shm_put() on all - * resolved pointers. - */ - shm = tee_shm_get_from_id(ctx, ip.c); - if (IS_ERR(shm)) - return PTR_ERR(shm); - - /* - * Ensure offset + size does not overflow - * offset and does not overflow the size of - * the referred shared memory object. - */ - if ((ip.a + ip.b) < ip.a || - (ip.a + ip.b) > shm->size) { - tee_shm_put(shm); - return -EINVAL; - } - } else if (ctx->cap_memref_null) { - /* Pass NULL pointer to OP-TEE */ - shm = NULL; - } else { - return -EINVAL; - } - - params[n].u.memref.shm_offs = ip.a; - params[n].u.memref.size = ip.b; - params[n].u.memref.shm = shm; + rc = param_from_user_memref(ctx, ¶ms[n].u.memref, + &ip); + if (rc) + return rc; break; default: /* Unknown attribute */ @@ -827,6 +889,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return tee_ioctl_shm_alloc(ctx, uarg); case TEE_IOC_SHM_REGISTER: return tee_ioctl_shm_register(ctx, uarg); + case TEE_IOC_SHM_REGISTER_FD: + return tee_ioctl_shm_register_fd(ctx, uarg); case TEE_IOC_OPEN_SESSION: return tee_ioctl_open_session(ctx, uarg); case TEE_IOC_INVOKE: @@ -1288,3 +1352,4 @@ MODULE_AUTHOR("Linaro"); MODULE_DESCRIPTION("TEE Driver"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h index 6c6ff5d5eed2..aad7f6c7e0f0 100644 --- a/drivers/tee/tee_private.h +++ b/drivers/tee/tee_private.h @@ -24,6 +24,7 @@ void teedev_ctx_put(struct tee_context *ctx); struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size); struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, unsigned long addr, size_t length); +struct tee_shm *tee_shm_get_parent_shm(struct tee_shm *shm, size_t *offs); int tee_heap_update_from_dma_buf(struct tee_device *teedev, struct dma_buf *dmabuf, size_t *offset, diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index daf6e5cfd59a..8b79918468b5 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include @@ -15,6 +16,16 @@ #include #include "tee_private.h" +/* extra references appended to shm object for registered shared memory */ +struct tee_shm_dmabuf_ref { + struct tee_shm shm; + size_t offset; + struct dma_buf *dmabuf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + struct tee_shm *parent_shm; +}; + static void shm_put_kernel_pages(struct page **pages, size_t page_count) { size_t n; @@ -45,7 +56,23 @@ static void release_registered_pages(struct tee_shm *shm) static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) { - if (shm->flags & TEE_SHM_POOL) { + struct tee_shm *parent_shm = NULL; + void *p = shm; + + if (shm->flags & TEE_SHM_DMA_BUF) { + struct tee_shm_dmabuf_ref *ref; + + ref = container_of(shm, struct tee_shm_dmabuf_ref, shm); + parent_shm = ref->parent_shm; + p = ref; + if (ref->attach) { + dma_buf_unmap_attachment(ref->attach, ref->sgt, + DMA_BIDIRECTIONAL); + + dma_buf_detach(ref->dmabuf, ref->attach); + } + dma_buf_put(ref->dmabuf); + } else if (shm->flags & TEE_SHM_POOL) { teedev->pool->ops->free(teedev->pool, shm); } else if (shm->flags & TEE_SHM_DYNAMIC) { int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm); @@ -57,9 +84,10 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) release_registered_pages(shm); } - teedev_ctx_put(shm->ctx); + if (shm->ctx) + teedev_ctx_put(shm->ctx); - kfree(shm); + kfree(p); tee_device_put(teedev); } @@ -169,7 +197,7 @@ struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size) * tee_client_invoke_func(). The memory allocated is later freed with a * call to tee_shm_free(). * - * @returns a pointer to 'struct tee_shm' + * @returns a pointer to 'struct tee_shm' on success, and ERR_PTR on failure */ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size) { @@ -179,6 +207,116 @@ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size) } EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf); +struct tee_shm *tee_shm_register_fd(struct tee_context *ctx, int fd) +{ + struct tee_shm_dmabuf_ref *ref; + int rc; + + if (!tee_device_get(ctx->teedev)) + return ERR_PTR(-EINVAL); + + teedev_ctx_get(ctx); + + ref = kzalloc(sizeof(*ref), GFP_KERNEL); + if (!ref) { + rc = -ENOMEM; + goto err_put_tee; + } + + refcount_set(&ref->shm.refcount, 1); + ref->shm.ctx = ctx; + ref->shm.id = -1; + ref->shm.flags = TEE_SHM_DMA_BUF; + + ref->dmabuf = dma_buf_get(fd); + if (IS_ERR(ref->dmabuf)) { + rc = PTR_ERR(ref->dmabuf); + goto err_kfree_ref; + } + + rc = tee_heap_update_from_dma_buf(ctx->teedev, ref->dmabuf, + &ref->offset, &ref->shm, + &ref->parent_shm); + if (!rc) + goto out; + if (rc != -EINVAL) + goto err_put_dmabuf; + + ref->attach = dma_buf_attach(ref->dmabuf, &ctx->teedev->dev); + if (IS_ERR(ref->attach)) { + rc = PTR_ERR(ref->attach); + goto err_put_dmabuf; + } + + ref->sgt = dma_buf_map_attachment(ref->attach, DMA_BIDIRECTIONAL); + if (IS_ERR(ref->sgt)) { + rc = PTR_ERR(ref->sgt); + goto err_detach; + } + + if (sg_nents(ref->sgt->sgl) != 1) { + rc = PTR_ERR(ref->sgt->sgl); + goto err_unmap_attachement; + } + + ref->shm.paddr = page_to_phys(sg_page(ref->sgt->sgl)); + ref->shm.size = ref->sgt->sgl->length; + +out: + mutex_lock(&ref->shm.ctx->teedev->mutex); + ref->shm.id = idr_alloc(&ref->shm.ctx->teedev->idr, &ref->shm, + 1, 0, GFP_KERNEL); + mutex_unlock(&ref->shm.ctx->teedev->mutex); + if (ref->shm.id < 0) { + rc = ref->shm.id; + if (ref->attach) + goto err_unmap_attachement; + goto err_put_dmabuf; + } + + return &ref->shm; + +err_unmap_attachement: + dma_buf_unmap_attachment(ref->attach, ref->sgt, DMA_BIDIRECTIONAL); +err_detach: + dma_buf_detach(ref->dmabuf, ref->attach); +err_put_dmabuf: + dma_buf_put(ref->dmabuf); +err_kfree_ref: + kfree(ref); +err_put_tee: + teedev_ctx_put(ctx); + tee_device_put(ctx->teedev); + + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(tee_shm_register_fd); + +struct tee_shm *tee_shm_get_parent_shm(struct tee_shm *shm, size_t *offs) +{ + struct tee_shm *parent_shm = NULL; + + if (shm->flags & TEE_SHM_DMA_BUF) { + struct tee_shm_dmabuf_ref *ref; + + ref = container_of(shm, struct tee_shm_dmabuf_ref, shm); + if (ref->parent_shm) { + /* + * the shm already has one reference to + * ref->parent_shm so we should be clear of 0. + * We're getting another reference since the caller + * of this function expects to put the returned + * parent_shm when it's done with it. + */ + parent_shm = ref->parent_shm; + refcount_inc(&parent_shm->refcount); + *offs = ref->offset; + } + } + + return parent_shm; +} + /** * tee_shm_alloc_priv_buf() - Allocate shared memory for a privately shared * kernel buffer diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h index 16ef078247ae..6bd833b6d0e1 100644 --- a/include/linux/tee_core.h +++ b/include/linux/tee_core.h @@ -28,6 +28,7 @@ #define TEE_SHM_USER_MAPPED BIT(1) /* Memory mapped in user space */ #define TEE_SHM_POOL BIT(2) /* Memory allocated from pool */ #define TEE_SHM_PRIV BIT(3) /* Memory private to TEE driver */ +#define TEE_SHM_DMA_BUF BIT(4) /* Memory with dma-buf handle */ #define TEE_DEVICE_FLAG_REGISTERED 0x1 #define TEE_MAX_DEV_NAME_LEN 32 diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index a54c203000ed..824f1251de60 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -116,6 +116,16 @@ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size); struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, void *addr, size_t length); +/** + * tee_shm_register_fd() - Register shared memory from file descriptor + * + * @ctx: Context that allocates the shared memory + * @fd: Shared memory file descriptor reference + * + * @returns a pointer to 'struct tee_shm' on success, and ERR_PTR on failure + */ +struct tee_shm *tee_shm_register_fd(struct tee_context *ctx, int fd); + /** * tee_shm_free() - Free shared memory * @shm: Handle to shared memory to free diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index d0430bee8292..1f9a4ac2b211 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -118,6 +118,35 @@ struct tee_ioctl_shm_alloc_data { #define TEE_IOC_SHM_ALLOC _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 1, \ struct tee_ioctl_shm_alloc_data) +/** + * struct tee_ioctl_shm_register_fd_data - Shared memory registering argument + * @fd: [in] File descriptor identifying the shared memory + * @size: [out] Size of shared memory to allocate + * @flags: [in] Flags to/from allocation. + * @id: [out] Identifier of the shared memory + * + * The flags field should currently be zero as input. Updated by the call + * with actual flags as defined by TEE_IOCTL_SHM_* above. + * This structure is used as argument for TEE_IOC_SHM_REGISTER_FD below. + */ +struct tee_ioctl_shm_register_fd_data { + __s64 fd; + __u64 size; + __u32 flags; + __s32 id; +}; + +/** + * TEE_IOC_SHM_REGISTER_FD - register a shared memory from a file descriptor + * + * Returns a file descriptor on success or < 0 on failure + * + * The returned file descriptor refers to the shared memory object in kernel + * land. The shared memory is freed when the descriptor is closed. + */ +#define TEE_IOC_SHM_REGISTER_FD _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 8, \ + struct tee_ioctl_shm_register_fd_data) + /** * struct tee_ioctl_buf_data - Variable sized buffer * @buf_ptr: [in] A __user pointer to a buffer From patchwork Wed Mar 5 13:04:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A2C0C19F32 for ; Wed, 5 Mar 2025 14:48:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+6L88VawgT5clB6S0hOB/yQKL6Af309OnWxwlD6cmBU=; b=JqFtfBHzEt6Iuc8zh3wnONUbmW Z6RmbKIlQKrRJ7/p2FHfk9fZnid0ge92B1Is779mvV3qFlFrTMYVnCboa1r4CB1jFHQv6QeKAahPV f+6zmJB8OtRoYGUiyY8lTCmIGMKUGQwlz03u+KCSPStLzL1hBUx1o3qUheMI0DrWLrlJQmMnuPmdw YH2KlszHLP9TnKM/ytBTWyXR+Js6Bmnz4/dVtICidZECszwkBGVtpwYNtPHHC5+Bkl2vJKtKH9Eod SG+ek+lLvLkmACOfNAr9dqbsfIY2Pvb5FaAzfO3BirBc8lCliDRw/UccmCwj1tC+iSKUIiO8QBN7n xLb0JqLw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpq3A-00000008P8D-3k9C; Wed, 05 Mar 2025 14:48:44 +0000 Received: from mail-ed1-f50.google.com ([209.85.208.50]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSj-000000087to-1NRw for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:07:02 +0000 Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-5e4ce6e3b8cso1311685a12.1 for ; Wed, 05 Mar 2025 05:07:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180019; x=1741784819; darn=lists.infradead.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=+6L88VawgT5clB6S0hOB/yQKL6Af309OnWxwlD6cmBU=; b=LyRUUiT8qpEbHz3wWp44CnXZ87VdXozZTB4OaNOtwkkf1GpiPgAZKYMAPxVFbftkmw Ss1YjtbUVHVjU3L+gjKcaqXk64NkCyZkGt45XgZDd+RIA8hNgJliDo56zdamKCsLaFU2 vOrv+/XW9HcuDtH2Cu3DYtAb8/6BFYrRgHVy+hJ6I80vSY4Zhz4GgjYEM8OcaqsepAKc +O4GotTj+IBAGyHGlblS1R5qhnLGUbL9Vx/CKTQeIKgJye4/X1Hbw3E225u0aB2i0tOX U0gywClyzZOr77XZY9ReSdzAEPtaFw22h6XjXgukBJum3WOLMRfAwMISC/YxdiLXadOU 5nOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180019; x=1741784819; 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=+6L88VawgT5clB6S0hOB/yQKL6Af309OnWxwlD6cmBU=; b=OAi1ipOiivXGlx6EzZLII5Vg9ROXa+iKRfzTpxUxY7Z5OBSQdCzHVmjgz1W1qWwzhn CPcx8XA3OdAyccIQDZEU7GknXgoz0sFTVZc6IbCdrU1qE7jM2UG2pvc0pVeXzYXgjZwV ZZRRl/LAJzg6PujX+8x25inK509J4e7pu4aMZqFl2kZDIWrFI0BIH2ThmmuYYhRYRJ3s Gdty+Xw64OVz9wUmXZ5jajgpA/2ypgqn6qnmSGKrutpONUWZffyHgiQMZBG0jO1/LVdM SXGO8NLfvbVEnYVLUIZyToKcN5wNxDY9f8H7ggLBNrk8abI5HZTvvQcvp6oJ5tDm9bWd YScw== X-Forwarded-Encrypted: i=1; AJvYcCUXqR4YJzZsii+iO2Z7oSeQIRzgS3hzS16Z10SbnHR4IKyXALlvOoAQ6u2P6F5cF8GzYRbH9MAeoVB1JpCgwmcE@lists.infradead.org X-Gm-Message-State: AOJu0YwB1Rj4N/mQtnY8mq0pHxvnz96OfzjG2eLtbFG/Q4EJVWn83jLt nHh5A/gai4FYK8eVZqZvvCO1RrzVgDf1vh0arqhoh/kQvz3Utj6z2PPgz4nh9h4= X-Gm-Gg: ASbGncvVwM+mvsYbmsY0IxLeyarYvu/JIKL5hZ+91n/cHkFM6IQHCyOfKK1vXvlQ8vE +8Ei/yAT/W2w675TSi53AXLx5gr+jPxLBwVk13vjeWvHcuycV0eFOFqivsE5fg2sxbk1WyQs9gJ A9luXV9uDApEFKAkb6Giv7fDqxSEqrAc4nKD5QhsqtMw9z4cdlxOdwH5aieRCatlXK198Jfad0s +5N6cVuJyJuz6IjWuOI9d7tBbqMpXVECO6h7NHQqZ13tM2UqG5YCQ5KwEhWMtRnMBkKOoJL1UDQ lKRcAhFI1ogIwUPorfLhpenOPL9EuqaQIl7E/yFlupJCVW84dAgOO99c42NkDYWYCMqw6Jh2aa0 m4W9TV5U34gVgM6OOkNfJug== X-Google-Smtp-Source: AGHT+IEAmgkcE8RyjO1pJJHrKqdAmUGw9vFkZJI7+m0/4SoKqcFz7yQm/3SS6AjKMMHXW07x446SxQ== X-Received: by 2002:a05:6402:4309:b0:5e4:d52b:78a2 with SMTP id 4fb4d7f45d1cf-5e584f51077mr7080244a12.15.1741180019316; Wed, 05 Mar 2025 05:06:59 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:06:57 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 07/10] tee: add tee_shm_alloc_cma_phys_mem() Date: Wed, 5 Mar 2025 14:04:13 +0100 Message-ID: <20250305130634.1850178-8-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_050701_367298_775CE202 X-CRM114-Status: GOOD ( 19.07 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add tee_shm_alloc_cma_phys_mem() to allocate a physical memory using from the default CMA pool. The memory is represented by a tee_shm object using the new flag TEE_SHM_CMA_BUF to identify it as physical memory from CMA. Signed-off-by: Jens Wiklander --- drivers/tee/tee_shm.c | 55 ++++++++++++++++++++++++++++++++++++++-- include/linux/tee_core.h | 4 +++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 8b79918468b5..8d8341f8ebd7 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -3,8 +3,11 @@ * Copyright (c) 2015-2017, 2019-2021 Linaro Limited */ #include +#include #include #include +#include +#include #include #include #include @@ -13,7 +16,6 @@ #include #include #include -#include #include "tee_private.h" /* extra references appended to shm object for registered shared memory */ @@ -59,7 +61,14 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) struct tee_shm *parent_shm = NULL; void *p = shm; - if (shm->flags & TEE_SHM_DMA_BUF) { + if (shm->flags & TEE_SHM_CMA_BUF) { +#if !IS_MODULE(CONFIG_TEE) && IS_ENABLED(CONFIG_CMA) + struct page *page = phys_to_page(shm->paddr); + struct cma *cma = dev_get_cma_area(&shm->ctx->teedev->dev); + + cma_release(cma, page, shm->size / PAGE_SIZE); +#endif + } else if (shm->flags & TEE_SHM_DMA_BUF) { struct tee_shm_dmabuf_ref *ref; ref = container_of(shm, struct tee_shm_dmabuf_ref, shm); @@ -341,6 +350,48 @@ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size) } EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf); +struct tee_shm *tee_shm_alloc_cma_phys_mem(struct tee_context *ctx, + size_t page_count, size_t align) +{ +#if !IS_MODULE(CONFIG_TEE) && IS_ENABLED(CONFIG_CMA) + struct tee_device *teedev = ctx->teedev; + struct cma *cma = dev_get_cma_area(&teedev->dev); + struct tee_shm *shm; + struct page *page; + + if (!tee_device_get(teedev)) + return ERR_PTR(-EINVAL); + + page = cma_alloc(cma, page_count, align, true/*no_warn*/); + if (!page) + goto err_put_teedev; + + shm = kzalloc(sizeof(*shm), GFP_KERNEL); + if (!shm) + goto err_cma_crelease; + + refcount_set(&shm->refcount, 1); + shm->ctx = ctx; + shm->paddr = page_to_phys(page); + shm->size = page_count * PAGE_SIZE; + shm->flags = TEE_SHM_CMA_BUF; + + teedev_ctx_get(ctx); + + return shm; + +err_cma_crelease: + cma_release(cma, page, page_count); +err_put_teedev: + tee_device_put(teedev); + + return ERR_PTR(-ENOMEM); +#else + return ERR_PTR(-EINVAL); +#endif +} +EXPORT_SYMBOL_GPL(tee_shm_alloc_cma_phys_mem); + int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h index 6bd833b6d0e1..b6727d9a3556 100644 --- a/include/linux/tee_core.h +++ b/include/linux/tee_core.h @@ -29,6 +29,7 @@ #define TEE_SHM_POOL BIT(2) /* Memory allocated from pool */ #define TEE_SHM_PRIV BIT(3) /* Memory private to TEE driver */ #define TEE_SHM_DMA_BUF BIT(4) /* Memory with dma-buf handle */ +#define TEE_SHM_CMA_BUF BIT(5) /* CMA allocated memory */ #define TEE_DEVICE_FLAG_REGISTERED 0x1 #define TEE_MAX_DEV_NAME_LEN 32 @@ -307,6 +308,9 @@ void *tee_get_drvdata(struct tee_device *teedev); */ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size); +struct tee_shm *tee_shm_alloc_cma_phys_mem(struct tee_context *ctx, + size_t page_count, size_t align); + int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, From patchwork Wed Mar 5 13:04:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002723 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BF9E5C19F32 for ; Wed, 5 Mar 2025 13:39:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=GV+1CN9mTm6W0e8GwrPdwh4pOa9jooWXILMnvo8a19M=; b=Fwj9Tu4GOhb9FpVGB20IT+0Rju +QWDA4EzCwDA/C+rWoF41kgQ5DBaqQKdDWj1TE6POqu7qJGOi1hTaOcjXogkNRQQpuiozRqLMAgvL dZ+mPMpSe4oLiT/iZX6fLi8YH9HJNBSXBZ03LsY3E2IDftS7KKN9QHko/7PM32Pq6uwnFkFyqpQby 2auH/Tpmq2jYF85ZFsZyi7SmTfH1W/0/AEuWTQdXzoQ6R9kS3Bpqsh/Ot3hH76CPaJ7166Bg1W+LO eG3Ql3VrEJnweMInZOLe2N5nUFvKrzcm6sepX1/uw99Hl8P2z8mII6gVzYAf2UCgbfum0MZov7Olo q+ZETs0w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpoxx-00000008DIF-30GD; Wed, 05 Mar 2025 13:39:17 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSo-000000087v7-2eQR for linux-arm-kernel@bombadil.infradead.org; Wed, 05 Mar 2025 13:07:06 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=GV+1CN9mTm6W0e8GwrPdwh4pOa9jooWXILMnvo8a19M=; b=I1B+OU+ZvspPmXZVra1hjsZjBd Jf6H+bUZJ+fCycO/MvW2r28N6BBOQn2/i3av72aTQAWyw6OnfHsoy0Z2VhU8sBpWTU+i94oM8esw8 9z9xpbjeubBIgXO2JCylPrNZ/cofgYkg+ifIDR97iKe8mKkvTYHDXIobQ14yFIlGiTft6V7vyw0Rg ff1RuTQZZvh0l3BvxGmHwJMkiy4CHCJ4xedbmPZc0rZS8RYL2epyCo2o0265w3Pf4f4XsGvB9yFIM n0QdEbi7tCTZAYpz84uI51HxYwh5M0hnogJ1ePpUOv/8T//jL1yT6jlM9+6wzP/qBjV/v0YLe+fRm pQCR9QsA==; Received: from mail-ed1-x529.google.com ([2a00:1450:4864:20::529]) by casper.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSl-00000005Xh3-3Vj8 for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:07:05 +0000 Received: by mail-ed1-x529.google.com with SMTP id 4fb4d7f45d1cf-5e4d3f92250so9365302a12.1 for ; Wed, 05 Mar 2025 05:07:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180021; x=1741784821; darn=lists.infradead.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=GV+1CN9mTm6W0e8GwrPdwh4pOa9jooWXILMnvo8a19M=; b=YG0B9k242Z+6pUlUZ/sf4Z1q50e0/anpdWsZwn5TKbV0OeMxLyg9MlHPyExTO8H/sR qBq+YFUnZe31mj5Mp6nEuHVwy/wGHtsokR1PD4S2oqYuf3bIAgBmw2ybzjhOfBGVvbcN rtWuv7cQx2kNYi/+HUkHDuY2Ld130sAMVGiNUQgLfE8lIWGTE8tAUKtnI0rFafsZOo9t HoLarjmhPat6rSPMGnPj6j1AQvUoItxv7qhurg5SjuxRWILApjbC5/U67c+5uV9ncqyq uX53x+jV9QTHFxE/ccJwql559M6GS2wu08eWHybIPUKvt1M/G3jR0vUwKNQtnvOZ/YUO CZxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180021; x=1741784821; 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=GV+1CN9mTm6W0e8GwrPdwh4pOa9jooWXILMnvo8a19M=; b=MyEyRiIAo4uwv+cIuaEJ53IudE7BusRkgPBMYv8dgRBjWaV1wu2j5kl1MPCnmIzoO6 P1PBUXVeYuIo+Ypkaye4zNtlP4/IENlshb948tRlDRBTfiex3wYc9uR0FkDKha0k7/H8 mDZh7tadm/oJePYiorcsFIvEzEumoRfd8B3jv48mtag9qWLmGuHXW3Y66JTXLfIA7eKe +Y4mF6yQwNptprjLbz7rmGUqs5x+i3ik4VD6hy+xISTN6jLqk4ETwwb6463gQCfsiJa8 xX80HrfzSQK9NHxlIapLbSpllFoX9/O7QgRhYQTD3RR6dGo6g0B8UfhS95UAeBRxLFm1 7Xfg== X-Forwarded-Encrypted: i=1; AJvYcCXjVoMnEngO+WV6IK4gmMECkVa2l4dn56ERo5G8Y5ql+uZIF14PfFJUS85Vtq3qvlEg3KHBkmmg8sKrEv7vCWQR@lists.infradead.org X-Gm-Message-State: AOJu0Yz5MqIQbuirHQhmchbWNeqGa8JxKfk1huIDehmOgFhyrmsZQ0en 5XU90eO60L1Hr39KoidulP9KcdWMSa3fo7VQBWjCPCjsDpSsezGALH1Juv9Ae3s= X-Gm-Gg: ASbGncvyuKpobAWrTLAOwN4Kps+CvIcCcndYoTOJ91kVzaX3XtMldHbpgk7xTub+G8t 5xAkvmM9eBMZx9QgV6so0CrU3E9qklJaTt7FsvqLixombBGyuuoydNmEDJtS+Vtbz0aRvBl3eMH mLt0WqPoIorI++boRQeJtwPwxOIQaLolRwcX3mFigLHzMpGvsc5/Z/HWI0C+2putDTNzSAIeayx j+g1KISCq0ylYC8mikdQGDKd0S+MmrVUNf0ubeuQKo/hi5b/W+ZBN5cWqusUdgC4qEEdUp8MtPf IwFC3gwel8rY9E3HvUdAPWcJhnC8QkE3AKv8iICjn73jCb14n0nOX+R8ks2V9JvqUucZOuDO8Et Kfp2kJN1Tz/cXD97VsEh3QA== X-Google-Smtp-Source: AGHT+IFZCxWXYzGPaJ+Fpyr5pD44xJg3mO/vEGV3TFHnOgghMwA++b6wko/XdNnqusONUByGqiK4lg== X-Received: by 2002:a05:6402:4302:b0:5de:dc08:9cc5 with SMTP id 4fb4d7f45d1cf-5e59f35eab4mr2661989a12.7.1741180021272; Wed, 05 Mar 2025 05:07:01 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.06.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:07:00 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 08/10] optee: support restricted memory allocation Date: Wed, 5 Mar 2025 14:04:14 +0100 Message-ID: <20250305130634.1850178-9-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_130703_907016_0CE2A0CA X-CRM114-Status: GOOD ( 18.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support in the OP-TEE backend driver for restricted memory allocation. The support is limited to only the SMC ABI and for secure video buffers. OP-TEE is probed for the range of restricted physical memory and a memory pool allocator is initialized if OP-TEE have support for such memory. Signed-off-by: Jens Wiklander --- drivers/tee/optee/core.c | 1 + drivers/tee/optee/smc_abi.c | 44 +++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c75fddc83576..c7fd8040480e 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -181,6 +181,7 @@ void optee_remove_common(struct optee *optee) tee_device_unregister(optee->supp_teedev); tee_device_unregister(optee->teedev); + tee_device_unregister_all_dma_heaps(optee->teedev); tee_shm_pool_free(optee->pool); optee_supp_uninit(&optee->supp); mutex_destroy(&optee->call_queue.mutex); diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index cfdae266548b..a14ff0b7d3b3 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1620,6 +1620,41 @@ static inline int optee_load_fw(struct platform_device *pdev, } #endif +static int optee_sdp_pool_init(struct optee *optee) +{ + enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; + struct tee_rstmem_pool *pool; + int rc; + + if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP) { + union { + struct arm_smccc_res smccc; + struct optee_smc_get_sdp_config_result result; + } res; + + optee->smc.invoke_fn(OPTEE_SMC_GET_SDP_CONFIG, 0, 0, 0, 0, 0, 0, + 0, &res.smccc); + if (res.result.status != OPTEE_SMC_RETURN_OK) { + pr_err("Secure Data Path service not available\n"); + return 0; + } + + pool = tee_rstmem_static_pool_alloc(res.result.start, + res.result.size); + if (IS_ERR(pool)) + return PTR_ERR(pool); + + rc = tee_device_register_dma_heap(optee->teedev, heap_id, pool); + if (rc) + goto err; + } + + return 0; +err: + pool->ops->destroy_pool(pool); + return rc; +} + static int optee_probe(struct platform_device *pdev) { optee_invoke_fn *invoke_fn; @@ -1715,7 +1750,7 @@ static int optee_probe(struct platform_device *pdev) optee = kzalloc(sizeof(*optee), GFP_KERNEL); if (!optee) { rc = -ENOMEM; - goto err_free_pool; + goto err_free_shm_pool; } optee->ops = &optee_ops; @@ -1788,6 +1823,10 @@ static int optee_probe(struct platform_device *pdev) pr_info("Asynchronous notifications enabled\n"); } + rc = optee_sdp_pool_init(optee); + if (rc) + goto err_notif_uninit; + /* * Ensure that there are no pre-existing shm objects before enabling * the shm cache so that there's no chance of receiving an invalid @@ -1823,6 +1862,7 @@ static int optee_probe(struct platform_device *pdev) optee_disable_shm_cache(optee); optee_smc_notif_uninit_irq(optee); optee_unregister_devices(); + tee_device_unregister_all_dma_heaps(optee->teedev); err_notif_uninit: optee_notif_uninit(optee); err_close_ctx: @@ -1839,7 +1879,7 @@ static int optee_probe(struct platform_device *pdev) tee_device_unregister(optee->teedev); err_free_optee: kfree(optee); -err_free_pool: +err_free_shm_pool: tee_shm_pool_free(pool); if (memremaped_shm) memunmap(memremaped_shm); From patchwork Wed Mar 5 13:04:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002743 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1FE59C19F32 for ; Wed, 5 Mar 2025 13:41:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=OqKSZBP+OJWF5gJmf7xM2I9adV5PGtGazVdFpn+CQSw=; b=jxQft6S1ZChmMlpZEaOTI67Y9P mLOEUgPrkASFaT3ZrXYlnXrbQH/YA2KSVEPrWgsmKdBuuXI+1so7GNVR5HrfzM1VqAGGmlq1LePHs UtExMVdn7mq8mSunwyHMUSC722+JOmMh3upENnodM4zI8AWMhE5EzrWPrZr+t+1a3CAw7UTG2OhYi 6UK4+UC2NMwFU3o/ztIzj6dV3Hwkj2rgS2lrzU/pCfI++Z3028ihOWK4JWaBvODkkPAxn8lTTmxqj SwolVufq0g/WEfctaYdv/osTbb8TeQfiLpUm/446af3tuHWfYZRI/IXpSLuLj48JcDHzBQRXq2NN5 ZhaHxxbA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpozW-00000008DVj-1U9a; Wed, 05 Mar 2025 13:40:54 +0000 Received: from mail-ed1-f45.google.com ([209.85.208.45]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSo-000000087v4-1D7W for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:07:07 +0000 Received: by mail-ed1-f45.google.com with SMTP id 4fb4d7f45d1cf-5e5491eb37dso5912536a12.0 for ; Wed, 05 Mar 2025 05:07:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180024; x=1741784824; darn=lists.infradead.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=OqKSZBP+OJWF5gJmf7xM2I9adV5PGtGazVdFpn+CQSw=; b=K0hTE56IlhGXSHNIDWekvsGSrtrGrDgiYVJ+/qdpkOTiACw+9uG11uG6Lrl36qfIHk loL9ahaEmjpd2skv4LvijS7cgnc6ZndOaOqbFA1/Q2EQGt9qefsWvUnU+J4IhiLcYEOz PEb/f5ZGhBTkHvt0H47CUiT8eE1Djn9k/YcAXWCqfzRNQo3YH+O80T9SnEGOrDsBLsEA OZQ+KWw9/uJMjpG2fqJ9ouU1DH+6iGFzzaMb1PuJTWk/ZyhaL5rQ/x7WaIO4+9tTg+Lf moncPk2ShEGuSQ07e5Ey7JGuZmAVveh6fYCD5JShKcB2V4zvJCn8eY+qE100FParHrVU soUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180024; x=1741784824; 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=OqKSZBP+OJWF5gJmf7xM2I9adV5PGtGazVdFpn+CQSw=; b=rynrjgL9OJp8syeRLVTyrHoDlxErsUTVy8ZZ90kF7FJjl0THxWPNdKyWCzhCu9fhtv IcNg8gQgFJ5PzNis8bStGx2rl2CvHx9Ox/1av4waU+cuuAZ6kWEwydck/GvEI9Is4Wj5 IWa+Fc+XoiJCJYzhgu8YoXBfVtr8ZW/ZRU/96NdsFF/GoOI3BpGPeX8SIpACpff4sz0Z YGzEKbO7eqK75vRNFMgvo2mI8UXg1JSovnfxwgr5VRit3jiLxgK3ZJ90BWDtzM/QdUFn NPb8XtLK5JBYZK3IvQsaMyL2M7/pPZfsV43AACp+gU5kQpAychYocfkRZPOrJn2VE6ax ZGRw== X-Forwarded-Encrypted: i=1; AJvYcCWj6vonrVJIP3bs/OOW1fFns/87NNuK7I311SA2WKxImOySHOy0fyNtWTv2x9dUmpkWof+p/N4ckbki0yr0pnLF@lists.infradead.org X-Gm-Message-State: AOJu0YysDIoajeda4Z0cE7kEBXBR3sJeiUet6mypyZEEsV5ssMx61y2r kemrTjuZZYpRD/Ne4sTKs8/WHbnthkC+7aOUElUFRseL2MSi7jgCk1F6VZ+C/zk= X-Gm-Gg: ASbGncu02vWBcsjEBRLYKghkuljnezeVhxAjK38J1iWSuSn2LBDoU8ptkxrbYZWzdOR h3H9+OZU87xM+SVYvu4l2nMTljMSA5f6+FcmWbjT3Qs968lmk8Sk64zzL+d9X5lNFvDJp14C7/5 oJ1tb1lygghLlWJLDrT8moffAzobEh/h+cNA056iu1I1DTE5OvOAloD5X0hkzRGk55o8+g99cl4 PFYdP14NWDKspams4R6BsIeHhES3dWHv3a1f3Il8yoxeqdBxQ5FhC6T+bVgugOOzm/2z2alV6CI WyLI7owNdXY6Y2IOhFkWm1k9dvvpd2awxh4pIaFPv+KyDJWNAVYMU3w46sP3nPgoxwYM4lTLYW6 Hrn72TMStdT2zaAYEm99TBA== X-Google-Smtp-Source: AGHT+IE15Fnv9zCGL44EN+x0x28iZKYTfWnu4C8Tigs1ik2W/BgqyNM9ZszaJHzYmQDtEqzGDoT2bw== X-Received: by 2002:a05:6402:2344:b0:5e5:827d:bb1c with SMTP id 4fb4d7f45d1cf-5e59f471818mr2458803a12.25.1741180024315; Wed, 05 Mar 2025 05:07:04 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.07.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:07:03 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 09/10] optee: FF-A: dynamic restricted memory allocation Date: Wed, 5 Mar 2025 14:04:15 +0100 Message-ID: <20250305130634.1850178-10-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_050706_404535_400E4476 X-CRM114-Status: GOOD ( 29.02 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support in the OP-TEE backend driver dynamic restricted memory allocation with FF-A. The restricted memory pools for dynamically allocated restrict memory are instantiated when requested by user-space. This instantiation can fail if OP-TEE doesn't support the requested use-case of restricted memory. Restricted memory pools based on a static carveout or dynamic allocation can coexist for different use-cases. We use only dynamic allocation with FF-A. Signed-off-by: Jens Wiklander --- drivers/tee/optee/Makefile | 1 + drivers/tee/optee/ffa_abi.c | 143 ++++++++++++- drivers/tee/optee/optee_private.h | 13 +- drivers/tee/optee/rstmem.c | 329 ++++++++++++++++++++++++++++++ 4 files changed, 483 insertions(+), 3 deletions(-) create mode 100644 drivers/tee/optee/rstmem.c diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index a6eff388d300..498969fb8e40 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -4,6 +4,7 @@ optee-objs += core.o optee-objs += call.o optee-objs += notif.o optee-objs += rpc.o +optee-objs += rstmem.o optee-objs += supp.o optee-objs += device.o optee-objs += smc_abi.o diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index e4b08cd195f3..6a55114232ef 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -672,6 +672,123 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx, return optee_ffa_yielding_call(ctx, &data, rpc_arg, system_thread); } +static int do_call_lend_rstmem(struct optee *optee, u64 cookie, u32 use_case) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_ASSIGN_RSTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; + msg_arg->params[0].u.value.a = cookie; + msg_arg->params[0].u.value.b = use_case; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) { + rc = -EINVAL; + goto out; + } + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + +static int optee_ffa_lend_rstmem(struct optee *optee, struct tee_shm *rstmem, + u16 *end_points, unsigned int ep_count, + u32 use_case) +{ + struct ffa_device *ffa_dev = optee->ffa.ffa_dev; + const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; + const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; + struct ffa_send_direct_data data; + struct ffa_mem_region_attributes *mem_attr; + struct ffa_mem_ops_args args = { + .use_txbuf = true, + .tag = use_case, + }; + struct page *page; + struct scatterlist sgl; + unsigned int n; + int rc; + + mem_attr = kcalloc(ep_count, sizeof(*mem_attr), GFP_KERNEL); + for (n = 0; n < ep_count; n++) { + mem_attr[n].receiver = end_points[n]; + mem_attr[n].attrs = FFA_MEM_RW; + } + args.attrs = mem_attr; + args.nattrs = ep_count; + + page = phys_to_page(rstmem->paddr); + sg_init_table(&sgl, 1); + sg_set_page(&sgl, page, rstmem->size, 0); + + args.sg = &sgl; + rc = mem_ops->memory_lend(&args); + kfree(mem_attr); + if (rc) + return rc; + + rc = do_call_lend_rstmem(optee, args.g_handle, use_case); + if (rc) + goto err_reclaim; + + rc = optee_shm_add_ffa_handle(optee, rstmem, args.g_handle); + if (rc) + goto err_unreg; + + rstmem->sec_world_id = args.g_handle; + + return 0; + +err_unreg: + data = (struct ffa_send_direct_data){ + .data0 = OPTEE_FFA_RELEASE_RSTMEM, + .data1 = (u32)args.g_handle, + .data2 = (u32)(args.g_handle >> 32), + }; + msg_ops->sync_send_receive(ffa_dev, &data); +err_reclaim: + mem_ops->memory_reclaim(args.g_handle, 0); + return rc; +} + +static int optee_ffa_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem) +{ + struct ffa_device *ffa_dev = optee->ffa.ffa_dev; + const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; + const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; + u64 global_handle = rstmem->sec_world_id; + struct ffa_send_direct_data data = { + .data0 = OPTEE_FFA_RELEASE_RSTMEM, + .data1 = (u32)global_handle, + .data2 = (u32)(global_handle >> 32) + }; + int rc; + + optee_shm_rem_ffa_handle(optee, global_handle); + rstmem->sec_world_id = 0; + + rc = msg_ops->sync_send_receive(ffa_dev, &data); + if (rc) + pr_err("Release SHM id 0x%llx rc %d\n", global_handle, rc); + + rc = mem_ops->memory_reclaim(global_handle, 0); + if (rc) + pr_err("mem_reclaim: 0x%llx %d", global_handle, rc); + + return rc; +} + /* * 6. Driver initialization * @@ -833,6 +950,8 @@ static const struct optee_ops optee_ffa_ops = { .do_call_with_arg = optee_ffa_do_call_with_arg, .to_msg_param = optee_ffa_to_msg_param, .from_msg_param = optee_ffa_from_msg_param, + .lend_rstmem = optee_ffa_lend_rstmem, + .reclaim_rstmem = optee_ffa_reclaim_rstmem, }; static void optee_ffa_remove(struct ffa_device *ffa_dev) @@ -941,7 +1060,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) optee->pool, optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); - goto err_free_pool; + goto err_free_shm_pool; } optee->teedev = teedev; @@ -988,6 +1107,24 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) rc); } + if (IS_ENABLED(CONFIG_CMA) && !IS_MODULE(CONFIG_OPTEE) && + (sec_caps & OPTEE_FFA_SEC_CAP_RSTMEM)) { + enum tee_dma_heap_id id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; + struct tee_rstmem_pool *pool; + + pool = optee_rstmem_alloc_cma_pool(optee, id); + if (IS_ERR(pool)) { + rc = PTR_ERR(pool); + goto err_notif_uninit; + } + + rc = tee_device_register_dma_heap(optee->teedev, id, pool); + if (rc) { + pool->ops->destroy_pool(pool); + goto err_notif_uninit; + } + } + rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES); if (rc) goto err_unregister_devices; @@ -1001,6 +1138,8 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) err_unregister_devices: optee_unregister_devices(); + tee_device_unregister_all_dma_heaps(optee->teedev); +err_notif_uninit: if (optee->ffa.bottom_half_value != U32_MAX) notif_ops->notify_relinquish(ffa_dev, optee->ffa.bottom_half_value); @@ -1018,7 +1157,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) tee_device_unregister(optee->supp_teedev); err_unreg_teedev: tee_device_unregister(optee->teedev); -err_free_pool: +err_free_shm_pool: tee_shm_pool_free(pool); err_free_optee: kfree(optee); diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index 20eda508dbac..faab31ad7c52 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -174,9 +174,14 @@ struct optee; * @do_call_with_arg: enters OP-TEE in secure world * @to_msg_param: converts from struct tee_param to OPTEE_MSG parameters * @from_msg_param: converts from OPTEE_MSG parameters to struct tee_param + * @lend_rstmem: lends physically contiguous memory as restricted + * memory, inaccessible by the kernel + * @reclaim_rstmem: reclaims restricted memory previously lent with + * @lend_rstmem() and makes it accessible by the + * kernel again * * These OPs are only supposed to be used internally in the OP-TEE driver - * as a way of abstracting the different methogs of entering OP-TEE in + * as a way of abstracting the different methods of entering OP-TEE in * secure world. */ struct optee_ops { @@ -191,6 +196,10 @@ struct optee_ops { size_t num_params, const struct optee_msg_param *msg_params, bool update_out); + int (*lend_rstmem)(struct optee *optee, struct tee_shm *rstmem, + u16 *end_points, unsigned int ep_count, + u32 use_case); + int (*reclaim_rstmem)(struct optee *optee, struct tee_shm *rstmem); }; /** @@ -285,6 +294,8 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, void optee_supp_init(struct optee_supp *supp); void optee_supp_uninit(struct optee_supp *supp); void optee_supp_release(struct optee_supp *supp); +struct tee_rstmem_pool *optee_rstmem_alloc_cma_pool(struct optee *optee, + enum tee_dma_heap_id id); int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params, struct tee_param *param); diff --git a/drivers/tee/optee/rstmem.c b/drivers/tee/optee/rstmem.c new file mode 100644 index 000000000000..ea27769934d4 --- /dev/null +++ b/drivers/tee/optee/rstmem.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Linaro Limited + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "optee_private.h" + +struct optee_rstmem_cma_pool { + struct tee_rstmem_pool pool; + struct gen_pool *gen_pool; + struct optee *optee; + size_t page_count; + u16 *end_points; + u_int end_point_count; + u_int align; + refcount_t refcount; + u32 use_case; + struct tee_shm *rstmem; + /* Protects when initializing and tearing down this struct */ + struct mutex mutex; +}; + +static struct optee_rstmem_cma_pool * +to_rstmem_cma_pool(struct tee_rstmem_pool *pool) +{ + return container_of(pool, struct optee_rstmem_cma_pool, pool); +} + +static int init_cma_rstmem(struct optee_rstmem_cma_pool *rp) +{ + int rc; + + rp->rstmem = tee_shm_alloc_cma_phys_mem(rp->optee->ctx, rp->page_count, + rp->align); + if (IS_ERR(rp->rstmem)) { + rc = PTR_ERR(rp->rstmem); + goto err_null_rstmem; + } + + /* + * TODO unmap the memory range since the physical memory will + * become inaccesible after the lend_rstmem() call. + */ + rc = rp->optee->ops->lend_rstmem(rp->optee, rp->rstmem, rp->end_points, + rp->end_point_count, rp->use_case); + if (rc) + goto err_put_shm; + rp->rstmem->flags |= TEE_SHM_DYNAMIC; + + rp->gen_pool = gen_pool_create(PAGE_SHIFT, -1); + if (!rp->gen_pool) { + rc = -ENOMEM; + goto err_reclaim; + } + + rc = gen_pool_add(rp->gen_pool, rp->rstmem->paddr, + rp->rstmem->size, -1); + if (rc) + goto err_free_pool; + + refcount_set(&rp->refcount, 1); + return 0; + +err_free_pool: + gen_pool_destroy(rp->gen_pool); + rp->gen_pool = NULL; +err_reclaim: + rp->optee->ops->reclaim_rstmem(rp->optee, rp->rstmem); +err_put_shm: + tee_shm_put(rp->rstmem); +err_null_rstmem: + rp->rstmem = NULL; + return rc; +} + +static int get_cma_rstmem(struct optee_rstmem_cma_pool *rp) +{ + int rc = 0; + + if (!refcount_inc_not_zero(&rp->refcount)) { + mutex_lock(&rp->mutex); + if (rp->gen_pool) { + /* + * Another thread has already initialized the pool + * before us, or the pool was just about to be torn + * down. Either way we only need to increase the + * refcount and we're done. + */ + refcount_inc(&rp->refcount); + } else { + rc = init_cma_rstmem(rp); + } + mutex_unlock(&rp->mutex); + } + + return rc; +} + +static void release_cma_rstmem(struct optee_rstmem_cma_pool *rp) +{ + gen_pool_destroy(rp->gen_pool); + rp->gen_pool = NULL; + + rp->optee->ops->reclaim_rstmem(rp->optee, rp->rstmem); + rp->rstmem->flags &= ~TEE_SHM_DYNAMIC; + + WARN(refcount_read(&rp->rstmem->refcount) != 1, "Unexpected refcount"); + tee_shm_put(rp->rstmem); + rp->rstmem = NULL; +} + +static void put_cma_rstmem(struct optee_rstmem_cma_pool *rp) +{ + if (refcount_dec_and_test(&rp->refcount)) { + mutex_lock(&rp->mutex); + if (rp->gen_pool) + release_cma_rstmem(rp); + mutex_unlock(&rp->mutex); + } +} + +static int rstmem_pool_op_cma_alloc(struct tee_rstmem_pool *pool, + struct sg_table *sgt, size_t size, + size_t *offs) +{ + struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool); + size_t sz = ALIGN(size, PAGE_SIZE); + phys_addr_t pa; + int rc; + + rc = get_cma_rstmem(rp); + if (rc) + return rc; + + pa = gen_pool_alloc(rp->gen_pool, sz); + if (!pa) { + rc = -ENOMEM; + goto err_put; + } + + rc = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (rc) + goto err_free; + + sg_set_page(sgt->sgl, phys_to_page(pa), size, 0); + *offs = pa - rp->rstmem->paddr; + + return 0; +err_free: + gen_pool_free(rp->gen_pool, pa, size); +err_put: + put_cma_rstmem(rp); + + return rc; +} + +static void rstmem_pool_op_cma_free(struct tee_rstmem_pool *pool, + struct sg_table *sgt) +{ + struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool); + struct scatterlist *sg; + int i; + + for_each_sgtable_sg(sgt, sg, i) + gen_pool_free(rp->gen_pool, sg_phys(sg), sg->length); + sg_free_table(sgt); + put_cma_rstmem(rp); +} + +static int rstmem_pool_op_cma_update_shm(struct tee_rstmem_pool *pool, + struct sg_table *sgt, size_t offs, + struct tee_shm *shm, + struct tee_shm **parent_shm) +{ + struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool); + + *parent_shm = rp->rstmem; + + return 0; +} + +static void pool_op_cma_destroy_pool(struct tee_rstmem_pool *pool) +{ + struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool); + + mutex_destroy(&rp->mutex); + kfree(rp); +} + +static struct tee_rstmem_pool_ops rstmem_pool_ops_cma = { + .alloc = rstmem_pool_op_cma_alloc, + .free = rstmem_pool_op_cma_free, + .update_shm = rstmem_pool_op_cma_update_shm, + .destroy_pool = pool_op_cma_destroy_pool, +}; + +static int get_rstmem_config(struct optee *optee, u32 use_case, + size_t *min_size, u_int *min_align, + u16 *end_points, u_int *ep_count) +{ + struct tee_param params[2] = { + [0] = { + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT, + .u.value.a = use_case, + }, + [1] = { + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT, + }, + }; + struct optee_shm_arg_entry *entry; + struct tee_shm *shm_param = NULL; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + if (end_points && *ep_count) { + params[1].u.memref.size = *ep_count * sizeof(*end_points); + shm_param = tee_shm_alloc_priv_buf(optee->ctx, + params[1].u.memref.size); + if (IS_ERR(shm_param)) + return PTR_ERR(shm_param); + params[1].u.memref.shm = shm_param; + } + + msg_arg = optee_get_msg_arg(optee->ctx, ARRAY_SIZE(params), &entry, + &shm, &offs); + if (IS_ERR(msg_arg)) { + rc = PTR_ERR(msg_arg); + goto out_free_shm; + } + msg_arg->cmd = OPTEE_MSG_CMD_GET_RSTMEM_CONFIG; + + rc = optee->ops->to_msg_param(optee, msg_arg->params, + ARRAY_SIZE(params), params, + false /*!update_out*/); + if (rc) + goto out_free_msg; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out_free_msg; + if (msg_arg->ret && msg_arg->ret != TEEC_ERROR_SHORT_BUFFER) { + rc = -EINVAL; + goto out_free_msg; + } + + rc = optee->ops->from_msg_param(optee, params, ARRAY_SIZE(params), + msg_arg->params, true /*update_out*/); + if (rc) + goto out_free_msg; + + if (!msg_arg->ret && end_points && + *ep_count < params[1].u.memref.size / sizeof(u16)) { + rc = -EINVAL; + goto out_free_msg; + } + + *min_size = params[0].u.value.a; + *min_align = params[0].u.value.b; + *ep_count = params[1].u.memref.size / sizeof(u16); + + if (msg_arg->ret == TEEC_ERROR_SHORT_BUFFER) { + rc = -ENOSPC; + goto out_free_msg; + } + + if (end_points) + memcpy(end_points, tee_shm_get_va(shm_param, 0), + params[1].u.memref.size); + +out_free_msg: + optee_free_msg_arg(optee->ctx, entry, offs); +out_free_shm: + if (shm_param) + tee_shm_free(shm_param); + return rc; +} + +struct tee_rstmem_pool *optee_rstmem_alloc_cma_pool(struct optee *optee, + enum tee_dma_heap_id id) +{ + struct optee_rstmem_cma_pool *rp; + u32 use_case = id; + size_t min_size; + int rc; + + rp = kzalloc(sizeof(*rp), GFP_KERNEL); + if (!rp) + return ERR_PTR(-ENOMEM); + rp->use_case = use_case; + + rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL, + &rp->end_point_count); + if (rc) { + if (rc != -ENOSPC) + goto err; + rp->end_points = kcalloc(rp->end_point_count, + sizeof(*rp->end_points), GFP_KERNEL); + if (!rp->end_points) { + rc = -ENOMEM; + goto err; + } + rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, + rp->end_points, &rp->end_point_count); + if (rc) + goto err_kfree_eps; + } + + rp->pool.ops = &rstmem_pool_ops_cma; + rp->optee = optee; + rp->page_count = min_size / PAGE_SIZE; + mutex_init(&rp->mutex); + + return &rp->pool; + +err_kfree_eps: + kfree(rp->end_points); +err: + kfree(rp); + return ERR_PTR(rc); +} From patchwork Wed Mar 5 13:04:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14002744 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CE9A9C19F32 for ; Wed, 5 Mar 2025 13:42:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=SZWcwQgxJYl5xqresVhiMdi9+ZPx9Y4Kk8m/1lcEjeM=; b=BrVpCDIqkZVv2nyc0RXUJ6Tvfa waqHY88iKr7GmepXojm08m36XAeyAIH03DHEi94nYVoCiqiTNCJk4cbQxwlGVKFItaGlLLl3OAbf0 UN7eP32waLnKfwiAZ1J2Ed12gdzJBHdvGTFaNsVfyEs7UBjF+DlHQMZoEWMsr4XGPoOq/HvDSTpre bmzRSSefOpT1W+1AMg3mYl7y1sKPx5NC9flqhLO/BVK63lP3HmFmFcySzK3ZFVixnj4vIf52Wpm6c KVJvNf7//CDSxG+ZuOYQAlbH3fXmxvTNRMTias7+zsyk2GtK7TaAoeQ30KWgUUlboExzumesRmK9k ILf4r3hA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tpp16-00000008DhV-07Pu; Wed, 05 Mar 2025 13:42:32 +0000 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tpoSr-000000087vp-2TZb for linux-arm-kernel@lists.infradead.org; Wed, 05 Mar 2025 13:07:10 +0000 Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-5e4bed34bccso9604975a12.3 for ; Wed, 05 Mar 2025 05:07:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741180028; x=1741784828; darn=lists.infradead.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=SZWcwQgxJYl5xqresVhiMdi9+ZPx9Y4Kk8m/1lcEjeM=; b=mMv4yaa3t8YpLQj2ZWvOUJYEZeYG7MD/o95j8CubY+Uk8apv0Wwv1iqwO8gdJucaFw 9/VALg0m540lav/cKydcc8ysSi5ogcEk8vGJ9Fmaz5VOrJCNBq9cF9Gvpg0hUKHbK4DJ bLc8b2FAm2ANiKmm4KmKHVfu7KBHeYLU4HLwZgebWJN2BFrfIPRmYbzCdIUXv9/fK5U8 PLc8lrKt4wlK5KGb7XAVKxFz78DF1seDMJIyImMp/BTyDX9L2PL0hUiUhUn3yF/KD3jg CFQAQrUfEefv6DjuxigukTOHEiL/jUp+wQbcykSEfmD0tnwUWZ3FYkxQNcpWxlYEGMym yQ9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741180028; x=1741784828; 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=SZWcwQgxJYl5xqresVhiMdi9+ZPx9Y4Kk8m/1lcEjeM=; b=HnJ5X7kHukoWhRwsZfoeUgfwTl3a+QiOEq/G6TO4y3ult3tiuApH3aAs28mCuZ8mKT TKXAP/e+fDxQ6Xj6yHy3hCb9LJLUfxm64RuuLwx+dyk4Zgpv/sQLd+PkrJnCXZffsRdd BsBwWsFP5Fuzj8qmhiXfpp72hThlZBecCRm6DZZrv2OjXlfT1uXSXn/pZ6mH/mscJlUe Q+P35hSwR73KwE+N59s1W0Gzn7oWykFEwPvUZa89V/Rd69Dz3NWhq0EroUzJhpXfgfSh VSxbi15zRT0nqLvsH3dLhdI6TwPE6S757GPaN0K0ixzjH8b9z8tIdezflIIpouTdAM4B jJ7w== X-Forwarded-Encrypted: i=1; AJvYcCVrySrDZRa/g3MwVAR30zojN9Z/ot22174mWNG7HIMpjjZg08iC5R3YfCZfqNnVXIz5cEYpdeU7wNBZIDtm3XCU@lists.infradead.org X-Gm-Message-State: AOJu0YxFZ6dpEbHdfjqyWOkyg5gH6VtWJ2XHr3w5AZq3JUijpKp867m+ C5Dhx6K3Fq1c6Ffp/T9PteBCxxBpgOBC7JaRTUV8Crfugh2Hfz6YEbMfLryAVd4= X-Gm-Gg: ASbGncuIaA0YRDpv0SP7uk0PAgD8rrF8tpl6CWaX20Cocm5uVtz4HvvnGlV9/XW5VwF DI7eaWHAwelJBYtVk4fansNKbrN5dburs7YPF3uhFz4gV4AP+u839lXPfDOvc+sGJQMuRER933S IwmC0PNJrXso7Y81D8B/XFPi+6oR9wDJ70DKCNT8PJC0YlloEEVkE557lAjbgoNdGx4R8p+S7a4 /Zii6/+DEz0r0wta0Z0hUBxAO1TSxUzJOwbnvNsIiOy7dGSQPVb+4N90h2PGBlmSOhTh7+7DN/g Zb4xoPBCL4/zdueEoDDq0r3/BvtiQ/0Ul5o0zyY4rlDihv/ohDhFXqyXzztaI9skv8bpKWuZzq+ f1oXOvcCXqtHnOXaAz/eUsQ== X-Google-Smtp-Source: AGHT+IEU8qhj3jZr5pC33H3BKUPYoPOJwyx39WdATtL+5/RDhfCQ1+ckzcmgDPihiiWE9zWeUGcUMw== X-Received: by 2002:a05:6402:13d1:b0:5e4:99af:b7c with SMTP id 4fb4d7f45d1cf-5e59f384aebmr3091724a12.9.1741180027839; Wed, 05 Mar 2025 05:07:07 -0800 (PST) Received: from rayden.urgonet (h-98-128-140-123.A175.priv.bahnhof.se. [98.128.140.123]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5bcd1595bsm65714a12.42.2025.03.05.05.07.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 05:07:06 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, op-tee@lists.trustedfirmware.org, linux-arm-kernel@lists.infradead.org Cc: Olivier Masse , Thierry Reding , Yong Wu , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T . J . Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Sumit Garg , Matthias Brugger , AngeloGioacchino Del Regno , azarrabi@qti.qualcomm.com, Simona Vetter , Daniel Stone , Jens Wiklander Subject: [PATCH v6 10/10] optee: smc abi: dynamic restricted memory allocation Date: Wed, 5 Mar 2025 14:04:16 +0100 Message-ID: <20250305130634.1850178-11-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250305130634.1850178-1-jens.wiklander@linaro.org> References: <20250305130634.1850178-1-jens.wiklander@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250305_050709_628882_934E3B44 X-CRM114-Status: GOOD ( 17.01 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support in the OP-TEE backend driver for dynamic restricted memory allocation using the SMC ABI. Signed-off-by: Jens Wiklander --- drivers/tee/optee/smc_abi.c | 96 +++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 15 deletions(-) diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index a14ff0b7d3b3..aa574ee6e277 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1001,6 +1001,69 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx, return rc; } +static int optee_smc_lend_rstmem(struct optee *optee, struct tee_shm *rstmem, + u16 *end_points, unsigned int ep_count, + u32 use_case) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 2, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_LEND_RSTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; + msg_arg->params[0].u.value.a = use_case; + msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; + msg_arg->params[1].u.tmem.buf_ptr = rstmem->paddr; + msg_arg->params[1].u.tmem.size = rstmem->size; + msg_arg->params[1].u.tmem.shm_ref = (u_long)rstmem; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) { + rc = -EINVAL; + goto out; + } + rstmem->sec_world_id = (u_long)rstmem; + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + +static int optee_smc_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_RECLAIM_RSTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; + msg_arg->params[0].u.rmem.shm_ref = (u_long)rstmem; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) + rc = -EINVAL; + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + /* * 5. Asynchronous notification */ @@ -1252,6 +1315,8 @@ static const struct optee_ops optee_ops = { .do_call_with_arg = optee_smc_do_call_with_arg, .to_msg_param = optee_to_msg_param, .from_msg_param = optee_from_msg_param, + .lend_rstmem = optee_smc_lend_rstmem, + .reclaim_rstmem = optee_smc_reclaim_rstmem, }; static int enable_async_notif(optee_invoke_fn *invoke_fn) @@ -1622,11 +1687,13 @@ static inline int optee_load_fw(struct platform_device *pdev, static int optee_sdp_pool_init(struct optee *optee) { + bool sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP; + bool dyn_sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM; enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; - struct tee_rstmem_pool *pool; - int rc; + struct tee_rstmem_pool *pool = ERR_PTR(-EINVAL); + int rc = -EINVAL; - if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP) { + if (sdp) { union { struct arm_smccc_res smccc; struct optee_smc_get_sdp_config_result result; @@ -1634,25 +1701,24 @@ static int optee_sdp_pool_init(struct optee *optee) optee->smc.invoke_fn(OPTEE_SMC_GET_SDP_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc); - if (res.result.status != OPTEE_SMC_RETURN_OK) { - pr_err("Secure Data Path service not available\n"); - return 0; - } + if (res.result.status == OPTEE_SMC_RETURN_OK) + pool = tee_rstmem_static_pool_alloc(res.result.start, + res.result.size); + } - pool = tee_rstmem_static_pool_alloc(res.result.start, - res.result.size); - if (IS_ERR(pool)) - return PTR_ERR(pool); + if (dyn_sdp && IS_ERR(pool)) + pool = optee_rstmem_alloc_cma_pool(optee, heap_id); + if (!IS_ERR(pool)) { rc = tee_device_register_dma_heap(optee->teedev, heap_id, pool); if (rc) - goto err; + pool->ops->destroy_pool(pool); } + if (rc && (sdp || dyn_sdp)) + pr_err("Secure Data Path service not available\n"); + return 0; -err: - pool->ops->destroy_pool(pool); - return rc; } static int optee_probe(struct platform_device *pdev)