From patchwork Thu Nov 19 21:05:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddharth Gupta X-Patchwork-Id: 11918977 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AEEE7C8300B for ; Thu, 19 Nov 2020 21:06:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 58EA7221F1 for ; Thu, 19 Nov 2020 21:06:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="N/N/9quX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726442AbgKSVFz (ORCPT ); Thu, 19 Nov 2020 16:05:55 -0500 Received: from m42-4.mailgun.net ([69.72.42.4]:17863 "EHLO m42-4.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726417AbgKSVFz (ORCPT ); Thu, 19 Nov 2020 16:05:55 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1605819955; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=wip3SqxPDZ8IG7Sc4+GAbXTApb3DFMxp79tDHTBbQ88=; b=N/N/9quXdPcbfHU5scRKp0BUDgihHy+MLgLhxcXvJSKE0AzGBEVOJjGQ1l1p3Li9r0XB/ejm UGuQtsOHCqiE3IYlSzP/6xNb8upgbPvlGtfG70P76/XjcJFdAgHjU3iMvE69aiR9q7UGoyEv BAtWygDw6hcwFPtiIVDa5MI6aR4= X-Mailgun-Sending-Ip: 69.72.42.4 X-Mailgun-Sid: WyI4ZWZiZiIsICJsaW51eC1yZW1vdGVwcm9jQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n06.prod.us-east-1.postgun.com with SMTP id 5fb6de32b9b39088ed0e5e5e (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 19 Nov 2020 21:05:54 GMT Sender: sidgup=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 47133C43467; Thu, 19 Nov 2020 21:05:53 +0000 (UTC) Received: from sidgup-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sidgup) by smtp.codeaurora.org (Postfix) with ESMTPSA id CA1DFC43460; Thu, 19 Nov 2020 21:05:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org CA1DFC43460 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=sidgup@codeaurora.org From: Siddharth Gupta To: agross@kernel.org, bjorn.andersson@linaro.org, ohad@wizery.com, linux-remoteproc@vger.kernel.org Cc: Siddharth Gupta , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tsoni@codeaurora.org, psodagud@codeaurora.org, rishabhb@codeaurora.org, linux-doc@vger.kernel.org Subject: [PATCH v8 1/4] remoteproc: core: Add ops to enable custom coredump functionality Date: Thu, 19 Nov 2020 13:05:32 -0800 Message-Id: <1605819935-10726-2-git-send-email-sidgup@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> References: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org Each remoteproc might have different requirements for coredumps and might want to choose the type of dumps it wants to collect. This change allows remoteproc drivers to specify their own custom dump function to be executed in place of rproc_coredump. If the coredump op is not specified by the remoteproc driver it will be set to rproc_coredump by default. Signed-off-by: Siddharth Gupta Reviewed-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 6 +++++- include/linux/remoteproc.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index dab2c0f..eba7543 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1704,7 +1704,7 @@ int rproc_trigger_recovery(struct rproc *rproc) goto unlock_mutex; /* generate coredump */ - rproc_coredump(rproc); + rproc->ops->coredump(rproc); /* load firmware */ ret = request_firmware(&firmware_p, rproc->firmware, dev); @@ -2126,6 +2126,10 @@ static int rproc_alloc_ops(struct rproc *rproc, const struct rproc_ops *ops) if (!rproc->ops) return -ENOMEM; + /* Default to rproc_coredump if no coredump function is specified */ + if (!rproc->ops->coredump) + rproc->ops->coredump = rproc_coredump; + if (rproc->ops->load) return 0; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 3fa3ba6..a419878 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -375,6 +375,7 @@ enum rsc_handling_status { * @get_boot_addr: get boot address to entry point specified in firmware * @panic: optional callback to react to system panic, core will delay * panic at least the returned number of milliseconds + * @coredump: collect firmware dump after the subsystem is shutdown */ struct rproc_ops { int (*prepare)(struct rproc *rproc); @@ -393,6 +394,7 @@ struct rproc_ops { int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); unsigned long (*panic)(struct rproc *rproc); + void (*coredump)(struct rproc *rproc); }; /** From patchwork Thu Nov 19 21:05:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddharth Gupta X-Patchwork-Id: 11918975 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEFC1C71156 for ; Thu, 19 Nov 2020 21:06:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8D02924686 for ; Thu, 19 Nov 2020 21:06:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="SP9pJclS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725907AbgKSVF7 (ORCPT ); Thu, 19 Nov 2020 16:05:59 -0500 Received: from m42-4.mailgun.net ([69.72.42.4]:51536 "EHLO m42-4.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726460AbgKSVF5 (ORCPT ); Thu, 19 Nov 2020 16:05:57 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1605819956; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=UQQRLEuHUEInm4aNU7lJ8YMbwm1KSTUWSy6Q+hsMiwQ=; b=SP9pJclSIFY63WCHRNYrhTKyhL6LHJH3H+4k/JeLrTdx1ME7kIc5Of54c2d5GXh3CGT0bvSF kn9p/BQBjFBCaQs2y9ZZVNDlKXKcsoO0Zr6eZ6ATVqkfo7sc4B/IBRPJCoD+wTpfQi9WrL+Z R7NX8FrmMd/iM7FydYXwdirhsMs= X-Mailgun-Sending-Ip: 69.72.42.4 X-Mailgun-Sid: WyI4ZWZiZiIsICJsaW51eC1yZW1vdGVwcm9jQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n10.prod.us-east-1.postgun.com with SMTP id 5fb6de337f0cfa6a167a4d23 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 19 Nov 2020 21:05:55 GMT Sender: sidgup=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 72D90C43464; Thu, 19 Nov 2020 21:05:54 +0000 (UTC) Received: from sidgup-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sidgup) by smtp.codeaurora.org (Postfix) with ESMTPSA id A8016C43465; Thu, 19 Nov 2020 21:05:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org A8016C43465 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=sidgup@codeaurora.org From: Siddharth Gupta To: agross@kernel.org, bjorn.andersson@linaro.org, ohad@wizery.com, linux-remoteproc@vger.kernel.org Cc: Siddharth Gupta , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tsoni@codeaurora.org, psodagud@codeaurora.org, rishabhb@codeaurora.org, linux-doc@vger.kernel.org Subject: [PATCH v8 2/4] remoteproc: coredump: Add minidump functionality Date: Thu, 19 Nov 2020 13:05:33 -0800 Message-Id: <1605819935-10726-3-git-send-email-sidgup@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> References: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org This change adds a new kind of core dump mechanism which instead of dumping entire program segments of the firmware, dumps sections of the remoteproc memory which are sufficient to allow debugging the firmware. This function thus uses section headers instead of program headers during creation of the core dump elf. Co-developed-by: Rishabh Bhatnagar Signed-off-by: Rishabh Bhatnagar Signed-off-by: Siddharth Gupta Reviewed-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_coredump.c | 140 ++++++++++++++++++++++++++++ drivers/remoteproc/remoteproc_elf_helpers.h | 26 ++++++ include/linux/remoteproc.h | 1 + 3 files changed, 167 insertions(+) diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c index 34530dc..81ec154 100644 --- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -323,3 +323,143 @@ void rproc_coredump(struct rproc *rproc) */ wait_for_completion(&dump_state.dump_done); } + +/** + * rproc_coredump_using_sections() - perform coredump using section headers + * @rproc: rproc handle + * + * This function will generate an ELF header for the registered sections of + * segments and create a devcoredump device associated with rproc. Based on + * the coredump configuration this function will directly copy the segments + * from device memory to userspace or copy segments from device memory to + * a separate buffer, which can then be read by userspace. + * The first approach avoids using extra vmalloc memory. But it will stall + * recovery flow until dump is read by userspace. + */ +void rproc_coredump_using_sections(struct rproc *rproc) +{ + struct rproc_dump_segment *segment; + void *shdr; + void *ehdr; + size_t data_size; + size_t strtbl_size = 0; + size_t strtbl_index = 1; + size_t offset; + void *data; + u8 class = rproc->elf_class; + int shnum; + struct rproc_coredump_state dump_state; + unsigned int dump_conf = rproc->dump_conf; + char *str_tbl = "STR_TBL"; + + if (list_empty(&rproc->dump_segments) || + dump_conf == RPROC_COREDUMP_DISABLED) + return; + + if (class == ELFCLASSNONE) { + dev_err(&rproc->dev, "Elf class is not set\n"); + return; + } + + /* + * We allocate two extra section headers. The first one is null. + * Second section header is for the string table. Also space is + * allocated for string table. + */ + data_size = elf_size_of_hdr(class) + 2 * elf_size_of_shdr(class); + shnum = 2; + + /* the extra byte is for the null character at index 0 */ + strtbl_size += strlen(str_tbl) + 2; + + list_for_each_entry(segment, &rproc->dump_segments, node) { + data_size += elf_size_of_shdr(class); + strtbl_size += strlen(segment->priv) + 1; + if (dump_conf == RPROC_COREDUMP_ENABLED) + data_size += segment->size; + shnum++; + } + + data_size += strtbl_size; + + data = vmalloc(data_size); + if (!data) + return; + + ehdr = data; + memset(ehdr, 0, elf_size_of_hdr(class)); + /* e_ident field is common for both elf32 and elf64 */ + elf_hdr_init_ident(ehdr, class); + + elf_hdr_set_e_type(class, ehdr, ET_CORE); + elf_hdr_set_e_machine(class, ehdr, rproc->elf_machine); + elf_hdr_set_e_version(class, ehdr, EV_CURRENT); + elf_hdr_set_e_entry(class, ehdr, rproc->bootaddr); + elf_hdr_set_e_shoff(class, ehdr, elf_size_of_hdr(class)); + elf_hdr_set_e_ehsize(class, ehdr, elf_size_of_hdr(class)); + elf_hdr_set_e_shentsize(class, ehdr, elf_size_of_shdr(class)); + elf_hdr_set_e_shnum(class, ehdr, shnum); + elf_hdr_set_e_shstrndx(class, ehdr, 1); + + /* + * The zeroth index of the section header is reserved and is rarely used. + * Set the section header as null (SHN_UNDEF) and move to the next one. + */ + shdr = data + elf_hdr_get_e_shoff(class, ehdr); + memset(shdr, 0, elf_size_of_shdr(class)); + shdr += elf_size_of_shdr(class); + + /* Initialize the string table. */ + offset = elf_hdr_get_e_shoff(class, ehdr) + + elf_size_of_shdr(class) * elf_hdr_get_e_shnum(class, ehdr); + memset(data + offset, 0, strtbl_size); + + /* Fill in the string table section header. */ + memset(shdr, 0, elf_size_of_shdr(class)); + elf_shdr_set_sh_type(class, shdr, SHT_STRTAB); + elf_shdr_set_sh_offset(class, shdr, offset); + elf_shdr_set_sh_size(class, shdr, strtbl_size); + elf_shdr_set_sh_entsize(class, shdr, 0); + elf_shdr_set_sh_flags(class, shdr, 0); + elf_shdr_set_sh_name(class, shdr, elf_strtbl_add(str_tbl, ehdr, class, &strtbl_index)); + offset += elf_shdr_get_sh_size(class, shdr); + shdr += elf_size_of_shdr(class); + + list_for_each_entry(segment, &rproc->dump_segments, node) { + memset(shdr, 0, elf_size_of_shdr(class)); + elf_shdr_set_sh_type(class, shdr, SHT_PROGBITS); + elf_shdr_set_sh_offset(class, shdr, offset); + elf_shdr_set_sh_addr(class, shdr, segment->da); + elf_shdr_set_sh_size(class, shdr, segment->size); + elf_shdr_set_sh_entsize(class, shdr, 0); + elf_shdr_set_sh_flags(class, shdr, SHF_WRITE); + elf_shdr_set_sh_name(class, shdr, + elf_strtbl_add(segment->priv, ehdr, class, &strtbl_index)); + + /* No need to copy segments for inline dumps */ + if (dump_conf == RPROC_COREDUMP_ENABLED) + rproc_copy_segment(rproc, data + offset, segment, 0, + segment->size); + offset += elf_shdr_get_sh_size(class, shdr); + shdr += elf_size_of_shdr(class); + } + + if (dump_conf == RPROC_COREDUMP_ENABLED) { + dev_coredumpv(&rproc->dev, data, data_size, GFP_KERNEL); + return; + } + + /* Initialize the dump state struct to be used by rproc_coredump_read */ + dump_state.rproc = rproc; + dump_state.header = data; + init_completion(&dump_state.dump_done); + + dev_coredumpm(&rproc->dev, NULL, &dump_state, data_size, GFP_KERNEL, + rproc_coredump_read, rproc_coredump_free); + + /* Wait until the dump is read and free is called. Data is freed + * by devcoredump framework automatically after 5 minutes. + */ + wait_for_completion(&dump_state.dump_done); +} +EXPORT_SYMBOL(rproc_coredump_using_sections); diff --git a/drivers/remoteproc/remoteproc_elf_helpers.h b/drivers/remoteproc/remoteproc_elf_helpers.h index 4b6be7b..26404e6 100644 --- a/drivers/remoteproc/remoteproc_elf_helpers.h +++ b/drivers/remoteproc/remoteproc_elf_helpers.h @@ -65,6 +65,7 @@ ELF_GEN_FIELD_GET_SET(hdr, e_type, u16) ELF_GEN_FIELD_GET_SET(hdr, e_version, u32) ELF_GEN_FIELD_GET_SET(hdr, e_ehsize, u32) ELF_GEN_FIELD_GET_SET(hdr, e_phentsize, u16) +ELF_GEN_FIELD_GET_SET(hdr, e_shentsize, u16) ELF_GEN_FIELD_GET_SET(phdr, p_paddr, u64) ELF_GEN_FIELD_GET_SET(phdr, p_vaddr, u64) @@ -75,6 +76,9 @@ ELF_GEN_FIELD_GET_SET(phdr, p_offset, u64) ELF_GEN_FIELD_GET_SET(phdr, p_flags, u32) ELF_GEN_FIELD_GET_SET(phdr, p_align, u64) +ELF_GEN_FIELD_GET_SET(shdr, sh_type, u32) +ELF_GEN_FIELD_GET_SET(shdr, sh_flags, u32) +ELF_GEN_FIELD_GET_SET(shdr, sh_entsize, u16) ELF_GEN_FIELD_GET_SET(shdr, sh_size, u64) ELF_GEN_FIELD_GET_SET(shdr, sh_offset, u64) ELF_GEN_FIELD_GET_SET(shdr, sh_name, u32) @@ -93,4 +97,26 @@ ELF_STRUCT_SIZE(shdr) ELF_STRUCT_SIZE(phdr) ELF_STRUCT_SIZE(hdr) +static inline unsigned int elf_strtbl_add(const char *name, void *ehdr, u8 class, size_t *index) +{ + u16 shstrndx = elf_hdr_get_e_shstrndx(class, ehdr); + void *shdr; + char *strtab; + size_t idx, ret; + + shdr = ehdr + elf_size_of_hdr(class) + shstrndx * elf_size_of_shdr(class); + strtab = ehdr + elf_shdr_get_sh_offset(class, shdr); + idx = index ? *index : 0; + if (!strtab || !name) + return 0; + + ret = idx; + strcpy((strtab + idx), name); + idx += strlen(name) + 1; + if (index) + *index = idx; + + return ret; +} + #endif /* REMOTEPROC_ELF_LOADER_H */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index a419878..cdf2722 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -656,6 +656,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); +void rproc_coredump_using_sections(struct rproc *rproc); int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); int rproc_coredump_add_custom_segment(struct rproc *rproc, dma_addr_t da, size_t size, From patchwork Thu Nov 19 21:05:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddharth Gupta X-Patchwork-Id: 11918973 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C869C388F9 for ; Thu, 19 Nov 2020 21:06:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C7EF1223FD for ; Thu, 19 Nov 2020 21:06:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="IhywlPWo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726460AbgKSVGA (ORCPT ); Thu, 19 Nov 2020 16:06:00 -0500 Received: from z5.mailgun.us ([104.130.96.5]:11016 "EHLO z5.mailgun.us" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726298AbgKSVF4 (ORCPT ); Thu, 19 Nov 2020 16:05:56 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1605819955; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=1mii8b/LdvSzQVn+JaHD7XQ6YMdqBU8iOBSykqZ7Unc=; b=IhywlPWowElZivNlfeeYRSKeIVd07aweubB9vEtj4VQtF6JvP+pE39qsrWL+U4+hQM6SkTr7 AhSEksY0ZjhGA+HDVzRTUw5kdvEk/rfUly8SRIswnl7oCfbKHxLqEc4vCo/4oivXnATVnPuB gATP5+7rCFWV5p+KIBEe6JV3GVA= X-Mailgun-Sending-Ip: 104.130.96.5 X-Mailgun-Sid: WyI4ZWZiZiIsICJsaW51eC1yZW1vdGVwcm9jQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n10.prod.us-west-2.postgun.com with SMTP id 5fb6de3377b63cdb34a67ce6 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 19 Nov 2020 21:05:55 GMT Sender: sidgup=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 68726C433C6; Thu, 19 Nov 2020 21:05:55 +0000 (UTC) Received: from sidgup-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sidgup) by smtp.codeaurora.org (Postfix) with ESMTPSA id 76A13C433C6; Thu, 19 Nov 2020 21:05:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 76A13C433C6 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=sidgup@codeaurora.org From: Siddharth Gupta To: agross@kernel.org, bjorn.andersson@linaro.org, ohad@wizery.com, linux-remoteproc@vger.kernel.org Cc: Siddharth Gupta , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tsoni@codeaurora.org, psodagud@codeaurora.org, rishabhb@codeaurora.org, linux-doc@vger.kernel.org, Gurbir Arora Subject: [PATCH v8 3/4] remoteproc: qcom: Add capability to collect minidumps Date: Thu, 19 Nov 2020 13:05:34 -0800 Message-Id: <1605819935-10726-4-git-send-email-sidgup@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> References: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org This patch adds support for collecting minidump in the event of remoteproc crash. Parse the minidump table based on remoteproc's unique minidump-id, read all memory regions from the remoteproc's minidump table entry and expose the memory to userspace. The remoteproc platform driver can choose to collect a full/mini dump by specifying the coredump op. Co-developed-by: Rishabh Bhatnagar Signed-off-by: Rishabh Bhatnagar Co-developed-by: Gurbir Arora Signed-off-by: Gurbir Arora Signed-off-by: Siddharth Gupta Reviewed-by: Bjorn Andersson --- drivers/remoteproc/qcom_common.c | 147 +++++++++++++++++++++++++++++++++++++ drivers/remoteproc/qcom_common.h | 2 + drivers/remoteproc/qcom_q6v5_pas.c | 27 ++++++- 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 085fd73..c41c3a5 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "remoteproc_internal.h" #include "qcom_common.h" @@ -25,6 +26,61 @@ #define to_smd_subdev(d) container_of(d, struct qcom_rproc_subdev, subdev) #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev) +#define MAX_NUM_OF_SS 10 +#define MAX_REGION_NAME_LENGTH 16 +#define SBL_MINIDUMP_SMEM_ID 602 +#define MD_REGION_VALID ('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0) +#define MD_SS_ENCR_DONE ('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0) +#define MD_SS_ENABLED ('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0) + +/** + * struct minidump_region - Minidump region + * @name : Name of the region to be dumped + * @seq_num: : Use to differentiate regions with same name. + * @valid : This entry to be dumped (if set to 1) + * @address : Physical address of region to be dumped + * @size : Size of the region + */ +struct minidump_region { + char name[MAX_REGION_NAME_LENGTH]; + __le32 seq_num; + __le32 valid; + __le64 address; + __le64 size; +}; + +/** + * struct minidump_subsystem_toc: Subsystem's SMEM Table of content + * @status : Subsystem toc init status + * @enabled : if set to 1, this region would be copied during coredump + * @encryption_status: Encryption status for this subsystem + * @encryption_required : Decides to encrypt the subsystem regions or not + * @region_count : Number of regions added in this subsystem toc + * @regions_baseptr : regions base pointer of the subsystem + */ +struct minidump_subsystem { + __le32 status; + __le32 enabled; + __le32 encryption_status; + __le32 encryption_required; + __le32 region_count; + __le64 regions_baseptr; +}; + +/** + * struct minidump_global_toc: Global Table of Content + * @status : Global Minidump init status + * @md_revision : Minidump revision + * @enabled : Minidump enable status + * @subsystems : Array of subsystems toc + */ +struct minidump_global_toc { + __le32 status; + __le32 md_revision; + __le32 enabled; + struct minidump_subsystem subsystems[MAX_NUM_OF_SS]; +}; + struct qcom_ssr_subsystem { const char *name; struct srcu_notifier_head notifier_list; @@ -34,6 +90,97 @@ struct qcom_ssr_subsystem { static LIST_HEAD(qcom_ssr_subsystem_list); static DEFINE_MUTEX(qcom_ssr_subsys_lock); + +static void qcom_minidump_cleanup(struct rproc *rproc) +{ + struct rproc_dump_segment *entry, *tmp; + + list_for_each_entry_safe(entry, tmp, &rproc->dump_segments, node) { + list_del(&entry->node); + kfree(entry->priv); + kfree(entry); + } +} + +static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsystem *subsystem) +{ + struct minidump_region __iomem *ptr; + struct minidump_region region; + int seg_cnt, i; + dma_addr_t da; + size_t size; + char *name; + + if (WARN_ON(!list_empty(&rproc->dump_segments))) { + dev_err(&rproc->dev, "dump segment list already populated\n"); + return -EUCLEAN; + } + + seg_cnt = le32_to_cpu(subsystem->region_count); + ptr = ioremap((unsigned long)le64_to_cpu(subsystem->regions_baseptr), + seg_cnt * sizeof(struct minidump_region)); + if (!ptr) + return -EFAULT; + + for (i = 0; i < seg_cnt; i++) { + memcpy_fromio(®ion, ptr + i, sizeof(region)); + if (region.valid == MD_REGION_VALID) { + name = kstrdup(region.name, GFP_KERNEL); + if (!name) { + iounmap(ptr); + return -ENOMEM; + } + da = le64_to_cpu(region.address); + size = le32_to_cpu(region.size); + rproc_coredump_add_custom_segment(rproc, da, size, NULL, name); + } + } + + iounmap(ptr); + return 0; +} + +void qcom_minidump(struct rproc *rproc, unsigned int minidump_id) +{ + int ret; + struct minidump_subsystem *subsystem; + struct minidump_global_toc *toc; + + /* Get Global minidump ToC*/ + toc = qcom_smem_get(QCOM_SMEM_HOST_ANY, SBL_MINIDUMP_SMEM_ID, NULL); + + /* check if global table pointer exists and init is set */ + if (IS_ERR(toc) || !toc->status) { + dev_err(&rproc->dev, "Minidump TOC not found in SMEM\n"); + return; + } + + /* Get subsystem table of contents using the minidump id */ + subsystem = &toc->subsystems[minidump_id]; + + /** + * Collect minidump if SS ToC is valid and segment table + * is initialized in memory and encryption status is set. + */ + if (subsystem->regions_baseptr == 0 || + le32_to_cpu(subsystem->status) != 1 || + le32_to_cpu(subsystem->enabled) != MD_SS_ENABLED || + le32_to_cpu(subsystem->encryption_status) != MD_SS_ENCR_DONE) { + dev_err(&rproc->dev, "Minidump not ready, skipping\n"); + return; + } + + ret = qcom_add_minidump_segments(rproc, subsystem); + if (ret) { + dev_err(&rproc->dev, "Failed with error: %d while adding minidump entries\n", ret); + goto clean_minidump; + } + rproc_coredump_using_sections(rproc); +clean_minidump: + qcom_minidump_cleanup(rproc); +} +EXPORT_SYMBOL_GPL(qcom_minidump); + static int glink_subdev_start(struct rproc_subdev *subdev) { struct qcom_rproc_glink *glink = to_glink_subdev(subdev); diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index dfc641c..a359f16 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -33,6 +33,8 @@ struct qcom_rproc_ssr { struct qcom_ssr_subsystem *info; }; +void qcom_minidump(struct rproc *rproc, unsigned int minidump_id); + void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink, const char *ssr_name); void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 3837f23..ca05c2ef 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -33,6 +33,7 @@ struct adsp_data { int crash_reason_smem; const char *firmware_name; int pas_id; + unsigned int minidump_id; bool has_aggre2_clk; bool auto_boot; @@ -63,6 +64,7 @@ struct qcom_adsp { int proxy_pd_count; int pas_id; + unsigned int minidump_id; int crash_reason_smem; bool has_aggre2_clk; const char *info_name; @@ -81,6 +83,13 @@ struct qcom_adsp { struct qcom_sysmon *sysmon; }; +static void adsp_minidump(struct rproc *rproc) +{ + struct qcom_adsp *adsp = rproc->priv; + + qcom_minidump(rproc, adsp->minidump_id); +} + static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds, size_t pd_count) { @@ -258,6 +267,15 @@ static const struct rproc_ops adsp_ops = { .panic = adsp_panic, }; +static const struct rproc_ops adsp_minidump_ops = { + .start = adsp_start, + .stop = adsp_stop, + .da_to_va = adsp_da_to_va, + .load = adsp_load, + .panic = adsp_panic, + .coredump = adsp_minidump, +}; + static int adsp_init_clock(struct qcom_adsp *adsp) { int ret; @@ -383,6 +401,7 @@ static int adsp_probe(struct platform_device *pdev) struct qcom_adsp *adsp; struct rproc *rproc; const char *fw_name; + const struct rproc_ops *ops = &adsp_ops; int ret; desc = of_device_get_match_data(&pdev->dev); @@ -398,8 +417,11 @@ static int adsp_probe(struct platform_device *pdev) if (ret < 0 && ret != -EINVAL) return ret; - rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, - fw_name, sizeof(*adsp)); + if (desc->minidump_id) + ops = &adsp_minidump_ops; + + rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); + if (!rproc) { dev_err(&pdev->dev, "unable to allocate remoteproc\n"); return -ENOMEM; @@ -411,6 +433,7 @@ static int adsp_probe(struct platform_device *pdev) adsp = (struct qcom_adsp *)rproc->priv; adsp->dev = &pdev->dev; adsp->rproc = rproc; + adsp->minidump_id = desc->minidump_id; adsp->pas_id = desc->pas_id; adsp->has_aggre2_clk = desc->has_aggre2_clk; adsp->info_name = desc->sysmon_name; From patchwork Thu Nov 19 21:05:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddharth Gupta X-Patchwork-Id: 11918971 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A984C56201 for ; Thu, 19 Nov 2020 21:06:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 05ADA2223F for ; Thu, 19 Nov 2020 21:06:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="sOQt22QY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726509AbgKSVGB (ORCPT ); Thu, 19 Nov 2020 16:06:01 -0500 Received: from z5.mailgun.us ([104.130.96.5]:55362 "EHLO z5.mailgun.us" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbgKSVGB (ORCPT ); Thu, 19 Nov 2020 16:06:01 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1605819961; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=lwagEK2rGEN9xgfP7v3iFqV+ZCBDN0gDho4DkTCttxY=; b=sOQt22QYPsK0Fp3JcVJ2PQ68rOKekwwGbcu+Bi12fG/VfVEk2PzLc7n/I0FKE4YyWKPGz+7/ nvOmiL3K59WoT4vBe0OJN3HcLsnJdVYaFOv7S7p1YcI0o0j/7n2vuZsHlPBuhXKXcgp6GO0w tIKh0WUhj3UXii+DwyEKsMbNRIw= X-Mailgun-Sending-Ip: 104.130.96.5 X-Mailgun-Sid: WyI4ZWZiZiIsICJsaW51eC1yZW1vdGVwcm9jQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n01.prod.us-west-2.postgun.com with SMTP id 5fb6de33e714ea65018adb42 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 19 Nov 2020 21:05:55 GMT Sender: sidgup=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id A75EBC43469; Thu, 19 Nov 2020 21:05:55 +0000 (UTC) Received: from sidgup-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sidgup) by smtp.codeaurora.org (Postfix) with ESMTPSA id 4E2BAC43461; Thu, 19 Nov 2020 21:05:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4E2BAC43461 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=sidgup@codeaurora.org From: Siddharth Gupta To: agross@kernel.org, bjorn.andersson@linaro.org, ohad@wizery.com, linux-remoteproc@vger.kernel.org Cc: Siddharth Gupta , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tsoni@codeaurora.org, psodagud@codeaurora.org, rishabhb@codeaurora.org, linux-doc@vger.kernel.org Subject: [PATCH v8 4/4] remoteproc: qcom: Add minidump id for sm8150 modem Date: Thu, 19 Nov 2020 13:05:35 -0800 Message-Id: <1605819935-10726-5-git-send-email-sidgup@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> References: <1605819935-10726-1-git-send-email-sidgup@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org Add minidump id for modem in sm8150 chipset so that the regions to be included in the coredump generated upon a crash is based on the minidump tables in SMEM instead of those in the ELF header. Signed-off-by: Siddharth Gupta Reviewed-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index ca05c2ef..e61ef88 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -630,6 +630,7 @@ static const struct adsp_data mpss_resource_init = { .crash_reason_smem = 421, .firmware_name = "modem.mdt", .pas_id = 4, + .minidump_id = 3, .has_aggre2_clk = false, .auto_boot = false, .active_pd_names = (char*[]){