Message ID | 20230214212457.3319814-1-quic_eberman@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp3207890wrn; Tue, 14 Feb 2023 13:27:31 -0800 (PST) X-Google-Smtp-Source: AK7set+2FAZqFUZolXoLDNH4afVq+ImyjJYpy+QtIRA32wyiFM/SxJcp8WgNwD5Tyg58B+m4jDNj X-Received: by 2002:a17:903:10b:b0:199:2f45:1a38 with SMTP id y11-20020a170903010b00b001992f451a38mr34789plc.52.1676410051098; Tue, 14 Feb 2023 13:27:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676410051; cv=none; d=google.com; s=arc-20160816; b=eFqRBA7V9SLJUbZByDhwUsLzeIZAo2dJbJaCh99WdpLeWJojaGBD9l4gnaVUDANiPQ ltZaKlDVJDqGFzKdElmcPbC42NPGdap93nhVlzUY9sAPaBidiZBusiM5P7X1GXry6TRQ NJ+DHX4tF4L4+4fLuZqxGOUUHScwCYYPvYM+/neDmqTSSQYAnwkd1RZ7LXJXOFQJtVj/ tUdeFTjBWfuN2VlF4Rgo4xchtqJnxFuxqXOcmQiCmAKLVWr+8YfN19VvzC5pP07mZgyV ijP4cKpSkCODM8UcmuDPJWT/5Sx9DIN416tlc3s86eP1zzRS1UGXc0xWhsvT3TPUoCZX 3mXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=XPWY8+sNHOreIEvICe2zHJsGaLipAQ2qPjvVkiKc32o=; b=abOsNVtupRU6vZT5Rag4vjeaIo5keL6bOpgnCQuJ2O9OdwTGmPhHuKlxS+LkOcCTYc XrlD63pCI1CUQvexy3YIRx4DKfgrduuSWsV+8uyMVDAJTvZeEbhYC9xPxhSlMSoHA/90 f4/f7pfCjV6xCEisMr1ItRgb3p9YKoV5wCIw9gkmfqF6Fs/0RIgOgjfUwx6t2pWkylsB bWPs38cim8z/YlbjjlYESif8jLgBhbbU1aEm18f3KCFpzcxLSwQDh9kGKVYJosFKrGrX 01mOD1BSFYB71Vz0L+c8O6W8BS9Adc3JhDP9VV3yE/vIjK1xAHLyJ0UBCvoppdq5tp+f dhlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=nUPVJaM9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f2-20020a170902ce8200b0019ab2f00b90si4390503plg.171.2023.02.14.13.27.17; Tue, 14 Feb 2023 13:27:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=nUPVJaM9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231276AbjBNV0k (ORCPT <rfc822;tebrre53rla2o@gmail.com> + 99 others); Tue, 14 Feb 2023 16:26:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbjBNV0i (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 14 Feb 2023 16:26:38 -0500 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B4E87ABD; Tue, 14 Feb 2023 13:26:01 -0800 (PST) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 31EBLApr014334; Tue, 14 Feb 2023 21:25:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=XPWY8+sNHOreIEvICe2zHJsGaLipAQ2qPjvVkiKc32o=; b=nUPVJaM9ibQXvbDBWhdw4AmUYjki3QNsGa3ySGXDNsGjOej9+Cql0JIvrHLZHlYfeuzX 2v2c8tgHwd7egQfi73zRkzXyTLbPt9JKkXB7EPWLascMK+bORHQ8UXKGL6faL4sPs/Z8 4Vf3Syn+jZVtys7whBMh798vPDlL7crOsqFmwbIf9lIsXwmF3HzTTsMX7dh3BnqMVqtX /z419NhMhL+3X61mzUQZIGFUEC5D5AyCy8RIggMXP/vuT7wwhCXFjOlRyT0byQqFvrxh Pbp1+9YnQSfG/YUiZAb4zr6VVFXsYFNkTmBeCYqVhaTTsM1yuC+HPZumKTqqAK/bLp1D Hg== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3nr6qkhxgs-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 14 Feb 2023 21:25:07 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 31ELP6TW000552 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 14 Feb 2023 21:25:06 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.36; Tue, 14 Feb 2023 13:25:05 -0800 From: Elliot Berman <quic_eberman@quicinc.com> To: Alex Elder <elder@linaro.org>, Srinivas Kandagatla <srinivas.kandagatla@linaro.org>, Andy Gross <agross@kernel.org>, "Bjorn Andersson" <andersson@kernel.org>, Konrad Dybcio <konrad.dybcio@linaro.org> CC: Elliot Berman <quic_eberman@quicinc.com>, Murali Nalajala <quic_mnalajal@quicinc.com>, Trilok Soni <quic_tsoni@quicinc.com>, "Srivatsa Vaddagiri" <quic_svaddagi@quicinc.com>, Carl van Schaik <quic_cvanscha@quicinc.com>, Prakruthi Deepak Heragu <quic_pheragu@quicinc.com>, Dmitry Baryshkov <dmitry.baryshkov@linaro.org>, Arnd Bergmann <arnd@arndb.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Rob Herring <robh+dt@kernel.org>, "Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>, Jonathan Corbet <corbet@lwn.net>, Bagas Sanjaya <bagasdotme@gmail.com>, Catalin Marinas <catalin.marinas@arm.com>, Jassi Brar <jassisinghbrar@gmail.com>, <linux-arm-msm@vger.kernel.org>, <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <linux-doc@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org> Subject: [PATCH v10 16/26] firmware: qcom_scm: Register Gunyah platform ops Date: Tue, 14 Feb 2023 13:24:57 -0800 Message-ID: <20230214212457.3319814-1-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230214211229.3239350-1-quic_eberman@quicinc.com> References: <20230214211229.3239350-1-quic_eberman@quicinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01a.na.qualcomm.com (10.47.209.196) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: rHalghu-Y0iVd-6YK544BfGcEGYTmKzj X-Proofpoint-ORIG-GUID: rHalghu-Y0iVd-6YK544BfGcEGYTmKzj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22 definitions=2023-02-14_15,2023-02-14_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 adultscore=0 clxscore=1015 bulkscore=0 impostorscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 priorityscore=1501 mlxscore=0 phishscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2302140183 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757843346144011507?= X-GMAIL-MSGID: =?utf-8?q?1757843346144011507?= |
Series |
Drivers for Gunyah hypervisor
|
|
Commit Message
Elliot Berman
Feb. 14, 2023, 9:24 p.m. UTC
Qualcomm platforms have a firmware entity which performs access control to physical pages. Dynamically started Gunyah virtual machines use the QCOM_SCM_RM_MANAGED_VMID for access. Linux thus needs to assign access to the memory used by guest VMs. Gunyah doesn't do this operation for us since it is the current VM (typically VMID_HLOS) delegating the access and not Gunyah itself. Use the Gunyah platform ops to achieve this so that only Qualcomm platforms attempt to make the needed SCM calls. Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu@quicinc.com> Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu@quicinc.com> Signed-off-by: Elliot Berman <quic_eberman@quicinc.com> --- drivers/firmware/Kconfig | 2 + drivers/firmware/qcom_scm.c | 100 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+)
Comments
Hi Elliot, Thank you for the patch! Yet something to improve: [auto build test ERROR on 3ebb0ac55efaf1d0fb1b106f852c114e5021f7eb] url: https://github.com/intel-lab-lkp/linux/commits/Elliot-Berman/docs-gunyah-Introduce-Gunyah-Hypervisor/20230215-055721 base: 3ebb0ac55efaf1d0fb1b106f852c114e5021f7eb patch link: https://lore.kernel.org/r/20230214212457.3319814-1-quic_eberman%40quicinc.com patch subject: [PATCH v10 16/26] firmware: qcom_scm: Register Gunyah platform ops config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230216/202302160838.BTq7ertw-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/33f0c4b130c7b249a1524da8076dd12333aa7cde git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Elliot-Berman/docs-gunyah-Introduce-Gunyah-Hypervisor/20230215-055721 git checkout 33f0c4b130c7b249a1524da8076dd12333aa7cde # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Link: https://lore.kernel.org/oe-kbuild-all/202302160838.BTq7ertw-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/firmware/qcom_scm.c: In function 'qcom_scm_gh_rm_pre_mem_share': >> drivers/firmware/qcom_scm.c:1335:49: error: passing argument 3 of 'qcom_scm_assign_mem' from incompatible pointer type [-Werror=incompatible-pointer-types] 1335 | &src_cpy, new_perms, mem_parcel->n_acl_entries); | ^~~~~~~~ | | | u64 * {aka long long unsigned int *} drivers/firmware/qcom_scm.c:912:39: note: expected 'unsigned int *' but argument is of type 'u64 *' {aka 'long long unsigned int *'} 912 | unsigned int *srcvm, | ~~~~~~~~~~~~~~^~~~~ In file included from include/asm-generic/bug.h:7, from arch/m68k/include/asm/bug.h:32, from include/linux/bug.h:5, from include/linux/thread_info.h:13, from include/asm-generic/preempt.h:5, from ./arch/m68k/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78, from arch/m68k/include/asm/irqflags.h:6, from include/linux/irqflags.h:16, from arch/m68k/include/asm/atomic.h:6, from include/linux/atomic.h:7, from include/linux/rcupdate.h:25, from include/linux/rculist.h:11, from include/linux/pid.h:5, from include/linux/sched.h:14, from include/linux/ratelimit.h:6, from include/linux/dev_printk.h:16, from include/linux/device.h:15, from include/linux/platform_device.h:13, from drivers/firmware/qcom_scm.c:5: drivers/firmware/qcom_scm.c:1353:49: error: passing argument 3 of 'qcom_scm_assign_mem' from incompatible pointer type [-Werror=incompatible-pointer-types] 1353 | &src_cpy, new_perms, 1)); | ^~~~~~~~ | | | u64 * {aka long long unsigned int *} include/linux/once_lite.h:28:41: note: in definition of macro 'DO_ONCE_LITE_IF' 28 | bool __ret_do_once = !!(condition); \ | ^~~~~~~~~ drivers/firmware/qcom_scm.c:1350:33: note: in expansion of macro 'WARN_ON_ONCE' 1350 | WARN_ON_ONCE(qcom_scm_assign_mem( | ^~~~~~~~~~~~ drivers/firmware/qcom_scm.c:912:39: note: expected 'unsigned int *' but argument is of type 'u64 *' {aka 'long long unsigned int *'} 912 | unsigned int *srcvm, | ~~~~~~~~~~~~~~^~~~~ drivers/firmware/qcom_scm.c: In function 'qcom_scm_gh_rm_post_mem_reclaim': drivers/firmware/qcom_scm.c:1385:49: error: passing argument 3 of 'qcom_scm_assign_mem' from incompatible pointer type [-Werror=incompatible-pointer-types] 1385 | &src_cpy, &new_perms, 1); | ^~~~~~~~ | | | u64 * {aka long long unsigned int *} drivers/firmware/qcom_scm.c:912:39: note: expected 'unsigned int *' but argument is of type 'u64 *' {aka 'long long unsigned int *'} 912 | unsigned int *srcvm, | ~~~~~~~~~~~~~~^~~~~ cc1: some warnings being treated as errors vim +/qcom_scm_assign_mem +1335 drivers/firmware/qcom_scm.c 1303 1304 static int qcom_scm_gh_rm_pre_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) 1305 { 1306 struct qcom_scm_vmperm *new_perms; 1307 u64 src, src_cpy; 1308 int ret = 0, i, n; 1309 u16 vmid; 1310 1311 new_perms = kcalloc(mem_parcel->n_acl_entries, sizeof(*new_perms), GFP_KERNEL); 1312 if (!new_perms) 1313 return -ENOMEM; 1314 1315 for (n = 0; n < mem_parcel->n_acl_entries; n++) { 1316 vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); 1317 if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) 1318 new_perms[n].vmid = vmid; 1319 else 1320 new_perms[n].vmid = QCOM_SCM_RM_MANAGED_VMID; 1321 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_X) 1322 new_perms[n].perm |= QCOM_SCM_PERM_EXEC; 1323 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_W) 1324 new_perms[n].perm |= QCOM_SCM_PERM_WRITE; 1325 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_R) 1326 new_perms[n].perm |= QCOM_SCM_PERM_READ; 1327 } 1328 1329 src = (1ull << QCOM_SCM_VMID_HLOS); 1330 1331 for (i = 0; i < mem_parcel->n_mem_entries; i++) { 1332 src_cpy = src; 1333 ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), 1334 le64_to_cpu(mem_parcel->mem_entries[i].size), > 1335 &src_cpy, new_perms, mem_parcel->n_acl_entries); 1336 if (ret) { 1337 src = 0; 1338 for (n = 0; n < mem_parcel->n_acl_entries; n++) { 1339 vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); 1340 if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) 1341 src |= (1ull << vmid); 1342 else 1343 src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); 1344 } 1345 1346 new_perms[0].vmid = QCOM_SCM_VMID_HLOS; 1347 1348 for (i--; i >= 0; i--) { 1349 src_cpy = src; 1350 WARN_ON_ONCE(qcom_scm_assign_mem( 1351 le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), 1352 le64_to_cpu(mem_parcel->mem_entries[i].size), 1353 &src_cpy, new_perms, 1)); 1354 } 1355 break; 1356 } 1357 } 1358 1359 kfree(new_perms); 1360 return ret; 1361 } 1362
Hi Elliot, Thank you for the patch! Yet something to improve: [auto build test ERROR on 3ebb0ac55efaf1d0fb1b106f852c114e5021f7eb] url: https://github.com/intel-lab-lkp/linux/commits/Elliot-Berman/docs-gunyah-Introduce-Gunyah-Hypervisor/20230215-055721 base: 3ebb0ac55efaf1d0fb1b106f852c114e5021f7eb patch link: https://lore.kernel.org/r/20230214212457.3319814-1-quic_eberman%40quicinc.com patch subject: [PATCH v10 16/26] firmware: qcom_scm: Register Gunyah platform ops config: hexagon-randconfig-r041-20230212 (https://download.01.org/0day-ci/archive/20230216/202302161942.xItsHIi1-lkp@intel.com/config) compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project db89896bbbd2251fff457699635acbbedeead27f) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/33f0c4b130c7b249a1524da8076dd12333aa7cde git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Elliot-Berman/docs-gunyah-Introduce-Gunyah-Hypervisor/20230215-055721 git checkout 33f0c4b130c7b249a1524da8076dd12333aa7cde # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/firmware/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Link: https://lore.kernel.org/oe-kbuild-all/202302161942.xItsHIi1-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from drivers/firmware/qcom_scm.c:7: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from drivers/firmware/qcom_scm.c:7: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from drivers/firmware/qcom_scm.c:7: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ >> drivers/firmware/qcom_scm.c:1335:7: error: incompatible pointer types passing 'u64 *' (aka 'unsigned long long *') to parameter of type 'unsigned int *' [-Werror,-Wincompatible-pointer-types] &src_cpy, new_perms, mem_parcel->n_acl_entries); ^~~~~~~~ drivers/firmware/qcom_scm.c:912:18: note: passing argument to parameter 'srcvm' here unsigned int *srcvm, ^ drivers/firmware/qcom_scm.c:1353:7: error: incompatible pointer types passing 'u64 *' (aka 'unsigned long long *') to parameter of type 'unsigned int *' [-Werror,-Wincompatible-pointer-types] &src_cpy, new_perms, 1)); ^~~~~~~~ include/asm-generic/bug.h:147:18: note: expanded from macro 'WARN_ON_ONCE' DO_ONCE_LITE_IF(condition, WARN_ON, 1) ^~~~~~~~~ include/linux/once_lite.h:28:27: note: expanded from macro 'DO_ONCE_LITE_IF' bool __ret_do_once = !!(condition); \ ^~~~~~~~~ drivers/firmware/qcom_scm.c:912:18: note: passing argument to parameter 'srcvm' here unsigned int *srcvm, ^ drivers/firmware/qcom_scm.c:1385:7: error: incompatible pointer types passing 'u64 *' (aka 'unsigned long long *') to parameter of type 'unsigned int *' [-Werror,-Wincompatible-pointer-types] &src_cpy, &new_perms, 1); ^~~~~~~~ drivers/firmware/qcom_scm.c:912:18: note: passing argument to parameter 'srcvm' here unsigned int *srcvm, ^ 6 warnings and 3 errors generated. vim +1335 drivers/firmware/qcom_scm.c 1303 1304 static int qcom_scm_gh_rm_pre_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) 1305 { 1306 struct qcom_scm_vmperm *new_perms; 1307 u64 src, src_cpy; 1308 int ret = 0, i, n; 1309 u16 vmid; 1310 1311 new_perms = kcalloc(mem_parcel->n_acl_entries, sizeof(*new_perms), GFP_KERNEL); 1312 if (!new_perms) 1313 return -ENOMEM; 1314 1315 for (n = 0; n < mem_parcel->n_acl_entries; n++) { 1316 vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); 1317 if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) 1318 new_perms[n].vmid = vmid; 1319 else 1320 new_perms[n].vmid = QCOM_SCM_RM_MANAGED_VMID; 1321 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_X) 1322 new_perms[n].perm |= QCOM_SCM_PERM_EXEC; 1323 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_W) 1324 new_perms[n].perm |= QCOM_SCM_PERM_WRITE; 1325 if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_R) 1326 new_perms[n].perm |= QCOM_SCM_PERM_READ; 1327 } 1328 1329 src = (1ull << QCOM_SCM_VMID_HLOS); 1330 1331 for (i = 0; i < mem_parcel->n_mem_entries; i++) { 1332 src_cpy = src; 1333 ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), 1334 le64_to_cpu(mem_parcel->mem_entries[i].size), > 1335 &src_cpy, new_perms, mem_parcel->n_acl_entries); 1336 if (ret) { 1337 src = 0; 1338 for (n = 0; n < mem_parcel->n_acl_entries; n++) { 1339 vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); 1340 if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) 1341 src |= (1ull << vmid); 1342 else 1343 src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); 1344 } 1345 1346 new_perms[0].vmid = QCOM_SCM_VMID_HLOS; 1347 1348 for (i--; i >= 0; i--) { 1349 src_cpy = src; 1350 WARN_ON_ONCE(qcom_scm_assign_mem( 1351 le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), 1352 le64_to_cpu(mem_parcel->mem_entries[i].size), 1353 &src_cpy, new_perms, 1)); 1354 } 1355 break; 1356 } 1357 } 1358 1359 kfree(new_perms); 1360 return ret; 1361 } 1362
On 14/02/2023 21:24, Elliot Berman wrote: > > Qualcomm platforms have a firmware entity which performs access control > to physical pages. Dynamically started Gunyah virtual machines use the > QCOM_SCM_RM_MANAGED_VMID for access. Linux thus needs to assign access > to the memory used by guest VMs. Gunyah doesn't do this operation for us > since it is the current VM (typically VMID_HLOS) delegating the access > and not Gunyah itself. Use the Gunyah platform ops to achieve this so > that only Qualcomm platforms attempt to make the needed SCM calls. > > Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu@quicinc.com> > Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu@quicinc.com> > Signed-off-by: Elliot Berman <quic_eberman@quicinc.com> > --- > drivers/firmware/Kconfig | 2 + > drivers/firmware/qcom_scm.c | 100 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 102 insertions(+) > > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig > index b59e3041fd62..b888068ff6f2 100644 > --- a/drivers/firmware/Kconfig > +++ b/drivers/firmware/Kconfig > @@ -214,6 +214,8 @@ config MTK_ADSP_IPC > > config QCOM_SCM > tristate > + select VIRT_DRIVERS > + select GUNYAH_PLATFORM_HOOKS This is really making all the Qualcomm platforms either with Gunyah and non-Gunyah hypervisors to enable VIRT_DRIVERS and GUNYAH_PLATFORM_HOOKS in there kernel builds, that is not right way to do this. SCM is used as library so lets keep it that way, I have added some comments on platform hooks patch and potential way I see that this can be done without making SCM aware of GUNAYAH internals. --srini > > config QCOM_SCM_DOWNLOAD_MODE_DEFAULT > bool "Qualcomm download mode enabled by default" > diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c > index 468d4d5ab550..875040982b48 100644 > --- a/drivers/firmware/qcom_scm.c > +++ b/drivers/firmware/qcom_scm.c > @@ -20,6 +20,7 @@ > #include <linux/clk.h> > #include <linux/reset-controller.h> > #include <linux/arm-smccc.h> > +#include <linux/gunyah_rsc_mgr.h> > > #include "qcom_scm.h" > > @@ -30,6 +31,9 @@ module_param(download_mode, bool, 0); > #define SCM_HAS_IFACE_CLK BIT(1) > #define SCM_HAS_BUS_CLK BIT(2) > > +#define QCOM_SCM_RM_MANAGED_VMID 0x3A > +#define QCOM_SCM_MAX_MANAGED_VMID 0x3F > + > struct qcom_scm { > struct device *dev; > struct clk *core_clk; > @@ -1297,6 +1301,99 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, > } > EXPORT_SYMBOL(qcom_scm_lmh_dcvsh); > > +static int qcom_scm_gh_rm_pre_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) > +{ > + struct qcom_scm_vmperm *new_perms; > + u64 src, src_cpy; > + int ret = 0, i, n; > + u16 vmid; > + > + new_perms = kcalloc(mem_parcel->n_acl_entries, sizeof(*new_perms), GFP_KERNEL); > + if (!new_perms) > + return -ENOMEM; > + > + for (n = 0; n < mem_parcel->n_acl_entries; n++) { > + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); > + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) > + new_perms[n].vmid = vmid; > + else > + new_perms[n].vmid = QCOM_SCM_RM_MANAGED_VMID; > + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_X) > + new_perms[n].perm |= QCOM_SCM_PERM_EXEC; > + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_W) > + new_perms[n].perm |= QCOM_SCM_PERM_WRITE; > + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_R) > + new_perms[n].perm |= QCOM_SCM_PERM_READ; > + } > + > + src = (1ull << QCOM_SCM_VMID_HLOS); > + > + for (i = 0; i < mem_parcel->n_mem_entries; i++) { > + src_cpy = src; > + ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), > + le64_to_cpu(mem_parcel->mem_entries[i].size), > + &src_cpy, new_perms, mem_parcel->n_acl_entries); > + if (ret) { > + src = 0; > + for (n = 0; n < mem_parcel->n_acl_entries; n++) { > + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); > + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) > + src |= (1ull << vmid); > + else > + src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); > + } > + > + new_perms[0].vmid = QCOM_SCM_VMID_HLOS; > + > + for (i--; i >= 0; i--) { > + src_cpy = src; > + WARN_ON_ONCE(qcom_scm_assign_mem( > + le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), > + le64_to_cpu(mem_parcel->mem_entries[i].size), > + &src_cpy, new_perms, 1)); > + } > + break; > + } > + } > + > + kfree(new_perms); > + return ret; > +} > + > +static int qcom_scm_gh_rm_post_mem_reclaim(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) > +{ > + struct qcom_scm_vmperm new_perms; > + u64 src = 0, src_cpy; > + int ret = 0, i, n; > + u16 vmid; > + > + new_perms.vmid = QCOM_SCM_VMID_HLOS; > + new_perms.perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ; > + > + for (n = 0; n < mem_parcel->n_acl_entries; n++) { > + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); > + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) > + src |= (1ull << vmid); > + else > + src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); > + } > + > + for (i = 0; i < mem_parcel->n_mem_entries; i++) { > + src_cpy = src; > + ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), > + le64_to_cpu(mem_parcel->mem_entries[i].size), > + &src_cpy, &new_perms, 1); > + WARN_ON_ONCE(ret); > + } > + > + return ret; > +} > + > +static struct gunyah_rm_platform_ops qcom_scm_gh_rm_platform_ops = { > + .pre_mem_share = qcom_scm_gh_rm_pre_mem_share, > + .post_mem_reclaim = qcom_scm_gh_rm_post_mem_reclaim, > +}; > + > static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) > { > struct device_node *tcsr; > @@ -1500,6 +1597,9 @@ static int qcom_scm_probe(struct platform_device *pdev) > if (download_mode) > qcom_scm_set_download_mode(true); > > + if (devm_gh_rm_register_platform_ops(&pdev->dev, &qcom_scm_gh_rm_platform_ops)) > + dev_warn(__scm->dev, "Gunyah RM platform ops were already registered\n"); > + > return 0; > } >
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index b59e3041fd62..b888068ff6f2 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -214,6 +214,8 @@ config MTK_ADSP_IPC config QCOM_SCM tristate + select VIRT_DRIVERS + select GUNYAH_PLATFORM_HOOKS config QCOM_SCM_DOWNLOAD_MODE_DEFAULT bool "Qualcomm download mode enabled by default" diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 468d4d5ab550..875040982b48 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -20,6 +20,7 @@ #include <linux/clk.h> #include <linux/reset-controller.h> #include <linux/arm-smccc.h> +#include <linux/gunyah_rsc_mgr.h> #include "qcom_scm.h" @@ -30,6 +31,9 @@ module_param(download_mode, bool, 0); #define SCM_HAS_IFACE_CLK BIT(1) #define SCM_HAS_BUS_CLK BIT(2) +#define QCOM_SCM_RM_MANAGED_VMID 0x3A +#define QCOM_SCM_MAX_MANAGED_VMID 0x3F + struct qcom_scm { struct device *dev; struct clk *core_clk; @@ -1297,6 +1301,99 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, } EXPORT_SYMBOL(qcom_scm_lmh_dcvsh); +static int qcom_scm_gh_rm_pre_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) +{ + struct qcom_scm_vmperm *new_perms; + u64 src, src_cpy; + int ret = 0, i, n; + u16 vmid; + + new_perms = kcalloc(mem_parcel->n_acl_entries, sizeof(*new_perms), GFP_KERNEL); + if (!new_perms) + return -ENOMEM; + + for (n = 0; n < mem_parcel->n_acl_entries; n++) { + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) + new_perms[n].vmid = vmid; + else + new_perms[n].vmid = QCOM_SCM_RM_MANAGED_VMID; + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_X) + new_perms[n].perm |= QCOM_SCM_PERM_EXEC; + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_W) + new_perms[n].perm |= QCOM_SCM_PERM_WRITE; + if (mem_parcel->acl_entries[n].perms & GH_RM_ACL_R) + new_perms[n].perm |= QCOM_SCM_PERM_READ; + } + + src = (1ull << QCOM_SCM_VMID_HLOS); + + for (i = 0; i < mem_parcel->n_mem_entries; i++) { + src_cpy = src; + ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), + le64_to_cpu(mem_parcel->mem_entries[i].size), + &src_cpy, new_perms, mem_parcel->n_acl_entries); + if (ret) { + src = 0; + for (n = 0; n < mem_parcel->n_acl_entries; n++) { + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) + src |= (1ull << vmid); + else + src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); + } + + new_perms[0].vmid = QCOM_SCM_VMID_HLOS; + + for (i--; i >= 0; i--) { + src_cpy = src; + WARN_ON_ONCE(qcom_scm_assign_mem( + le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), + le64_to_cpu(mem_parcel->mem_entries[i].size), + &src_cpy, new_perms, 1)); + } + break; + } + } + + kfree(new_perms); + return ret; +} + +static int qcom_scm_gh_rm_post_mem_reclaim(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel) +{ + struct qcom_scm_vmperm new_perms; + u64 src = 0, src_cpy; + int ret = 0, i, n; + u16 vmid; + + new_perms.vmid = QCOM_SCM_VMID_HLOS; + new_perms.perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ; + + for (n = 0; n < mem_parcel->n_acl_entries; n++) { + vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid); + if (vmid <= QCOM_SCM_MAX_MANAGED_VMID) + src |= (1ull << vmid); + else + src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); + } + + for (i = 0; i < mem_parcel->n_mem_entries; i++) { + src_cpy = src; + ret = qcom_scm_assign_mem(le64_to_cpu(mem_parcel->mem_entries[i].ipa_base), + le64_to_cpu(mem_parcel->mem_entries[i].size), + &src_cpy, &new_perms, 1); + WARN_ON_ONCE(ret); + } + + return ret; +} + +static struct gunyah_rm_platform_ops qcom_scm_gh_rm_platform_ops = { + .pre_mem_share = qcom_scm_gh_rm_pre_mem_share, + .post_mem_reclaim = qcom_scm_gh_rm_post_mem_reclaim, +}; + static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) { struct device_node *tcsr; @@ -1500,6 +1597,9 @@ static int qcom_scm_probe(struct platform_device *pdev) if (download_mode) qcom_scm_set_download_mode(true); + if (devm_gh_rm_register_platform_ops(&pdev->dev, &qcom_scm_gh_rm_platform_ops)) + dev_warn(__scm->dev, "Gunyah RM platform ops were already registered\n"); + return 0; }