Message ID | 20221121140009.2353512-20-quic_eberman@quicinc.com |
---|---|
State | New |
Headers | show |
Series | [v7,01/20] docs: gunyah: Introduce Gunyah Hypervisor | expand |
Hi Elliot, I love your patch! Yet something to improve: [auto build test ERROR on 094226ad94f471a9f19e8f8e7140a09c2625abaa] url: https://github.com/intel-lab-lkp/linux/commits/Elliot-Berman/Drivers-for-gunyah-hypervisor/20221121-220942 base: 094226ad94f471a9f19e8f8e7140a09c2625abaa patch link: https://lore.kernel.org/r/20221121140009.2353512-20-quic_eberman%40quicinc.com patch subject: [PATCH v7 19/20] firmware: qcom_scm: Register Gunyah platform ops config: m68k-randconfig-m041-20221201 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/e7c817504febf0e6f3171fe49429d117c4ec7bec git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Elliot-Berman/Drivers-for-gunyah-hypervisor/20221121-220942 git checkout e7c817504febf0e6f3171fe49429d117c4ec7bec # 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 SHELL=/bin/bash drivers/virt/gunyah/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/virt/gunyah/gunyah_platform_hooks.c:39:5: error: redefinition of 'gh_rm_register_platform_ops' 39 | int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/virt/gunyah/gunyah_platform_hooks.c:8: include/linux/gunyah_rsc_mgr.h:132:19: note: previous definition of 'gh_rm_register_platform_ops' with type 'int(struct gunyah_rm_platform_ops *)' 132 | static inline int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ >> drivers/virt/gunyah/gunyah_platform_hooks.c:53:6: error: redefinition of 'gh_rm_unregister_platform_ops' 53 | void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/gunyah_rsc_mgr.h:134:20: note: previous definition of 'gh_rm_unregister_platform_ops' with type 'void(struct gunyah_rm_platform_ops *)' 134 | static inline void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops) { } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/gh_rm_register_platform_ops +39 drivers/virt/gunyah/gunyah_platform_hooks.c 732a90ac408a53 Elliot Berman 2022-11-21 38 732a90ac408a53 Elliot Berman 2022-11-21 @39 int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops) 732a90ac408a53 Elliot Berman 2022-11-21 40 { 732a90ac408a53 Elliot Berman 2022-11-21 41 int ret = 0; 732a90ac408a53 Elliot Berman 2022-11-21 42 732a90ac408a53 Elliot Berman 2022-11-21 43 down_write(&rm_platform_ops_lock); 732a90ac408a53 Elliot Berman 2022-11-21 44 if (!rm_platform_ops) 732a90ac408a53 Elliot Berman 2022-11-21 45 rm_platform_ops = platform_ops; 732a90ac408a53 Elliot Berman 2022-11-21 46 else 732a90ac408a53 Elliot Berman 2022-11-21 47 ret = -EEXIST; 732a90ac408a53 Elliot Berman 2022-11-21 48 up_write(&rm_platform_ops_lock); 732a90ac408a53 Elliot Berman 2022-11-21 49 return ret; 732a90ac408a53 Elliot Berman 2022-11-21 50 } 732a90ac408a53 Elliot Berman 2022-11-21 51 EXPORT_SYMBOL_GPL(gh_rm_register_platform_ops); 732a90ac408a53 Elliot Berman 2022-11-21 52 732a90ac408a53 Elliot Berman 2022-11-21 @53 void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops) 732a90ac408a53 Elliot Berman 2022-11-21 54 { 732a90ac408a53 Elliot Berman 2022-11-21 55 down_write(&rm_platform_ops_lock); 732a90ac408a53 Elliot Berman 2022-11-21 56 if (rm_platform_ops == platform_ops) 732a90ac408a53 Elliot Berman 2022-11-21 57 rm_platform_ops = NULL; 732a90ac408a53 Elliot Berman 2022-11-21 58 up_write(&rm_platform_ops_lock); 732a90ac408a53 Elliot Berman 2022-11-21 59 } 732a90ac408a53 Elliot Berman 2022-11-21 60 EXPORT_SYMBOL_GPL(gh_rm_unregister_platform_ops); 732a90ac408a53 Elliot Berman 2022-11-21 61
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 92763dce6477..2dde5cd9701b 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -17,6 +17,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" @@ -27,6 +28,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; @@ -1292,6 +1296,94 @@ 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_rpc *rm, struct gh_rm_mem_parcel *mem_parcel) +{ + struct qcom_scm_vmperm *new_perms; + u64 src, src_cpy; + int ret, i, n; + + 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++) { + if (mem_parcel->acl_entries[n].vmid <= QCOM_SCM_MAX_MANAGED_VMID) + new_perms[n].vmid = mem_parcel->acl_entries[n].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(mem_parcel->mem_entries[i].ipa_base, + 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++) { + if (mem_parcel->acl_entries[n].vmid <= QCOM_SCM_MAX_MANAGED_VMID) + src |= (1ull << mem_parcel->acl_entries[n].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; + ret = qcom_scm_assign_mem(mem_parcel->mem_entries[i].ipa_base, + mem_parcel->mem_entries[i].size, + &src_cpy, new_perms, 1); + WARN_ON_ONCE(ret); + } + break; + } + } + + kfree(new_perms); + return ret; +} + +static int qcom_scm_gh_rm_post_mem_reclaim(struct gh_rm_rpc *rm, + struct gh_rm_mem_parcel *mem_parcel) +{ + struct qcom_scm_vmperm new_perms; + u64 src = 0; + int ret, i, n; + + 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++) { + if (mem_parcel->acl_entries[n].vmid <= QCOM_SCM_MAX_MANAGED_VMID) + src |= (1ull << mem_parcel->acl_entries[n].vmid); + else + src |= (1ull << QCOM_SCM_RM_MANAGED_VMID); + } + + for (i = 0; i < mem_parcel->n_mem_entries; i++) { + ret = qcom_scm_assign_mem(mem_parcel->mem_entries[i].ipa_base, + mem_parcel->mem_entries[i].size, + &src, &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; @@ -1414,6 +1506,9 @@ static int qcom_scm_probe(struct platform_device *pdev) if (download_mode) qcom_scm_set_download_mode(true); + if (gh_rm_register_platform_ops(&qcom_scm_gh_rm_platform_ops)) + dev_warn(__scm->dev, "Gunyah RM platform ops were already registered\n"); + return 0; }