From patchwork Fri Apr 4 14:31:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038561 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 8DAB1C36010 for ; Fri, 4 Apr 2025 14:36:18 +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=5ItVLbwXh6klaFZ4DOTZKuJkyifurR/QGuqAr/eTlGU=; b=etGCf3C1hh0qF45jaIzimZTR16 LYkMTlnJhj3nBtf245OCEkOs1Cl/ajpw3MPy8W/d4QfLzkTKsz+v30b9/wVGJngxrtylqmJEnH0wS 7cwZnAuTj1rOR1XvcCjZU3P2fUVGa74cCIEJZLpJMpvjzTYeK90rYD1Vqs5pRy1ig0B3ABHoyYifh lXjValFEFpH6pDMlT6+ZfUrbSF0dUncbq7e6aHHSCZL7oi03qXo0XrvKOLjMVGV9guh+fC/YCOxOB WE18LpyoKL88MGCMd704wg+LEX/b0lcW1b5Z5GdNkXv4Wx6mrJswAfaFJEaziv18756b7YVqWAj5E VRDHKLsw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i9P-0000000C00J-3cTg; Fri, 04 Apr 2025 14:36:07 +0000 Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i5r-0000000BzFx-30Gz for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:28 +0000 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-5e677f59438so3334665a12.2 for ; Fri, 04 Apr 2025 07:32:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777146; x=1744381946; 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=5ItVLbwXh6klaFZ4DOTZKuJkyifurR/QGuqAr/eTlGU=; b=WZeavRvGzPeK7+nabL1VLqREbCX1oi3VR/nL8wIAShdc1XHiJSliToY9F4AnUbzesz uzyrKPQ0CNwy6pXuRyuh71a3eBmWibal9NOj9XT1HUkPFV+ubHc+KJAiyHG3eZzHifuR a8f0QwLw86ZBAzthBatFHKAZ0QzRKCPspnNzhteH55jzqfvuYfGcf4dllvGCIGlw8l32 5gf15lZ8LS9UE3oWWuvomKo4ZKCEV8J1a5xB2hQ6gmtKyctQnY6DxotsvZP0mGfzUvFq ZL7ZFcEbo8WeQsUUmQtc6QhQuuta92OYwy2RJLp6Xuilh7J4kJKnI3M/PrU+lRSHHGzB iZaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777146; x=1744381946; 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=5ItVLbwXh6klaFZ4DOTZKuJkyifurR/QGuqAr/eTlGU=; b=S8V1l7y7DhIwmvg2MSH5g6O46BRfB0BjU5ANOCc9pd1O0JLKzjM7kvUNXPZiodm3Bu SSZDy64E3dWQ85dxm9e1/RfJOt8yrRTcK+trXzXfvHSYI55A7/kqjXBah/743pqf+MA7 1dtqIynf8XcrxnKVfxyI8Hx7HzwyFA13AZ3g2/CsHHN863M21P3bxbNMOLUKHy2sx2ry CVlQ7M7nqeT8nA8JjzNxYVYov9rVC1Ft4ohukeFecHPCtpPkdpediUTgiU8yDvWnRPlp fl3So3Yih/1R8oaosRJ03VOieW7VJ96Told2ZjxII6S0irNBYGERD5N3N0EruXKnFBtO id+A== X-Forwarded-Encrypted: i=1; AJvYcCWNcfjzRcMjRWVbf+Iqw2PCGfazLShjsDgXckhv49C9YzX4QyzcbGecfT9qWsCNegL+09QB/h1/Dkyy+RmYhHe0@lists.infradead.org X-Gm-Message-State: AOJu0Yw7scpZ2nbOTcpnQn2VMG+wO58yZP5LaIhObbM4bWiNDGrYUQUH 0kBCVzYgExivyYkc4THOLQcqdlmya15cMPaAlwUSMtvaisYNltAfYYiwuyf2IQU= X-Gm-Gg: ASbGnctYSK8LWVOmtgGYkN4O1Ao99jiQXZj8ZewfU+XV2JJ5mjmmulmG3WZSH0xNPa6 byPKZpan2YaMbfeKqzy9EI+Uh1kwz+9YPd5OguBRwy3jS9vvKScaE++VZoyELVKYAUzRsFs3eEQ 7i2Z2Se3WXqNgDLvL/NeL2rMr6pXUlQPep5g9pxcHwmxuDKrFGGOM9nAPRwv0KIy+gtV7gc0Syr 6q5PpDtd8ZUsjKO4XiwixW7Fbgac3EyjiMO377qQJhULFOvdIWknQ9FyhrI/6kv0+vc0bXKFhW5 SocDc70/GkTNpQ6xxNZ1YO65sbq4pttJFwg/dArNsjrlq9adaXKkkdJisVpoPe7Ao8aBnWhkHce 8UFBCqsDxKA0KqU2RYpasPA== X-Google-Smtp-Source: AGHT+IHJ/1I/ptH3pCVDAQfcdNx5KHUGy5Tb2VN4inalxBPszr0OVkQ817HOYwXzW+KxBXdP3/CVtg== X-Received: by 2002:a05:6402:234e:b0:5e7:b081:aa7c with SMTP id 4fb4d7f45d1cf-5f0b5ebbc4emr2568089a12.12.1743777145883; Fri, 04 Apr 2025 07:32:25 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:25 -0700 (PDT) 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 v7 01/11] tee: tee_device_alloc(): copy dma_mask from parent device Date: Fri, 4 Apr 2025 16:31:24 +0200 Message-ID: <20250404143215.2281034-2-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073227_751784_AD0F3C34 X-CRM114-Status: GOOD ( 10.44 ) 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 Reviewed-by: Sumit Garg --- 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 Fri Apr 4 14:31:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038562 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 0B5EAC36010 for ; Fri, 4 Apr 2025 14:38: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=5X2I1MlNrc8OtxTMPdYsTmJ1JjM0sba198ISiH4P8wU=; b=LaaFPy37lGaoN/IdE4PNglKSzf oc1JwudrYNlsHp2eWNlXVKUzl7lrZCeNrPIAxx2TQxrW0dd/9RlnTUE5SLRydkhfPvE9wMOTtifsc QbRhC/WI820OYdboJSsQrMMFKan7AcOLUCK240DOCFlH8E9Mn/sFhJdNvliQeCoHGIanHnUDldKMs OmUrDMdfDrmMFYZarGQg0j3Zffv8vto+PvNw7g1Ibf7xY/soZJNpwK5XPlOjBE0Kpf5+PQs0Cw4qx +ssMTsha9xfheJj3sXrksdx2NrMBNqqH0oS2GCFWS2atBuOWphKW+YeSdkWdmhputsBvy2IvM9/8T XwNLARXw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iB8-0000000C0Pg-2Hhw; Fri, 04 Apr 2025 14:37:54 +0000 Received: from mail-ed1-x52a.google.com ([2a00:1450:4864:20::52a]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i5t-0000000BzGd-40WT for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:31 +0000 Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-5ed43460d6bso3468587a12.0 for ; Fri, 04 Apr 2025 07:32:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777148; x=1744381948; 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=5X2I1MlNrc8OtxTMPdYsTmJ1JjM0sba198ISiH4P8wU=; b=Dr6DrkKZ34kaDMzpDMwOl2F9PguZUQz3WgaGTDXrhiR0agYuUrWdPKgt0nSve0e/4W FoJv5M/SAbrFIrjl/5dU2kbbfZI7xaOXPM/ly7+FHKacpxvpj60FLT7MfOailHMImFAn YEYRHMyvTWgVXJsnt62/PVXePtxYCkU6MgueBBpxVIzzr+UZ9Tjs/Bfq9nL+ALk8Fii2 ar8ufScLZLcv+4IqX9aGyzNpwM3UF4Sw2SgCr429BRAyu0IAhz17Mdr+tsUNjXgwKl5F UF6N+KILDmpM4lq7q+UeupRcK1MZ5Ca5OmAEOlliNrH0zA5bIayptOPd2TvCXmCLQ/2K 40vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777148; x=1744381948; 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=5X2I1MlNrc8OtxTMPdYsTmJ1JjM0sba198ISiH4P8wU=; b=U12pFmKbYN/kEHnqtRiRbRTopwivpAvKMfrXmXIaPRBRfkgZ4BZmmjBQYs2FX4RANw inpdK2jefCNUn5lArp7y3WRLemOGFxOXzHKueoPvlWlneW0A5AXR+rp3BOc9BFw42YB0 UrjMoN+YqzXaUZm1xm7WTxt1wHXPYTTqYZs9/ChaxF6prcvP+r+O24JKGmb8v6ZK5s4C /DaBCngJkqS7xA7ay4H/v/ZjUQsr6Dlg8hGDYMQX63jB+8B2x1UqftcFfl7/7vb5HhsP FsyPeZpKpE994Y6naskzDjr/i4mK4zOXTRiu8dq58HrJmPjDEi3k4yzY+z+k/U2rxBRT WDdA== X-Forwarded-Encrypted: i=1; AJvYcCW0kLptLaUueKN/hh0zLLFsGuES9hGl4GUPbEyh6+NhTv9+3xTnyoLT2iJS4ufYQqq+0ru0ZEQH3vlHuYnv8CNV@lists.infradead.org X-Gm-Message-State: AOJu0YxT7gFi40dOQ1JOqB9+jCzvchmOC5S3owW6XbJ7uDsDyVFKck3k ddgWDl2j+Iq3f3RgBZkqjO7vYXkI+MAaSQkKtfxCRan4rfNvZ2HaN4A8/iLGyVM= X-Gm-Gg: ASbGncujNEa8rHNDjcqYht/l0wDIa3fmVezVkzo5/FxfY3gxnxXKFT/vhBK9cG6WcXs npVko/3tl82JinBXR6e7zBx2KAcu0S1/X+8xdY8W7zAyYdflvbmjm1xB1w7pzXcVnCJO16H2Jz0 0YFUT+TqnTs2wFeSY6+MFTTBzMNsmW6sAzrde6WGE16RsyB2YnKIz04FGAd2TGmgmhtOkKG28ST duvBbkVVUjs0+S1PBQJPs4pT/uiBlPw+n9xtP66e5Es1zkQQmgLsHQcUgEyEDt6Et61YhByn2pJ sqo6pxoDzsvNdaXD+GJl+23eq4FMvogT9DS3DIRMVooKsPu9X28P+PUf7ug+lkvcEG8SzpUkhhj EszxxicRpXN6SZ7yOnL8eig== X-Google-Smtp-Source: AGHT+IFkJLuZYKHkFqitQEQ3Yg1FLEq81E4C9if1/VM+Yaec4v2BrToG7RwujiSsE0q6nDmGLkPdOA== X-Received: by 2002:a05:6402:4415:b0:5e5:e396:3f6e with SMTP id 4fb4d7f45d1cf-5f0b661aaebmr2120030a12.26.1743777148470; Fri, 04 Apr 2025 07:32:28 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:27 -0700 (PDT) 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 v7 02/11] optee: pass parent device to tee_device_alloc() Date: Fri, 4 Apr 2025 16:31:25 +0200 Message-ID: <20250404143215.2281034-3-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073229_996289_B3FD0581 X-CRM114-Status: GOOD ( 13.45 ) 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 Reviewed-by: Sumit Garg --- 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 Fri Apr 4 14:31:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038563 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 E032BC36010 for ; Fri, 4 Apr 2025 14:39: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=tnKwjJ1FVLv4umx37hI66Bb7z/WCUlz7TSg/JWGf0qo=; b=WBngM1DpTOLVMfSokHdFn3SSUw XuX05tOCbyWIBUkWwDrUJzld8V9ZYaH/DFwzsGNLj+tE53iXN7yZ5H0G6QSnSpB/Y7+paLz0/qqzo ppgctl/7zcWzAQSTinNzh2zvU9dSaGuJDVtMroqyrhBfZmOWXVHcfvUhONKEARasz0r9CZvjICK4d zijuJjLcbijbe5/GDtxB9h7SZTwm0drVvRDDL0vLw4uLsriRK9ApG8yqTlnoN/w1GyhL80Fx90Mjc n78f6W4nxsZznkS9lvqBVTcMzcERZGKliaHw9/b+sx2HUOstYKI8Ax3rhL9j3WunFFZAx0xoho1q9 1FLLVrjw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iCq-0000000C0er-0rUw; Fri, 04 Apr 2025 14:39:40 +0000 Received: from mail-ed1-x52a.google.com ([2a00:1450:4864:20::52a]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i5v-0000000BzHE-3bIR for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:33 +0000 Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-5f0c8448f99so1200604a12.1 for ; Fri, 04 Apr 2025 07:32:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777150; x=1744381950; 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=d9/8q5e/40t1pUP1lCuqdqBZhEaTbozpYl/6HYHl3Hmi1I0F9BHbqp360rZCwmGDeN bLtgaIpnxuzQwi0yloLhXAI078vPurVoJcxE2OYx8+pTsd8l5olDQv/iQE78GGHkxjeH EwRs1qRQMiUIOmhH45G8dqkwBC8Vr4MI4p13xyzStcopYEXljUAYsydEGS2ykDLkJWZv MKDNqxha9fgu5dfIrhNtNzm7O2hizhidOXPpdiuIQN8HAbsoeINI8JPOpT2yQ/qbiNoi 5wsaXVCh5+vjicM+Habp13AQwHWbrePaaEd2BqDMpWaYgtzUPV7d41kX62hzXrXQ3VLO A6Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777150; x=1744381950; 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=TMdird4TaRCNALPIZiPHb/kyQ2EoQ19b58tYlnhgTidbAboiM6+bjUqjvoLj20PImp HbSYU8kv+WyDYIZyNTt2IjJ+Qs/EO9K7cBLiU3a3p4ONLElMd7rj+X557ur56Hai6b9+ sJ5ZLPiINBDuJeauQXP//BKFz8lYpk9wDcN4IvnamrmM+8XqGcHtVoGH5iBm2uIjC76e zFbRBgghYCf8fLMXUYO72nmPbd99Mo7hXXfd6zH6HqFF2qMdq4Vfeoz0QlQBw7WHR2wj qk+haBDGnxkGEnrOVOYckry0WgY62R4b0Y9nvKzEB4dRtB3q+f6pCQdCXTJLtg6yS2pD b9OQ== X-Forwarded-Encrypted: i=1; AJvYcCW6c6riVe2G5++3AcgmluANsdcL90dQic+Jy0FXpVjyj4eOVn/Oi3328FlM5wBhRSLeoYDgEx/z7tmX79YL+vnY@lists.infradead.org X-Gm-Message-State: AOJu0Yzp13iTz6Mu79hzlPt9KDtq5/FWdkpJAwLPgChxcNpGcSGQyoSR iuOoBN3ZOIr7ggdAigTyaxsaBong81j/1OUshT2UfDKP+mbqlZ6w5ZROMznm3MlVEswUSWi7Jig wrcw= X-Gm-Gg: ASbGnctvsTNmK0aUrlk2XUOAZvV0qS5+V3uEkxxvGUtN9dzpEJIsPX8wqJNUA/472T7 Rp7QmwbAPmNzPso6E2+Fg55v9/KdoUemaXRBpS8IFTCVHQLrT96CRrEUX2Azwn+mfueCdT4WED1 lDvOdMLUemhg3OiKh3x1nKGIoHbV7qnq3QkHaE9XYsyIdWgMHfMedKYteWsikto+u7FVHb2A5BP wYkhUc85KDddvGNPH74B+Gpbr9bAvRhlubOYK/WLiZl4rwu50SdxUN8lXjuEmtBfa4moZauO2hP yUZRj/KSIek/5JeIFTiWlcRv/dHsujclMNrlnpckr2X9guwvS5N6HAHOLdh9HJ/cQD280X+E9HN Xvu763e1ECAZhOMTAfq5CDA== X-Google-Smtp-Source: AGHT+IFEAnVFrVjfr36d1giO+EGoBdAR1GXaalGBXW6UinaiYENsuFNEXqCgnVviYRCmRoOpBYYuSw== X-Received: by 2002:a05:6402:2709:b0:5e1:8604:9a2d with SMTP id 4fb4d7f45d1cf-5f0b3b65912mr3036010a12.4.1743777150382; Fri, 04 Apr 2025 07:32:30 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:29 -0700 (PDT) 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 v7 03/11] optee: account for direction while converting parameters Date: Fri, 4 Apr 2025 16:31:26 +0200 Message-ID: <20250404143215.2281034-4-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073232_072004_9D4ECEA5 X-CRM114-Status: GOOD ( 24.15 ) 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 Fri Apr 4 14:31:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038564 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 78CBBC36010 for ; Fri, 4 Apr 2025 14:41: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=F6BjtAt9Fs9/6s/sgyteem8A9dvJCTVhv9ApDG/Ww5o=; b=HXTSoyUDGbU8hlVVkM8SNa+Aob N24InmFTxzM5VopYOC4Y9c3rRr1rzW58EsIXVQjNDMHe9v5fjOgQ5XAM/w2ceG4koq2sRPTtjOOx5 Bffh9tP1OPBnPDXfnoTi564YBsnfOKmWo2wLZ1J8VyLqV52xeK1rzms+7AhBJdfOqqokz3K5LxLsk jZ0ZZ1AXQJV38OcCZCG0Gu9oxJAeOnbwVewUyYcy/fVQ31VC186wpn7CQAy85KM8ibADdOgCTvZrC pbATtsviYNp9d4Rd7FojHIdh+ZnySCTIxXwfLRn8xQkXILTOb0dpcIDiLJyxdk7i1biKKLuHBgb1u 5/W9Mz4A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iEX-0000000C0wJ-42U4; Fri, 04 Apr 2025 14:41:26 +0000 Received: from mail-ed1-x52e.google.com ([2a00:1450:4864:20::52e]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i5y-0000000BzIP-0eFL for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:35 +0000 Received: by mail-ed1-x52e.google.com with SMTP id 4fb4d7f45d1cf-5e5cd420781so2943158a12.2 for ; Fri, 04 Apr 2025 07:32:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777152; x=1744381952; 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=F6BjtAt9Fs9/6s/sgyteem8A9dvJCTVhv9ApDG/Ww5o=; b=QgdqHr39JuRqDf3R7Wmwrormn3KTEZkCenvg1KNOOnR3XlDmeSVCZU9BCHiHLaYEGV 7mVkaPNeZJdS8BbLl2wpux190Qn5UehpNLGJyL96fMH2PBVxK7GFKstabOw/p4rU/dqh wcBwmGL1rsHRXrneqXTVGKKQUUbsg9/r8bxc777uE/wVaOjI22soa7PeIumYNuODS/uz kuQr6aJjhs1HqwrzCcsroBZ2hxmT2+GlLSB05YcL7tBvOk02ucjiiR09qk6WxIBbSBLD 5k2iK9aGmUYPG4EXKxYd6ShcW/97Xn1DspXOSSFTADVqkqWPptBNSDoyCkR93uzM8FI/ hjuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777152; x=1744381952; 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=F6BjtAt9Fs9/6s/sgyteem8A9dvJCTVhv9ApDG/Ww5o=; b=lAKgl3BDyYK/Kg7LL9jRcJkeBch5vubEb3hcm3dG2lzhsT76I5l8gC7C0+/eo8HU4m edayplmimyZJwit8hOrDk0LNXzbJFsZp6/U5+h4/da+SG/lwls2y+gGGHN6DjTkUp1zZ tqfTC1jlTzP44sdesUdpUV1ET5LChBQ3RAZxbAd23cHl0iC5WHuulk9voevdQNOmFaNw u1eK7qep26BJ/fk7Qrj1/OQYvG6i6PNWRKjWqSPt0Jt/IwPKcBg6J7Q/6f8RCUd+s5ba nY/DS/sahRWGhscLivF4npPeEX7xI1mhtWg01F0+vMdLeaZD13fLd3mF81am8o/35z1c KmMA== X-Forwarded-Encrypted: i=1; AJvYcCXYRKwIB1eAVxu+x8SJQO6WnFqgVsXme43du6vpco3PrqUjAUU7u3FkXn3i0y7vfzXtgSk+mCALaBz6mDmcOVJb@lists.infradead.org X-Gm-Message-State: AOJu0YwAu2zT9Gnm2vOxqYUwy3SAz8a9v906ZjxmGN9g37kSMaKQzCiy UJGNQOeAEOakoXQ1aaWHvtKpQlsJxSKOU8N32hm470k5rLdIPqOBoudtooqMvxA= X-Gm-Gg: ASbGnct0IAAAbvu08S3dyW/ykHewUwG9REtIA9iAnlTcVmmBZeloY9lWJB0P1efU+R1 br/RzovSb/JPfRFkJvAkkypQ/gn+DgRQBTy3QgttRotLeOmM+ghAXIa8Qmma8oa2bYu18v0vvY7 A5r3qMEkrnO1ZK/AskuZ932RxFaW5J4PJJRJUPpIgXeAt7eLHBSDCCqvRdx4rTmFuR0rd5rtP0e JsunDw9eA28SCZfkLerx1pLYBgrx+z1oSMGj3Ezl3BQAUhyNWOYSMROEYOigsOI0LhPSOvBfgS3 CocuMd8iS4z4SzsZuMn3IkXqKBBL+OfK/vTyuP45XYnOB3fhy65JqRcPgEnCd6Kk+44xJpNndpP aSrKDORiGbAR0r9vBxzUqjpFezSnI0zko X-Google-Smtp-Source: AGHT+IE/s4grzJamKNkRm0AL6bHJZwn2CiadFSE8M1OzjktZeW8BdCogb4CFp6YqnkovQ4cWd1r8Ug== X-Received: by 2002:a05:6402:380c:b0:5f0:8551:9790 with SMTP id 4fb4d7f45d1cf-5f0b3bcd2c0mr2480914a12.16.1743777152260; Fri, 04 Apr 2025 07:32:32 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:31 -0700 (PDT) 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 v7 04/11] optee: sync secure world ABI headers Date: Fri, 4 Apr 2025 16:31:27 +0200 Message-ID: <20250404143215.2281034-5-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073234_192971_7DF7B88D X-CRM114-Status: GOOD ( 19.15 ) 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 protected memory, but as usual backward compatible. Signed-off-by: Jens Wiklander --- drivers/tee/optee/optee_ffa.h | 27 +++++++++--- drivers/tee/optee/optee_msg.h | 83 ++++++++++++++++++++++++++++++----- drivers/tee/optee/optee_smc.h | 71 +++++++++++++++++++++++++++++- 3 files changed, 163 insertions(+), 18 deletions(-) diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h index 257735ae5b56..cc257e7956a3 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 Protected Memory for secure data path */ +#define OPTEE_FFA_SEC_CAP_PROTMEM 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 Protected memory + * + * Call register usage: + * w3: Service ID, OPTEE_FFA_RECLAIM_PROTMEM + * 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_PROTMEM 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..22d71d6f110d 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_PROTMEM below + * OPTEE_MSG_PROTMEM_RESERVED Reserved + * OPTEE_MSG_PROTMEM_SECURE_VIDEO_PLAY Secure Video Playback + * OPTEE_MSG_PROTMEM_TRUSTED_UI Trused UI + * OPTEE_MSG_PROTMEM_SECURE_VIDEO_RECORD Secure Video Recording + */ +#define OPTEE_MSG_PROTMEM_RESERVED 0 +#define OPTEE_MSG_PROTMEM_SECURE_VIDEO_PLAY 1 +#define OPTEE_MSG_PROTMEM_TRUSTED_UI 2 +#define OPTEE_MSG_PROTMEM_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,15 +349,62 @@ 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_PROTMEM lends protected memory. The passed normal + * physical memory is protected 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_PROTMEM_* 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 protected memory reference + * + * OPTEE_MSG_CMD_RECLAIM_PROTMEM reclaims a previously lent protected + * 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 protected memory cookie + * + * OPTEE_MSG_CMD_GET_PROTMEM_CONFIG get configuration for a specific + * protected memory use case. Parameters are passed as: + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_VALUE_INOUT + * [in] param[0].value.a OPTEE_MSG_PROTMEM_* + * [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 protected use case: + * [out] param[0].value.a Minimal size of protected memory + * [out] param[0].value.b Required alignment of size and start of + * protected 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_PROTMEM assigns use-case to protected 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 protected memory cookie + * [in] param[0].u.value.b OPTEE_MSG_PROTMEM_* defined above */ -#define OPTEE_MSG_CMD_OPEN_SESSION 0 -#define OPTEE_MSG_CMD_INVOKE_COMMAND 1 -#define OPTEE_MSG_CMD_CLOSE_SESSION 2 -#define OPTEE_MSG_CMD_CANCEL 3 -#define OPTEE_MSG_CMD_REGISTER_SHM 4 -#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_FUNCID_CALL_WITH_ARG 0x0004 +#define OPTEE_MSG_CMD_OPEN_SESSION 0 +#define OPTEE_MSG_CMD_INVOKE_COMMAND 1 +#define OPTEE_MSG_CMD_CLOSE_SESSION 2 +#define OPTEE_MSG_CMD_CANCEL 3 +#define OPTEE_MSG_CMD_REGISTER_SHM 4 +#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_PROTMEM 8 +#define OPTEE_MSG_CMD_RECLAIM_PROTMEM 9 +#define OPTEE_MSG_CMD_GET_PROTMEM_CONFIG 10 +#define OPTEE_MSG_CMD_ASSIGN_PROTMEM 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..b17e81f464a3 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 protected memory */ +#define OPTEE_SMC_SEC_CAP_PROTMEM BIT(8) +/* Secure world supports dynamic protected memory */ +#define OPTEE_SMC_SEC_CAP_DYNAMIC_PROTMEM 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 protected memory config + * + * Returns the protected memory config. + * + * Call register usage: + * a0 SMC Function ID, OPTEE_SMC_GET_PROTMEM_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 protected memory + * a2 Size of protected 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_PROTMEM_CONFIG 20 +#define OPTEE_SMC_GET_PROTMEM_CONFIG \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_PROTMEM_CONFIG) + +struct optee_smc_get_protmem_config_result { + unsigned long status; + unsigned long start; + unsigned long size; + unsigned long flags; +}; + +/* + * Get dynamic protected memory config + * + * Returns the dynamic protected 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 protected memory + * a2 Required alignment of size and start of registered protected 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_PROTMEM_CONFIG 21 +#define OPTEE_SMC_GET_DYN_PROTMEM_CONFIG \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_DYN_PROTMEM_CONFIG) + +struct optee_smc_get_dyn_protmem_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 Fri Apr 4 14:31:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038566 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 7ADD9C36010 for ; Fri, 4 Apr 2025 14:43:22 +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=gMFLY8tgBdm5YQSIAMEFl5qHyQny8N65Ba6fpys5Ync=; b=jO3nLDH0TjRozZR6lFUTODXQ4P 7RqejmugCkUTko3Um+3WH7vwvkSOdeqONWsEcVF91wWrQfnqiul1w2shDICL4MW4DB1D3cGcJ2F7B E0qTydrSlwRaPf6VWnZgWN0akeH1g4KHyCdkfYxxFxLNkNH7e37raUWROrOT5BAlD4Q84BD7PtAtL bYP3Zmp/f9WsStULabr7EARMvGmFY3CLmws95kegExAkMhM40yIe+aFjDKYoLHJUZWtNxvch01vHe 5K8EhxzJox9emCBP4yvQvlyecXSRXYg6rbiSYkFjQqjc2f82Spb7hVGcIaAzPWzuMK/nVz2gEVb3N rt/x6nbA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iGF-0000000C1D1-30xl; Fri, 04 Apr 2025 14:43:11 +0000 Received: from mail-ed1-x52d.google.com ([2a00:1450:4864:20::52d]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i60-0000000BzJO-0TK2 for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:37 +0000 Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-5e6167d0536so3809302a12.1 for ; Fri, 04 Apr 2025 07:32:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777154; x=1744381954; 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=gMFLY8tgBdm5YQSIAMEFl5qHyQny8N65Ba6fpys5Ync=; b=XrCROpWbzCAWmSOmflt99B4N6lvyFbhfvM2LIEqmrrHzpEH/Pun2W/xgbt4tALtA4z pBJUvjaDf/bM5IiGslYIjVG+rafY2AdkDv4qKzzxLa20xpQfwIEnQSWkhJD6v2SyPV8r c6C/5jRVPjlayZJpjq8dITzJChZoKBpYnWkYmLqVKBcxr5KhnPLB4mTVe4cTXzUasu6D F2LmvIzkvjVwdOn7BKa6Nl/ApBRD5wpyHjiQLBzwLmeEDT5EpeLZrPSv6mSO46UN80y2 uf+EGg5zDc1MY8EZKdseNk/ffnPpCjJtGV+62S1BaLWWw7eli+7pwhCj614Oj9ZZWvHH qb+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777154; x=1744381954; 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=gMFLY8tgBdm5YQSIAMEFl5qHyQny8N65Ba6fpys5Ync=; b=jXH+GTrdveUC0+dRApxEZa0+EUd+vKXvimbchd76WPWJ1aTBwqTmC0X8A8es5OLxxj 7f2203/Po7ipAPHRsm6UE3nJ6905l7ajVkCkgeYCcNsxnYUfpV1ot9UyqGnKWd+feZXG Pz0+ZxrNMlI5KJxEMoSby4uj86sCzy5NLsxjbFEqXvjwRzkrfJXkjFoR16TtV85pTtkJ 9J2QlIr8i0cOa5VEDCiev+PKsmUE6xxgm8AyirahkYMBieldoWogUCh64WMLGDMQ3v7W 4crvWD0AB1OMv0eO4uepC6ydcx7Z2KQdaT54Z1YiTXzKT2hEA417yjFOxd3NMDlI9j+C zleA== X-Forwarded-Encrypted: i=1; AJvYcCWL7vc8Brf3MBev7DYS8s2npJrmAFJea0+U9Zt+Lv86RMtACiLDsB0moi2zcDfE9/msqAFTmJsXpQiy9NuXe9ZK@lists.infradead.org X-Gm-Message-State: AOJu0Yx6jCAbEBXMaP5JJMAC+ztU6OMvdTx92ad3j9bYTtm4BqogMVab tW4NN174Xnnkwf3fwx4u4w2QFdPUiz6QAjHI/KA/jdDUAxPUwi8VWDHXa4Adqxs= X-Gm-Gg: ASbGnctNphkBp01io2Zguz6ecwAyPs13PSXnghqoz/4Ut5a0Etm1QXOi6K6zD0tDvbt gqGdxlb+mnNJmJ9dN1GDqIxLrGzNlG9ROZFgOhtTdRloghRJMqec62kuBcpoZRF7PWrgieBQx6P mlbuf/0MSaCu4Qqf2bG62M99FM7/koYhbtfm7av5p/r5f3AvbhGS/ErSFoI4Pf7m+GhadPxMZDm LE4pBHVmZAPrNLsQaaYoHp+4fUQejr3vAYTseGPkhYTFV8skNZv6UzYypBbwy6EEFk0ugBMhYRy vxGSuyWJg4ogO6yqDaTZkBlqK1sarGGqM1s6cuqwTfiZnazZEcIcGqikp5PNBXoT2jZD6w8L7of 7EKKQqNfPYLZTpZZcwrK0ew== X-Google-Smtp-Source: AGHT+IEe0eUi4d09I1zqDHqCTm/+uQ1O2y6bi+XUr0swpeiaUM56qZ0J21lL3kmxfrVyM2yJ4tHYEw== X-Received: by 2002:a05:6402:1ece:b0:5e5:c5f5:f4b with SMTP id 4fb4d7f45d1cf-5f0b3e3658cmr3112378a12.22.1743777154258; Fri, 04 Apr 2025 07:32:34 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:33 -0700 (PDT) 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 v7 05/11] tee: implement protected DMA-heap Date: Fri, 4 Apr 2025 16:31:28 +0200 Message-ID: <20250404143215.2281034-6-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073236_158745_54CA47B8 X-CRM114-Status: GOOD ( 24.89 ) 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 protected 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 protected memory buffers via interaction with a TEE implementation. The protected 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 protected memory pool to manage the protected memory. Signed-off-by: Jens Wiklander --- drivers/tee/Kconfig | 5 + drivers/tee/Makefile | 1 + drivers/tee/tee_heap.c | 469 ++++++++++++++++++++++++++++++++++++++ drivers/tee/tee_private.h | 6 + include/linux/tee_core.h | 65 ++++++ 5 files changed, 546 insertions(+) create mode 100644 drivers/tee/tee_heap.c diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig index 61b507c18780..084bd794374d 100644 --- a/drivers/tee/Kconfig +++ b/drivers/tee/Kconfig @@ -11,6 +11,11 @@ menuconfig TEE This implements a generic interface towards a Trusted Execution Environment (TEE). +config TEE_DMABUF_HEAP + bool + depends on TEE = y && DMABUF_HEAPS + default y + if TEE source "drivers/tee/optee/Kconfig" 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..83693ddb2767 --- /dev/null +++ b/drivers/tee/tee_heap.c @@ -0,0 +1,469 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Linaro Limited + */ + +#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_protmem_pool *pool; + struct tee_device *teedev; + /* Protects pool and teedev above */ + struct mutex mu; +}; + +struct tee_heap_buffer { + struct tee_protmem_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_protmem_static_pool { + struct tee_protmem_pool pool; + struct gen_pool *gen_pool; + phys_addr_t pa_base; +}; + +#if IS_ENABLED(CONFIG_TEE_DMABUF_HEAP) +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_protmem_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_protmem_free; + + return dmabuf; + +err_protmem_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 "protected,secure-video"; + case TEE_DMA_HEAP_TRUSTED_UI: + return "protected,trusted-ui"; + case TEE_DMA_HEAP_SECURE_VIDEO_RECORD: + return "protected,secure-video-record"; + default: + return NULL; + } +} + +static int alloc_dma_heap(struct tee_device *teedev, enum tee_dma_heap_id id, + struct tee_protmem_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_protmem_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_protmem_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_protmem_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_protmem_static_pool * +to_protmem_static_pool(struct tee_protmem_pool *pool) +{ + return container_of(pool, struct tee_protmem_static_pool, pool); +} + +static int protmem_pool_op_static_alloc(struct tee_protmem_pool *pool, + struct sg_table *sgt, size_t size, + size_t *offs) +{ + struct tee_protmem_static_pool *stp = to_protmem_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 protmem_pool_op_static_free(struct tee_protmem_pool *pool, + struct sg_table *sgt) +{ + struct tee_protmem_static_pool *stp = to_protmem_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 protmem_pool_op_static_update_shm(struct tee_protmem_pool *pool, + struct sg_table *sgt, size_t offs, + struct tee_shm *shm, + struct tee_shm **parent_shm) +{ + struct tee_protmem_static_pool *stp = to_protmem_static_pool(pool); + + shm->paddr = stp->pa_base + offs; + *parent_shm = NULL; + + return 0; +} + +static void protmem_pool_op_static_destroy_pool(struct tee_protmem_pool *pool) +{ + struct tee_protmem_static_pool *stp = to_protmem_static_pool(pool); + + gen_pool_destroy(stp->gen_pool); + kfree(stp); +} + +static struct tee_protmem_pool_ops protmem_pool_ops_static = { + .alloc = protmem_pool_op_static_alloc, + .free = protmem_pool_op_static_free, + .update_shm = protmem_pool_op_static_update_shm, + .destroy_pool = protmem_pool_op_static_destroy_pool, +}; + +struct tee_protmem_pool *tee_protmem_static_pool_alloc(phys_addr_t paddr, + size_t size) +{ + const size_t page_mask = PAGE_SIZE - 1; + struct tee_protmem_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 = &protmem_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_protmem_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..b8b99c97e00c 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,36 @@ struct tee_desc { u32 flags; }; +/** + * struct tee_protmem_pool - protected 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_protmem_pool { + const struct tee_protmem_pool_ops *ops; +}; + +/** + * struct tee_protmem_pool_ops - protected memory pool operations + * @alloc: called when allocating protected memory + * @free: called when freeing protected memory + * @update_shm: called when registering a dma-buf to update the @shm + * with physical address of the buffer or to return the + * @parent_shm of the memory pool + * @destroy_pool: called when destroying the pool + */ +struct tee_protmem_pool_ops { + int (*alloc)(struct tee_protmem_pool *pool, struct sg_table *sgt, + size_t size, size_t *offs); + void (*free)(struct tee_protmem_pool *pool, struct sg_table *sgt); + int (*update_shm)(struct tee_protmem_pool *pool, struct sg_table *sgt, + size_t offs, struct tee_shm *shm, + struct tee_shm **parent_shm); + void (*destroy_pool)(struct tee_protmem_pool *pool); +}; + /** * tee_device_alloc() - Allocate a new struct tee_device instance * @teedesc: Descriptor for this driver @@ -154,6 +192,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_protmem_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 +272,28 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool) pool->ops->destroy_pool(pool); } +/** + * tee_protmem_static_pool_alloc() - Create a protected 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_protmem_pool *tee_protmem_static_pool_alloc(phys_addr_t paddr, + size_t size); + +/** + * tee_protmem_pool_free() - Free a protected memory pool + * @pool: The protected memory pool to free + * + * There must be no remaining protected memory allocated from this pool + * when this function is called. + */ +static inline void tee_protmem_pool_free(struct tee_protmem_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 Fri Apr 4 14:31:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038567 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 AF14CC36010 for ; Fri, 4 Apr 2025 14:45:08 +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=fs7nqD12lkBPC3o5IKJmDFRrEPWNWVuJ0deEV/XnG9g=; b=dM/2zX590x0oHQBkQjg80ii7D2 fzvYpO0QJ61LBM27HmqylxxCYBx+ov0CM2XOFwP2AcgPCFuyr7oWbNBqMMQXFO2VqgHazoMCACMTt 95z7tQe8UpaEN80WOm4reDJShC33NeFEJiV1cqUhnKpLtoRHeIfAqAPJ6apIGPqI12GXKKWM1/xIu S1q79IXHoeEwa4QIti61YHl+9vnn+cip3/aDpbQ1h8+5B/NFIBxaegE6Vhh7B7TzXXKJfP9TXeOXQ s9gxEMUSzqklFTdZzXXKMQeEPnbbOWi/9IIaZhdV0tFYOAiN7RKm+PJI9FMb77r4whHXa400EkCgl 0S6IyVqw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iHy-0000000C1T9-1dma; Fri, 04 Apr 2025 14:44:58 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i61-0000000BzKg-2AOC for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:38 +0000 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-5eb92df4fcbso4048797a12.0 for ; Fri, 04 Apr 2025 07:32:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777156; x=1744381956; 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=fs7nqD12lkBPC3o5IKJmDFRrEPWNWVuJ0deEV/XnG9g=; b=C50KXz0G4SFAvy0/zGW1TctuLu6sGu1y3g03OEQTdg068MqjYMFOaHWzQ2IjVMD+hE wG3vcZbwfbQIYlRRZkP2t/98dcrWsMzyKTqyjd1GZf1wqpNFK36m+/x5+zp5k/2sAFZU y/On7eFfAFjulbkKVBoO9U0BE4XbfIhjPcumPr9VWd3Wwx/N6GinGCJrUdpEJvLoBuOd m3x68NTTt1nyNLWl8z6n9J6hxZtEqthvxrqj8zcLNcOK5EMozVYgDQuLKxS2cjCrgBWl gCAegeVVu+8+693rht2BmDz3Wh15vNXkohgUEmghSIyBbQyOx3Fr1eNXedsq7VHDcXm4 R4Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777156; x=1744381956; 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=fs7nqD12lkBPC3o5IKJmDFRrEPWNWVuJ0deEV/XnG9g=; b=LDyrL+25INxRNqXw6gthQQpHaHCIAkWZVR1qbfcfw1HoGtZ/SCRTBCyXQ8+O+txHvI IZKTsAYJN+CFHrW7hpr31ksXBjJvT8EV3sUkt9COSQvW5/BdBaawoXifhm4Wb8IyFWYQ y1KbEByLTjP8J4CVZyh0+ItqD8wcT8eoIQAnj1KCgn9AihvwlHJQj4LZj1VAGtSFB4Hq kJa5u4JzGOHE7tJktT+TPF6o5Q5H/CCcjv7HhHTCWangkUOIGXKqHm4Qtpn3URr6LCqP 6cymWr5yacK2iBhrYiu6ojbK3MyZxlkMNB9gjJttfRCQ6mDL8iis/YSjWmPGK/IZi1O0 IBzw== X-Forwarded-Encrypted: i=1; AJvYcCVAoVuvjKnOUGAsl/JL8N78jnCSHINsiG0KFbOzBrltxeB3Vg64t2H+/j+HVFEUY4slFxWgFkzGNctkgH6iMYjR@lists.infradead.org X-Gm-Message-State: AOJu0YzkAVePu9EkVw8PQ5Aj9qNBLAGKJ9hXE98fCOGTPHlA9bbUEXGU DQrWpn6LP8w/7xRaQeINNxO9HwlLxalvNY+Zw/v+mMVNZhjBVbEqqq7EM0ZpR5vDFDp9Ce385X4 ggq0= X-Gm-Gg: ASbGncsOcpxcky+E8FrunldzSIFHeo5MKCGpWDSQccbzWvGyEssOeFXcMpW7baVMB59 6FQ5Puqhl6UKa4XaA70Pr/KNV3TlF5zxjN66EkbRibrAWqMn7Iv0JdeWUO2jsGdcFjRBIRDVf1d FKZYn+FeYDr/b4/gsBV+hcf7gVRcv9d70K4nd2gteXFuLUiGEjaYqLLwcdpWok0Xpg8xF5cMyZv tRaS1IxIIuIE0wj9SOVZmO3n0utuAaMdsViAGexPE0kKpOJo6dpfuFJj54ZD+qhqntbGBQuWEjN jBZXfdCHjrb7c/ZCjhqKa4dc0p9/Fy3qe+Rths2VfiSKCP0pba9xawyud6c3/DtBBzhkArcNg5w 14uq2HHrGCtaTv3E6t808Hw== X-Google-Smtp-Source: AGHT+IFs+Hyg3/qgGfM04VQJy6hexkwcypVkkd955EopjzAxNOwVqKRSb29t6l7fEI6wJVCNyo9dwQ== X-Received: by 2002:a05:6402:42c7:b0:5ec:958b:6f5a with SMTP id 4fb4d7f45d1cf-5f0b4711e42mr2859878a12.28.1743777156026; Fri, 04 Apr 2025 07:32:36 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:35 -0700 (PDT) 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 v7 06/11] tee: refactor params_from_user() Date: Fri, 4 Apr 2025 16:31:29 +0200 Message-ID: <20250404143215.2281034-7-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073237_560694_E334B514 X-CRM114-Status: GOOD ( 18.73 ) 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 Break out the memref handling into a separate helper function. No change in behavior. Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 94 ++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 685afcaa3ea1..820e394b9054 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -353,6 +353,55 @@ tee_ioctl_shm_register(struct tee_context *ctx, 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; + + /* + * 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; + } + + memref->shm_offs = ip->a; + 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 +409,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 +433,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 */ From patchwork Fri Apr 4 14:31:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038579 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 72542C36014 for ; Fri, 4 Apr 2025 14:46:54 +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=JWI5/wfw2XIY92V5DOFxDxh9wk7+UmuAY5M2ulODp2o=; b=CI1sqEM8pFyJ9aK/MYDRy8E7Fo nwM5rhw07VNHjSqmv9ggTML14jbSkA+evTBWRWoHRhMlyub+sbK116LEvMlnkfrGzYCqpkeeieFKk dBL+E+lYqp3T9VhURgyNV1MXcbmMz7qS3chlmFgXMWjblT0+24DEjn/uL7WWA6mzkIt5ieSgOk6dq 3EySUySnP5cUtflw7J0lQLwNXQwA/6WGO73mm2N3OaP2o6KgfLSs5nEM+YMzsnk9wAqQxe6mLzTfD SD4gCM3HE0MrcYfXeinSxc2m8bB0rGS1E4UrbDW/z3mMGDAqV0OfHUyjB/mNzwaJVH5pEpAdJC104 hKi/enHQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iJh-0000000C1ur-0dYY; Fri, 04 Apr 2025 14:46:45 +0000 Received: from mail-ed1-x529.google.com ([2a00:1450:4864:20::529]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i63-0000000BzLk-3LCd for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:41 +0000 Received: by mail-ed1-x529.google.com with SMTP id 4fb4d7f45d1cf-5e686d39ba2so4048287a12.2 for ; Fri, 04 Apr 2025 07:32:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777158; x=1744381958; 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=JWI5/wfw2XIY92V5DOFxDxh9wk7+UmuAY5M2ulODp2o=; b=QBecFRo7ENhqbGazLfu5YJnX2kIQ9BWD/dq1xJYFZYLiLVX9aMCEcbm6SzI+8mRZn0 y0y94ZBv+BoR+v98dtbtwRjXN1M7NTdDdMnzrmdV1e9lFftHFYZ8qHVZ/Oy3dM+73BEo ECZZOodfViY0HlMl6vMiBNRbhjKUmgjRPpuNbIMz5/4AzevK+Vsz/cHJAKQfxxZY8NDX onb6WWMxDLY33JcMbFN3N5YOqJGF1xvccP0KA3Yb4DEBjizKG6KXdNVHotUB+GJjUp7s m3ppg1Uq7ux6ASGkBA9Xn6lFL3tGtv3CTSqbVGEr2KcrDz+Zs5L0Jsb6NyQYqMhojeM8 R6QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777158; x=1744381958; 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=JWI5/wfw2XIY92V5DOFxDxh9wk7+UmuAY5M2ulODp2o=; b=JmJqgp7D4Xq9dD6KLZtzEmO1dvOMNm54CgPY8A6TG5OIV6k4JSKuTStpH0i87hINTD yCMaFjO8JjGq45aWzMwlDARfYmTt8bYSaWhdx927yZ1plfN2aBVDiYnicjVEfwQzDlrC HIez2iIY/U04dCbY1E+7vvjHJBeVKZMQG+mDtJXRaG+l6zQ1SyBSez4+rZoBB1uznzqW rGGRYWWYEged+ukx575YvyNuaLJ0ULtRqYWY9jn3DFkErl5C+kI/AR0WNDKbhQCmcHS7 b51d0QyXYJwbDMIIUVr7g/T0tBHQ9jY8eHqRsbj65p8THyBsqiWuWKX7tLHlYVoWwuIR 2P2Q== X-Forwarded-Encrypted: i=1; AJvYcCVJG9t31tFWu8MjCPoYCDaSlqEc0JvxWvzGdbqYfoGQHDJCf3CRx9rmuIzLO3MH742O2nAA8KioEARqkVeeK6hl@lists.infradead.org X-Gm-Message-State: AOJu0Yyepc5gkFvgDeBd35OtK6alvNzZuua+chTZkdQRPH8m6u0r+9zZ HRqLvvWVVvKF/5ZIpl59FsOW1pyO4EXLUusrDe14H78CJGcB5V0TdyNJe013aiY= X-Gm-Gg: ASbGncuhDxIu05Pq64MrUPNP2gYjJplFk0qH45kyjVyAIt4bdQnmJmNV8djU9Nx/dvv KYNaWceBswN+FFBazscUzBtwqPKuNZBzVezRWUcCI0cVnLuJq7Vyh/FBIHWZWGzo//wdZwLJgeR I1HrmvawlcozcfyHEHF+GncIh1mwKeqS8R5eEchd9isLOJpidEU2mbLxAsoiOcKmyfaTlDx6mBr CaSnRTVOU7VazIQzEssosOLiwV8ySmwOV0uwDYp633xuTvO2FMeSBmSV6rucLfS6vhdo9Dmp66g LflA80gc0oET1ug/uxF9LOQWC7zcaMyx3aw6ASYEng3aT47El5QPV6cyfk+VR4wt1QFJpj8j+HD bH+IEy9LuMY3dlbxCPwd1LA== X-Google-Smtp-Source: AGHT+IEkj6B8aYCauBjQUycfpo6dEovhSrl8tra6E+j4TxdWtkdhXZHtgmBSixMkQtlIRWUpbXrT0Q== X-Received: by 2002:a05:6402:2811:b0:5e5:e836:71f3 with SMTP id 4fb4d7f45d1cf-5f0b4702134mr2810933a12.29.1743777157959; Fri, 04 Apr 2025 07:32:37 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:37 -0700 (PDT) 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 v7 07/11] tee: new ioctl to a register tee_shm from a dmabuf file descriptor Date: Fri, 4 Apr 2025 16:31:30 +0200 Message-ID: <20250404143215.2281034-8-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073239_843740_CBA1D115 X-CRM114-Status: GOOD ( 33.86 ) 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 Add a userspace API 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 returned file descriptor. Userspace is free to close the dmabuf file descriptor after it has been registered since all the resources are now held via the new tee_shm object. Closing the tee_shm file descriptor will eventually release all resources used by the tee_shm object when all references are released. The new IOCTL, TEE_IOC_SHM_REGISTER_FD, supports dmabuf references to physically contiguous memory buffers. Dmabuf references acquired from the TEE DMA-heap can be used as protected memory for Secure Video Path and such use cases. It depends on the TEE and the TEE driver if dmabuf references acquired by other means can be used. A new tee_shm flag is added 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 | 63 +++++++++++++++++++++- drivers/tee/tee_private.h | 10 ++++ drivers/tee/tee_shm.c | 111 ++++++++++++++++++++++++++++++++++++-- include/linux/tee_core.h | 1 + include/linux/tee_drv.h | 10 ++++ include/uapi/linux/tee.h | 31 +++++++++++ 6 files changed, 221 insertions(+), 5 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 820e394b9054..d26612ac060b 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -353,11 +353,49 @@ 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, @@ -388,6 +426,26 @@ static int param_from_user_memref(struct tee_context *ctx, tee_shm_put(shm); return -EINVAL; } + + 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 are clear of 0. + * We're getting another reference since + * this shm will be used in the parameter + * list instead of the shm we got with + * tee_shm_get_from_id() above. + */ + refcount_inc(&ref->parent_shm->refcount); + tee_shm_put(shm); + shm = ref->parent_shm; + offs = ref->offset; + } + } } else if (ctx->cap_memref_null) { /* Pass NULL pointer to OP-TEE */ shm = NULL; @@ -395,7 +453,7 @@ static int param_from_user_memref(struct tee_context *ctx, return -EINVAL; } - memref->shm_offs = ip->a; + memref->shm_offs = ip->a + offs; memref->size = ip->b; memref->shm = shm; @@ -841,6 +899,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: @@ -1302,3 +1362,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..308467705da6 100644 --- a/drivers/tee/tee_private.h +++ b/drivers/tee/tee_private.h @@ -13,6 +13,16 @@ #include #include +/* 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; +}; + int tee_shm_get_fd(struct tee_shm *shm); bool tee_device_get(struct tee_device *teedev); diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index daf6e5cfd59a..e1ed52ee0a16 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include @@ -45,7 +46,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 +74,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 +187,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 +197,91 @@ 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 = -EINVAL; + 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); + /** * 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 b8b99c97e00c..02c07f661349 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..8ec5f46fbfbe 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -118,6 +118,37 @@ 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 dmabuf reference + * @size: [out] Size of referenced memory + * @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 the + * kernel. The supplied file deccriptor can be closed if it's not needed + * for other purposes. 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 Fri Apr 4 14:31:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038580 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 62F32C36010 for ; Fri, 4 Apr 2025 14:48:43 +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=q5qo2YyNIySD0VmMNIZFqRKusBLbWYGLyvGHeWkP+bg=; b=peZeIU6tt/3lMs7V1g/cE5vJMR 3rn/aQAXuFJcL4rNd/5jvaGRBjngO7BGQUr6Nl+pjOAEYWbBgcpvSMCVctDnliaa6ifAMloTmoeFf vY7OBddGmHrMozrId9m27tyGI1+jHiNBcd/6WP7QEC9+79b7KIwG1r/lFukKGQn9v+9GkZJPNUZQg ojYoreqtpByG/L0cpLvKwOTWgU0BOnOINlQiCjOnFdXckvVMghUQyfw4h7Pyb6mbWoY0uRjuqsW7Q 8eAFwIQg23kGRIbd6IgTg8sMKjtC4keru/DhU87bLAXXaP7ppCDqzXtkpcZ0mpJU1q1CA27VhMrIy bimgljxA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iLP-0000000C2Jm-3V8Z; Fri, 04 Apr 2025 14:48:31 +0000 Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i65-0000000BzN0-1BLZ for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:42 +0000 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-5f0c8448f99so1201051a12.1 for ; Fri, 04 Apr 2025 07:32:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777160; x=1744381960; 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=q5qo2YyNIySD0VmMNIZFqRKusBLbWYGLyvGHeWkP+bg=; b=gRjJlsqmHnQGpvif967PvQv4L9BDjjA1wwPWRHWiAb5o9UTxyOevyO1eDDYCFsyevU q9fzFj0yevAKIRmBWjfRfe3GUxzSIOj5HLOjBm+niqkB8T9dtQsPCr05yBo3HPtLZZQr jRixuolaesr8agaPVfb8OTAJZEy0XFDVDiI7wWnvflv9AtS/3sXrjRV2ohOsj86BnK1+ yNMzjvW/um8VIXvzsQQVlmgzM9tnzlZMuXhLZf0GcuNZbF0+ShoImUTtxuAv+hiYNmqU xtasnvS6fvNP2ehNLcS/H/Pml4nu6nKUffMEri8Nks0JhgQP9leorERYrOf0W18JCxzS r9Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777160; x=1744381960; 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=q5qo2YyNIySD0VmMNIZFqRKusBLbWYGLyvGHeWkP+bg=; b=Orr0ciec+extpLP2QP9d3yxRcb1goHIB1f0sXvHkpH2BIz8CguCcRISCHfvcdBH7dx lNXAY07J/jTllyTE1CSONC2Qo5tBekwJtUimB08hBd77ia1kBNJJPqgFlAQOVFiYXi2B KLqN47wDz68RL3H+fzt22aX7I8OA2H73ITbftIS7Tds6I7SxpUq2y5elC8I9GqygIHCr P1qo+Sm76gsGFO6Nn1vI8oy2w0rA06OrUK9HCiCrmKjKypF0IXHIK0uzHiLXwTnMRDat W1Lng7LD3D/CVP/E8bZQP0WjJH13MMwxS5qjqMQMrFqXdcOltZrE/Qg8j/XntfTecADI FIJg== X-Forwarded-Encrypted: i=1; AJvYcCVxr2f+2npbvo9ySJzj+vxvpoffnQ3RPIsxSJRNLiuzjymLSNmmLSHSBOHfLlpKgGcQQhrbDNCmafqah/WeNPdn@lists.infradead.org X-Gm-Message-State: AOJu0YzZKKkDNOYCAP31rVVBk41FsGAfh/RiHsmE2JZeE2RqzT20bl0r 99k1GztfZAx9T7oCDmZPtnOxiRrNQmgKxB4PFbXCQr8VyUITX2nooAHBl7R9fSk= X-Gm-Gg: ASbGncvqOrCFMNNApHyXFUJfz/n8Mcy+4s/hLLfkj5yHM5HGcNqSNQis/nJLaCTE9Wf gbp2z9J9hSg2UYjL4EJmjcnyDJApHPOUcjjUePbp854npbukRfj1VBQex9pVSeucEv4foda8dCR MOmJvTzSNsU1ab+hsZu43gdA/REuHlI8iw9tt96di5nqlK19IglJwig3/QxKD5Ip7qvJAIn5rDf gxx8NOgpe/4AwaC5G39Iqmjyiyr9o6VAREnwqp69LcHS1Q5RCO4yH1k202aQ48DFS37Epjngt+B CiBYCimMK2abOY3bRSNMS4uLqw/PGvp2EjSyDAq0j2Bssdtb2NJJyUjilGLkvkxNxa30lOaMRe/ EyxYEyNHaiKOnS7kuZoeRVQ== X-Google-Smtp-Source: AGHT+IEM2hKGK5BPtUOQZ2C93jlWGXwVhi6Jdx1BijC2kUctXxlRef+Ez6JQ6wrB5PbeK6VU5VkWDQ== X-Received: by 2002:a05:6402:2347:b0:5e4:be64:b562 with SMTP id 4fb4d7f45d1cf-5f0b3b658ecmr2441621a12.1.1743777159861; Fri, 04 Apr 2025 07:32:39 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:39 -0700 (PDT) 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 v7 08/11] tee: add tee_shm_alloc_cma_phys_mem() Date: Fri, 4 Apr 2025 16:31:31 +0200 Message-ID: <20250404143215.2281034-9-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073241_318894_A91242EE X-CRM114-Status: GOOD ( 19.58 ) 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/Kconfig | 5 ++++ drivers/tee/tee_shm.c | 55 ++++++++++++++++++++++++++++++++++++++-- include/linux/tee_core.h | 4 +++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig index 084bd794374d..53514cccd1c9 100644 --- a/drivers/tee/Kconfig +++ b/drivers/tee/Kconfig @@ -16,6 +16,11 @@ config TEE_DMABUF_HEAP depends on TEE = y && DMABUF_HEAPS default y +config TEE_CMA + bool + depends on TEE = y && CMA + default y + if TEE source "drivers/tee/optee/Kconfig" diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index e1ed52ee0a16..d6b310b4a5fc 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" static void shm_put_kernel_pages(struct page **pages, size_t page_count) @@ -49,7 +51,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_ENABLED(CONFIG_TEE_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); @@ -306,6 +315,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_ENABLED(CONFIG_TEE_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 02c07f661349..3a4e1b00fcc7 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 @@ -310,6 +311,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 Fri Apr 4 14:31:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038581 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 B7999C36010 for ; Fri, 4 Apr 2025 14:50:27 +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=qqVUo9839x0Dz2BO0CX+S7eZwnYbMhFJhNNlz9OFNHU=; b=sh+Xn2iXRyQ2vihlza01wSunDf roEdEvClQiPggIVTsLp3Hxdb7+9YhjRBX5WfWa8WnA+ilGbcu1ZOMH3ZK7BbYzFeA786BFeSJEGrV jhN5gSDGoVoqia3hEKPqxpapanMYO/V27iEg0sGXEUEV14voY6iX3yTDo++r9C5R7B9j8anjb8+lG l0D7qREART3drktQ+25eMsRI5HpCL0SV7JTijdGHGE7DL6GdJGqAlLOz9gDC2guSBJR+Khk0WSf9Q EA2OFVSmt6uV7yAcFNdrXpFB+CbKlm6V0hxFTTJFjdHy7J/mCDAI/027EiPlWrXYs6Lbb0pzXFErz J8scYLXA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iN8-0000000C2lr-27zU; Fri, 04 Apr 2025 14:50:18 +0000 Received: from mail-ed1-x52f.google.com ([2a00:1450:4864:20::52f]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i67-0000000BzOf-2DRS for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:44 +0000 Received: by mail-ed1-x52f.google.com with SMTP id 4fb4d7f45d1cf-5e8be1c6ff8so3974467a12.1 for ; Fri, 04 Apr 2025 07:32:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777162; x=1744381962; 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=qqVUo9839x0Dz2BO0CX+S7eZwnYbMhFJhNNlz9OFNHU=; b=PdYf3vyhAC9MnN9xRssK9ufN+zmflrXbC/fv5cuXGrToeblG9rKTNdZCGmyqxLxw67 0k+s7yyR4vltlYjT53gazztUL9Hm8xEYeLWD+V3wuCqTbwcauuN43pMyAPL5LWmz6Buu rFWZ+0/M9xTiUENNSwpqlfBhIgdTIPlyk4v+JL9umrtSGN5Yumy9FAZGlAsS1dBFWjW7 3jNrLiUUqPBHNbP8XjxA+mDUGiEL0BTJ+xQwkIzJ9GGVGTsybB0RV4JQf6Kir2hdwZLw et1XGl+sr+3hbWSvZUTUKPlQl7oaWO48fjnR8wWxi88yNgXWYGmCiRbONe6DlJBdJP04 b5ZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777162; x=1744381962; 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=qqVUo9839x0Dz2BO0CX+S7eZwnYbMhFJhNNlz9OFNHU=; b=bhh0vWPBC+agJS5urT5Bf/13Mm/2iqaSt9lIKCiVklnqH9OUZUD2DrxYGfJDcwhZZF zJjGWr+cV0LjGWLJcBqRT6AnDTkFwlZeuzL02gS6pqV4Q4bVSARWmcWr5414OUCIXuOw vb3zInYw2PFeGm8SDTxUkl8O53G2TZEbSt3eucTqnU7+VqJtVvvGVtAZLCMRcyRwkJW+ 4Q7iF8Ey5Q1NRrbAQMo3F4P1F3uh6Pi+DICFPhCw8yA/e4eomuFo0LrByHeDho6J0Qsq V9dA0rEHNDWyfAmQt0Y3hweV7zGYWzgDrFVB+4l8mTgn5pREJ/DAy24/bjgCQ1XtpIbw bqHQ== X-Forwarded-Encrypted: i=1; AJvYcCX7IKavg/57DwWt1JeEJ++QffpF0wFjzVn10V3RV+5SpUjY+Emw4Sg8UxpO6dxp1IvqzZkiN49mAG84hTOr59d7@lists.infradead.org X-Gm-Message-State: AOJu0YxXw8WQcYbwDlV/owzxKvVlIfqlbQ6bHDP/4bujIppSv36CCI0z b5hFo4pOcgG97g/yYqTru4b1/vz9b7iON3WI0yjdZFYDpvwHefWsE9wWY/w2QKY= X-Gm-Gg: ASbGncsbMgvZOGJxrLtc4dANrfADlWslhwjR4thN1TY+50XrobTcddgu8Ib9daZPRQN E+WoJUUoXmhMbvHjwUC1Xa/YDuH62nmE798DIxLpb1d9u5JWpQ1S4RDS2yPFVqkoboii6btjP5P hZFzW9ESFVaeveW1BngVWGuKbt0F1UISm7RmJUjU4nh+7OICHpswcFl6+59idVvGPbQgtBKrxad 8Xxj/Ed8yBnl0h6hi5DeHv/wbkNsgdbHqob3XH2h7WYqUEbMUzSem9C9FO+euIxL0rF+t2MkKDx LXvfLD79lPWCg4AoJOZV3JFD+BlN4t5Ez4PoLhns0AYuhE7FQISoUEEBFFM9xt6kJo0CwRVQHKr R1XlwdLXSgMHX+d+3ds5Geg== X-Google-Smtp-Source: AGHT+IGI4VswEXbkr8wvPcpZqZzKqeC9kMo0saIbDftZfl+T9cBHd+BN83SFjwOfSSTztOoIdlkUdw== X-Received: by 2002:a05:6402:5cb:b0:5ec:cc28:1a78 with SMTP id 4fb4d7f45d1cf-5f0b657a59dmr2556677a12.20.1743777161950; Fri, 04 Apr 2025 07:32:41 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:41 -0700 (PDT) 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 v7 09/11] optee: support protected memory allocation Date: Fri, 4 Apr 2025 16:31:32 +0200 Message-ID: <20250404143215.2281034-10-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073243_565724_822C77A7 X-CRM114-Status: GOOD ( 17.73 ) 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 protected memory allocation. The support is limited to only the SMC ABI and for secure video buffers. OP-TEE is probed for the range of protected 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..c10b38b23586 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_rstmem_pool_init(struct optee *optee) +{ + enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; + struct tee_protmem_pool *pool; + int rc; + + if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM) { + union { + struct arm_smccc_res smccc; + struct optee_smc_get_protmem_config_result result; + } res; + + optee->smc.invoke_fn(OPTEE_SMC_GET_PROTMEM_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_protmem_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_rstmem_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 Fri Apr 4 14:31:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038587 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 C2376C36010 for ; Fri, 4 Apr 2025 14:52:16 +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=zftogUH8wrVhS+ppxIzLQgaqNYiWDbaDEKbm5R6PXVo=; b=WArgyU6Rfa2Fr6hbeHbMXX5NA6 vOqcKLdAEQErpuulqT4gXqMbT8EIaHm8RhJGmC0WIMeAOhvfl+/Ry+9junOcMuIFEw1Q4E4ble16z eYaBf35oI5k2WG6vwqvG37sD9JtOEhFbH5Bjw3tRhfgyFYgg/YMehaSB5bsDV4MCUOSG5zD6xYzy0 aSeK8kg64y/BMsnVaZM0XTmg1l2Kjo2xX6uvBBjc5vnChzN7pmAJsE36hk+nNeYu52to+Qc1dAxiS 0m4+P4Wi/r3Mcrk1AFnmXZ85Fm0mrgvLasUKwc9e5QwKzWSBUzmajM31acqGMbRtrNaBdHjAvPL4q f0radmrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iOr-0000000C3EF-1A5S; Fri, 04 Apr 2025 14:52:05 +0000 Received: from mail-ed1-x52c.google.com ([2a00:1450:4864:20::52c]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i69-0000000BzPF-2Zpc for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:46 +0000 Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-5e673822f76so3625364a12.2 for ; Fri, 04 Apr 2025 07:32:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777164; x=1744381964; 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=zftogUH8wrVhS+ppxIzLQgaqNYiWDbaDEKbm5R6PXVo=; b=LAfq26OHqF7zs+cM4QgkX7LN/olIo2C9th1z8YjczyVoeaB9mWLfYX0RiSl/aajwKj 9p/hWPDON/t2gyr2H5qxHTEBTAMzdEHxiZLQfhZlatF55SZ+NlBV7qorZAq+dNkmSu6g GGPdiRcHhJ+MYTB7ODsuBdrcIqTYt7Yc0fKEAJjy0c3pkJUYHtNZfFO78UPITQ3WCLU1 V164uHlOldVRv+MJ6w418957U87716czLjs9/FLlmC6yZrEbJF7/KfDCd33OiClp88uB NxcEGm2wHUo25UO29WdYtUar+i0UIQ0PqSeuC1uST9g4LCz2V7inEssLHzlEXtcjQwDV yHTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777164; x=1744381964; 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=zftogUH8wrVhS+ppxIzLQgaqNYiWDbaDEKbm5R6PXVo=; b=e0QknKEj5bYDdTU7h+/xEsDzJPFhi5FoXj4jrtmP7LXUoKXpVKHZFF36Z56R16JgG/ De37GtuLTJ+UqIstwyqdh8WgOUv0HC+yERH3w3mvrxYSK7mgd89aPAba+Hfh/OOthi0K 3Ie/QBxamj+FadVilQHQzV3GZZgmcuNMJR8HQVKf8LuxmsZtztYcFzCLlwd4bBQXCsW1 ouSXiX6YvXnYhylKldj5h3Fmyni5u13pS5CFIuFp884Vx+wClFgYOpLaPhLSLrelmYSN uTxLfEgKzSKxNy8Xajmc3gJuaIDNQzLEc6igazEbnkw83C2SratnNKWbv9PgHge9MJLO UDQw== X-Forwarded-Encrypted: i=1; AJvYcCWEsN/pu116s3i7EBd1x2WI3Ci4EoBs5PlDEu0MGFWIeerZSo+deLgzFn5CB9uwEV8qkD28HUlWrZHTXrarZHf8@lists.infradead.org X-Gm-Message-State: AOJu0Yxzd/tdL1dmtI7XFLmRLTqdCLsKv73VzK1i977D92OWjomosSbm IuQ/XLVNceoFtyOoF/8Xn7Ze8Ey3GzCWX9HmNkah2L1uL+1TwQ/R28xfUDhV+DM= X-Gm-Gg: ASbGncubgXu1Zo2ekM0NzfdIBSU98WUY/vN8E1ENVOdjv3+dBbPK4mAVFtD+97UtZ1u B1izilarrI5hbKmcSSI33TgSbYIpMQKEI9wDbKmzIKcombc990HLMZMpPxAPoA0yY0Jwgl3EhmP tSITsy1cbhkM6ReBF0Kio5erWkbDmzLYjYLphDxLk4fVVbDJnMDM8Vs8iANEoSuwEvxRkXrpLU5 +ilDMsBhPdkOr8bu7ROzqzvD48wS6jx+M1ADr1kgqdwNbtb0PeIqsQlvtRNiBQicQEKYJsWWrcF gOQY1WBYRfoad0dk/5jFc5pq5bDOqlZ7IVPfnGIPtaQyG/WW47O9orEZQDeIXi6r6yqcJbOFx4I 5abUIsP6r8+DB8X9jIL3gyw== X-Google-Smtp-Source: AGHT+IFjGhwgHZOVgOI2F03Goqk+5N163rrNp4qt5sJZVhpDmuR+V3ybcqRsEzSx49PUhVBHLk7XOA== X-Received: by 2002:a05:6402:3593:b0:5dc:c531:e5c0 with SMTP id 4fb4d7f45d1cf-5f0b6606169mr2834359a12.27.1743777163798; Fri, 04 Apr 2025 07:32:43 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:43 -0700 (PDT) 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 v7 10/11] optee: FF-A: dynamic protected memory allocation Date: Fri, 4 Apr 2025 16:31:33 +0200 Message-ID: <20250404143215.2281034-11-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073245_674957_F317E9FF X-CRM114-Status: GOOD ( 28.76 ) 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 protected memory allocation with FF-A. The protected memory pools for dynamically allocated protected memory are instantiated when requested by user-space. This instantiation can fail if OP-TEE doesn't support the requested use-case of protected 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 | 144 ++++++++++++- drivers/tee/optee/optee_private.h | 13 +- drivers/tee/optee/protmem.c | 330 ++++++++++++++++++++++++++++++ 4 files changed, 485 insertions(+), 3 deletions(-) create mode 100644 drivers/tee/optee/protmem.c diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index a6eff388d300..ad7049c1c107 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 += protmem.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..98cb0e9094eb 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -672,6 +672,124 @@ 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_protmem(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_PROTMEM; + 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_protmem(struct optee *optee, struct tee_shm *protmem, + 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(protmem->paddr); + sg_init_table(&sgl, 1); + sg_set_page(&sgl, page, protmem->size, 0); + + args.sg = &sgl; + rc = mem_ops->memory_lend(&args); + kfree(mem_attr); + if (rc) + return rc; + + rc = do_call_lend_protmem(optee, args.g_handle, use_case); + if (rc) + goto err_reclaim; + + rc = optee_shm_add_ffa_handle(optee, protmem, args.g_handle); + if (rc) + goto err_unreg; + + protmem->sec_world_id = args.g_handle; + + return 0; + +err_unreg: + data = (struct ffa_send_direct_data){ + .data0 = OPTEE_FFA_RELEASE_PROTMEM, + .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_protmem(struct optee *optee, + struct tee_shm *protmem) +{ + 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 = protmem->sec_world_id; + struct ffa_send_direct_data data = { + .data0 = OPTEE_FFA_RELEASE_PROTMEM, + .data1 = (u32)global_handle, + .data2 = (u32)(global_handle >> 32) + }; + int rc; + + optee_shm_rem_ffa_handle(optee, global_handle); + protmem->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 +951,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_protmem = optee_ffa_lend_protmem, + .reclaim_protmem = optee_ffa_reclaim_protmem, }; static void optee_ffa_remove(struct ffa_device *ffa_dev) @@ -941,7 +1061,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 +1108,24 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) rc); } + if (IS_ENABLED(CONFIG_TEE_CMA) && + (sec_caps & OPTEE_FFA_SEC_CAP_PROTMEM)) { + enum tee_dma_heap_id id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; + struct tee_protmem_pool *pool; + + pool = optee_protmem_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 +1139,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 +1158,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..7c53433f6562 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_protmem: lends physically contiguous memory as restricted + * memory, inaccessible by the kernel + * @reclaim_protmem: reclaims restricted memory previously lent with + * @lend_protmem() 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_protmem)(struct optee *optee, struct tee_shm *protmem, + u16 *end_points, unsigned int ep_count, + u32 use_case); + int (*reclaim_protmem)(struct optee *optee, struct tee_shm *protmem); }; /** @@ -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_protmem_pool *optee_protmem_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/protmem.c b/drivers/tee/optee/protmem.c new file mode 100644 index 000000000000..a9a2d20bff30 --- /dev/null +++ b/drivers/tee/optee/protmem.c @@ -0,0 +1,330 @@ +// 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_protmem_cma_pool { + struct tee_protmem_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 *protmem; + /* Protects when initializing and tearing down this struct */ + struct mutex mutex; +}; + +static struct optee_protmem_cma_pool * +to_protmem_cma_pool(struct tee_protmem_pool *pool) +{ + return container_of(pool, struct optee_protmem_cma_pool, pool); +} + +static int init_cma_protmem(struct optee_protmem_cma_pool *rp) +{ + int rc; + + rp->protmem = tee_shm_alloc_cma_phys_mem(rp->optee->ctx, rp->page_count, + rp->align); + if (IS_ERR(rp->protmem)) { + rc = PTR_ERR(rp->protmem); + goto err_null_protmem; + } + + /* + * TODO unmap the memory range since the physical memory will + * become inaccesible after the lend_protmem() call. + */ + rc = rp->optee->ops->lend_protmem(rp->optee, rp->protmem, + rp->end_points, + rp->end_point_count, rp->use_case); + if (rc) + goto err_put_shm; + rp->protmem->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->protmem->paddr, + rp->protmem->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_protmem(rp->optee, rp->protmem); +err_put_shm: + tee_shm_put(rp->protmem); +err_null_protmem: + rp->protmem = NULL; + return rc; +} + +static int get_cma_protmem(struct optee_protmem_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_protmem(rp); + } + mutex_unlock(&rp->mutex); + } + + return rc; +} + +static void release_cma_protmem(struct optee_protmem_cma_pool *rp) +{ + gen_pool_destroy(rp->gen_pool); + rp->gen_pool = NULL; + + rp->optee->ops->reclaim_protmem(rp->optee, rp->protmem); + rp->protmem->flags &= ~TEE_SHM_DYNAMIC; + + WARN(refcount_read(&rp->protmem->refcount) != 1, "Unexpected refcount"); + tee_shm_put(rp->protmem); + rp->protmem = NULL; +} + +static void put_cma_protmem(struct optee_protmem_cma_pool *rp) +{ + if (refcount_dec_and_test(&rp->refcount)) { + mutex_lock(&rp->mutex); + if (rp->gen_pool) + release_cma_protmem(rp); + mutex_unlock(&rp->mutex); + } +} + +static int protmem_pool_op_cma_alloc(struct tee_protmem_pool *pool, + struct sg_table *sgt, size_t size, + size_t *offs) +{ + struct optee_protmem_cma_pool *rp = to_protmem_cma_pool(pool); + size_t sz = ALIGN(size, PAGE_SIZE); + phys_addr_t pa; + int rc; + + rc = get_cma_protmem(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->protmem->paddr; + + return 0; +err_free: + gen_pool_free(rp->gen_pool, pa, size); +err_put: + put_cma_protmem(rp); + + return rc; +} + +static void protmem_pool_op_cma_free(struct tee_protmem_pool *pool, + struct sg_table *sgt) +{ + struct optee_protmem_cma_pool *rp = to_protmem_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_protmem(rp); +} + +static int protmem_pool_op_cma_update_shm(struct tee_protmem_pool *pool, + struct sg_table *sgt, size_t offs, + struct tee_shm *shm, + struct tee_shm **parent_shm) +{ + struct optee_protmem_cma_pool *rp = to_protmem_cma_pool(pool); + + *parent_shm = rp->protmem; + + return 0; +} + +static void pool_op_cma_destroy_pool(struct tee_protmem_pool *pool) +{ + struct optee_protmem_cma_pool *rp = to_protmem_cma_pool(pool); + + mutex_destroy(&rp->mutex); + kfree(rp); +} + +static struct tee_protmem_pool_ops protmem_pool_ops_cma = { + .alloc = protmem_pool_op_cma_alloc, + .free = protmem_pool_op_cma_free, + .update_shm = protmem_pool_op_cma_update_shm, + .destroy_pool = pool_op_cma_destroy_pool, +}; + +static int get_protmem_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_PROTMEM_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_protmem_pool *optee_protmem_alloc_cma_pool(struct optee *optee, + enum tee_dma_heap_id id) +{ + struct optee_protmem_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_protmem_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_protmem_config(optee, use_case, &min_size, &rp->align, + rp->end_points, &rp->end_point_count); + if (rc) + goto err_kfree_eps; + } + + rp->pool.ops = &protmem_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 Fri Apr 4 14:31:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 14038588 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 2FA5DC36010 for ; Fri, 4 Apr 2025 14:54:00 +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=vPfYhkbEaDQyvItBPqD6f0Sef9tTAM/sN3gZBFbfI4Q=; b=RlyLnmtzxw1FrVF9Ss4wEgY/eh MUYRUzHKTBjg7tHxLBX+KIwCdLhtPWb3xEpxt+Mo+x/4ZobDupgic53ODMWZ1Mh8EHaXNCFvvX7zv eJSCRClCi5CI/A/0XGAYPb2aPQQLM+a+cRzzU+s3KZqafH4ZqfP+M+ELHqs0Yr28IzeF/tN4ZbzZy uXOEPyarhK8B6Rzs0rlHowHLb/psW/FXzpKRfzH8KE7QQoA14SrTIWksuEDCC09dAatzsw453gGBH Nx1bBxATiFoMhdm7hWQxVeslC2fF5RURRlkXNywr1+i7UFIxCsI/ivXKcKZ9cNIREZ4ebuAu98Hij GUaV/DBA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0iQZ-0000000C3Wp-44BF; Fri, 04 Apr 2025 14:53:51 +0000 Received: from mail-ed1-x52f.google.com ([2a00:1450:4864:20::52f]) by bombadil.infradead.org with esmtps (Exim 4.98.1 #2 (Red Hat Linux)) id 1u0i6B-0000000BzQa-0gCY for linux-arm-kernel@lists.infradead.org; Fri, 04 Apr 2025 14:32:48 +0000 Received: by mail-ed1-x52f.google.com with SMTP id 4fb4d7f45d1cf-5e6c18e2c7dso4077324a12.3 for ; Fri, 04 Apr 2025 07:32:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1743777166; x=1744381966; 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=vPfYhkbEaDQyvItBPqD6f0Sef9tTAM/sN3gZBFbfI4Q=; b=LXZ+wM1MS4EUjFZeBXcGtEfYdY4BnCtFzClGHjT7a/VLVLi9q7LaE1sCf2C6H0r1QA jPU25tsXv9wUPFYotFnsLGPPOhb3Llg6PSPeq/wAv1ZuD+VIZ6xYYKRqzGc7SpJebeIx YYcNRdOy+A5Sx7x51/o+KpOmxCCs/3sCONhO81bQDa+s6Z0EbWlaH/dg1s6EJApY2WXZ /7uBp8aS1sa3heLvEtN4Nm6E1uu98BUU3LY/zoJjDWDNqVS7NJGY5KS3gSjTChYwVkjc 69OBxCTxw/M6fzP3tcRow+RYyy22zUTfzFdFNXGQs/a9wzj2V5s3Gf0cgJ9iUdrSISR4 GfdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743777166; x=1744381966; 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=vPfYhkbEaDQyvItBPqD6f0Sef9tTAM/sN3gZBFbfI4Q=; b=iHr3QfCL6C62swDTLf1ha06TtDDhodhyAKbYn01Vh33DF6jiyEGtl/aodPdcRq17As IasOSo+QaCzuVy/WYRQXc1lnCRe9xkLUy6CYxI04GhOGs0/wA//PTuvKAcuXOXIvfBvx biAqYBezQ84ld9PGgys9BXBmMtK7Ty2prewoev8vOvaZKVGuodyjTymDazIONziIePTL Lt8p/b5faPJ0cuUcE7wrEF/dMKiMtFc368A92G2LIr6I4nIUaNO8bQFiU6xVudejsKpc rSo0FY4xm008072JjFzK2D6YEgsNPE4tPl1xqdu+2Jn1GCt0Sd+2OHp19rfVUVYIEJae Ra9g== X-Forwarded-Encrypted: i=1; AJvYcCUbDPQtJU1Hh881bFus4UEUlj96XOXQIufCGVjucUGR6PilpBj7AugNRMYJXVtcsSJuiCLufLLTAf25LFIanF35@lists.infradead.org X-Gm-Message-State: AOJu0YwXsA5YgYujXD/sHfgnucTY5D3XJ88mS66exsHm9UrpMKTYATTY tAlD3v0d2E+MHzCmkOwoXLYZIlObFzhacXf3uCi4N4Nw1J/iqDrMbBMOOBxR6dE= X-Gm-Gg: ASbGnctizuVwvuU7Iq9btSZNqdYzu6ghv62NHOZAAHqOxnkNKcN59KiPlcz7GN6FAI8 esAC7/jHheCt1PP2C+wzhOBf/R7QY6SsxPHzgQFcZKmogX2zEniGL/9yTkriSp4Dgy82tyeaQTU vBXhQ8eMJLdAlF/4xTUEMcLX5ruqhzM6D5IIm0Ko+OlbIaQONywD1vpQ/NvQiqipZyitT676ixc SVs4jfObW2VT0wbPaiu5/tKIRmceMDhDgsRCdMQel94VTOkBzgwvUazwW7946FV7f+5S4njngHz m9uqruRn0wi8Zr6E2smQMIKtWQ5ta0YR+pBWZcXowgEKIZfVDzDd6yzjdfACNaMundE2XfUkTmx lVy8JIT0OA+5x0vCarMxr4g== X-Google-Smtp-Source: AGHT+IExyXHbOf2taNxw2yz+3CcX0NYoBCdJtwB6sr0Vv5nuFXnktNWKFMtHaLzI32Tb9SdvBjUavw== X-Received: by 2002:a05:6402:380c:b0:5f0:8551:9790 with SMTP id 4fb4d7f45d1cf-5f0b3bcd2c0mr2481680a12.16.1743777165747; Fri, 04 Apr 2025 07:32:45 -0700 (PDT) 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-5f087f0a0f3sm2567450a12.43.2025.04.04.07.32.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Apr 2025 07:32:45 -0700 (PDT) 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 v7 11/11] optee: smc abi: dynamic protected memory allocation Date: Fri, 4 Apr 2025 16:31:34 +0200 Message-ID: <20250404143215.2281034-12-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250404143215.2281034-1-jens.wiklander@linaro.org> References: <20250404143215.2281034-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-20250404_073247_216799_72EA17F4 X-CRM114-Status: GOOD ( 16.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 Add support in the OP-TEE backend driver for dynamic protected memory allocation using the SMC ABI. Signed-off-by: Jens Wiklander --- drivers/tee/optee/smc_abi.c | 102 ++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index c10b38b23586..dd9887826590 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1001,6 +1001,70 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx, return rc; } +static int optee_smc_lend_protmem(struct optee *optee, struct tee_shm *protmem, + 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_PROTMEM; + 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 = protmem->paddr; + msg_arg->params[1].u.tmem.size = protmem->size; + msg_arg->params[1].u.tmem.shm_ref = (u_long)protmem; + + 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; + } + protmem->sec_world_id = (u_long)protmem; + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + +static int optee_smc_reclaim_protmem(struct optee *optee, + struct tee_shm *protmem) +{ + 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_PROTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; + msg_arg->params[0].u.rmem.shm_ref = (u_long)protmem; + + 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 +1316,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_protmem = optee_smc_lend_protmem, + .reclaim_protmem = optee_smc_reclaim_protmem, }; static int enable_async_notif(optee_invoke_fn *invoke_fn) @@ -1620,13 +1686,16 @@ static inline int optee_load_fw(struct platform_device *pdev, } #endif -static int optee_rstmem_pool_init(struct optee *optee) +static int optee_protmem_pool_init(struct optee *optee) { + bool protm = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM; + bool dyn_protm = optee->smc.sec_caps & + OPTEE_SMC_SEC_CAP_DYNAMIC_PROTMEM; enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; - struct tee_protmem_pool *pool; - int rc; + struct tee_protmem_pool *pool = ERR_PTR(-EINVAL); + int rc = -EINVAL; - if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM) { + if (protm) { union { struct arm_smccc_res smccc; struct optee_smc_get_protmem_config_result result; @@ -1634,25 +1703,24 @@ static int optee_rstmem_pool_init(struct optee *optee) optee->smc.invoke_fn(OPTEE_SMC_GET_PROTMEM_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_protmem_static_pool_alloc(res.result.start, + res.result.size); + } - pool = tee_protmem_static_pool_alloc(res.result.start, - res.result.size); - if (IS_ERR(pool)) - return PTR_ERR(pool); + if (dyn_protm && IS_ERR(pool)) + pool = optee_protmem_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 && (protm || dyn_protm)) + pr_info("Protected memory service not available\n"); + return 0; -err: - pool->ops->destroy_pool(pool); - return rc; } static int optee_probe(struct platform_device *pdev) @@ -1823,7 +1891,7 @@ static int optee_probe(struct platform_device *pdev) pr_info("Asynchronous notifications enabled\n"); } - rc = optee_rstmem_pool_init(optee); + rc = optee_protmem_pool_init(optee); if (rc) goto err_notif_uninit;