diff --git a/arch/arm64/configs/vendor/pineapple_GKI.config b/arch/arm64/configs/vendor/pineapple_GKI.config index 1324fbbb4ad6..f0e1a7140b23 100644 --- a/arch/arm64/configs/vendor/pineapple_GKI.config +++ b/arch/arm64/configs/vendor/pineapple_GKI.config @@ -145,6 +145,7 @@ CONFIG_QCOM_QFPROM=m CONFIG_QCOM_QMI_HELPERS=m CONFIG_QCOM_RAMDUMP=m CONFIG_QCOM_RPMH=m +CONFIG_QCOM_RPROC_BOTH_DUMPS=y CONFIG_QCOM_RPROC_COMMON=m CONFIG_QCOM_RUN_QUEUE_STATS=m CONFIG_QCOM_SCM=m diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 8ffd425c67df..b7f26a6ac870 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -344,6 +344,14 @@ config RPROC_SSR_NOTIF_TIMEOUT the start and end of SSR notifications through the subsystem notifier, before a warning is emitted. +config QCOM_RPROC_BOTH_DUMPS + bool "Collect both minidump and fulldump for subsystem crash" + help + Say y here to allow dumping both fulldump and minidump for the + case where subsystem minidump is enabled by policy and the feature + is enabled for a client. The case where minidump is not enabled, + and fulldump is collected by default remains unaffected. + config ST_REMOTEPROC tristate "ST remoteproc support" depends on ARCH_STI diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 2bb72c8337d0..120de038fb4f 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -102,6 +102,8 @@ static struct kobject *sysfs_kobject; bool qcom_device_shutdown_in_progress; EXPORT_SYMBOL(qcom_device_shutdown_in_progress); +static bool qcom_collect_both_coredumps; + static LIST_HEAD(qcom_ssr_subsystem_list); static DEFINE_MUTEX(qcom_ssr_subsys_lock); @@ -124,6 +126,23 @@ static ssize_t qcom_rproc_shutdown_request_store(struct kobject *kobj, struct ko static struct kobj_attribute shutdown_requested_attr = __ATTR(shutdown_in_progress, 0220, NULL, qcom_rproc_shutdown_request_store); +static ssize_t qcom_collect_both_coredumps_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + bool val; + int ret; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; + + qcom_collect_both_coredumps = val; + pr_info("qcom rproc: Collect both coredumps: %s\n", val ? "true" : "false"); + return count; +} +static struct kobj_attribute both_coredumps_attr = __ATTR(collect_both_coredumps, 0644, NULL, + qcom_collect_both_coredumps_store); + static void qcom_minidump_cleanup(struct rproc *rproc) { struct rproc_dump_segment *entry, *tmp; @@ -280,8 +299,8 @@ static void qcom_rproc_minidump(struct rproc *rproc, struct device *md_dev) dev_coredumpv(md_dev, data, data_size, GFP_KERNEL); } -void qcom_minidump(struct rproc *rproc, struct device *md_dev, - unsigned int minidump_id, rproc_dumpfn_t dumpfn) +void qcom_minidump(struct rproc *rproc, struct device *md_dev, unsigned int minidump_id, + rproc_dumpfn_t dumpfn, bool both_dumps) { int ret; struct minidump_subsystem *subsystem; @@ -309,6 +328,11 @@ void qcom_minidump(struct rproc *rproc, struct device *md_dev, return rproc_coredump(rproc); } + + if (both_dumps && IS_ENABLED(CONFIG_QCOM_RPROC_BOTH_DUMPS) && + qcom_collect_both_coredumps) + rproc_coredump(rproc); + if (le32_to_cpu(subsystem->encryption_status) != MD_SS_ENCR_DONE) { dev_err(&rproc->dev, "Minidump not ready, skipping\n"); return; @@ -813,10 +837,16 @@ static int __init qcom_common_init(void) goto remove_kobject; } + ret = sysfs_create_file(sysfs_kobject, &both_coredumps_attr.attr); + if (ret) { + pr_err("qcom rproc: failed to create both_coredumps sysfs file\n"); + goto remove_shutdown_sysfs; + } + ret = register_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL); if (ret) { pr_err("qcom rproc: failed to register trace hooks\n"); - goto remove_sysfs; + goto remove_coredump_sysfs; } ret = register_trace_android_vh_rproc_recovery_set(rproc_recovery_notifier, NULL); @@ -829,7 +859,9 @@ static int __init qcom_common_init(void) unregister_rproc_recovery_vh: unregister_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL); -remove_sysfs: +remove_coredump_sysfs: + sysfs_remove_file(sysfs_kobject, &both_coredumps_attr.attr); +remove_shutdown_sysfs: sysfs_remove_file(sysfs_kobject, &shutdown_requested_attr.attr); remove_kobject: kobject_put(sysfs_kobject); @@ -841,6 +873,7 @@ module_init(qcom_common_init); static void __exit qcom_common_exit(void) { unregister_trace_android_vh_rproc_recovery_set(rproc_recovery_notifier, NULL); + sysfs_remove_file(sysfs_kobject, &both_coredumps_attr.attr); sysfs_remove_file(sysfs_kobject, &shutdown_requested_attr.attr); kobject_put(sysfs_kobject); unregister_trace_android_vh_rproc_recovery(qcom_check_ssr_status, NULL); diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index 13368967c3ab..2c760c984671 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -62,7 +62,7 @@ typedef void (*rproc_dumpfn_t)(struct rproc *rproc, struct rproc_dump_segment *s void *dest, size_t offset, size_t size); void qcom_minidump(struct rproc *rproc, struct device *md_dev, - unsigned int minidump_id, rproc_dumpfn_t dumpfn); + unsigned int minidump_id, rproc_dumpfn_t dumpfn, bool both_dumps); void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink, const char *ssr_name); diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 15f9a05b8d3a..d8c5d247b0ca 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -61,6 +61,7 @@ struct adsp_data { int dtb_pas_id; bool free_after_auth_reset; unsigned int minidump_id; + bool both_dumps; bool uses_elf64; bool has_aggre2_clk; bool auto_boot; @@ -106,6 +107,7 @@ struct qcom_adsp { struct qcom_mdt_metadata *mdata; struct qcom_mdt_metadata dtb_mdata; unsigned int minidump_id; + bool both_dumps; bool retry_shutdown; struct icc_path *bus_client; int crash_reason_smem; @@ -170,7 +172,8 @@ static void adsp_minidump(struct rproc *rproc) if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) goto exit; - qcom_minidump(rproc, adsp->minidump_dev, adsp->minidump_id, adsp_segment_dump); + qcom_minidump(rproc, adsp->minidump_dev, adsp->minidump_id, adsp_segment_dump, + adsp->both_dumps); exit: trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_minidump", "exit"); @@ -1056,6 +1059,7 @@ static int adsp_probe(struct platform_device *pdev) adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->qmp_name = desc->qmp_name; adsp->dma_phys_below_32b = desc->dma_phys_below_32b; + adsp->both_dumps = desc->both_dumps; if (desc->free_after_auth_reset) { adsp->mdata = devm_kzalloc(adsp->dev, sizeof(struct qcom_mdt_metadata), GFP_KERNEL); @@ -1538,6 +1542,7 @@ static const struct adsp_data pineapple_mpss_resource = { .qmp_name = "modem", .ssctl_id = 0x12, .dma_phys_below_32b = true, + .both_dumps = true, }; static const struct adsp_data cinder_mpss_resource = {