From: Mukesh Ojha <quic_mojha@quicinc.com>
To: <corbet@lwn.net>, <agross@kernel.org>, <andersson@kernel.org>,
<konrad.dybcio@linaro.org>, <robh+dt@kernel.org>,
<krzysztof.kozlowski+dt@linaro.org>, <conor+dt@kernel.org>,
<keescook@chromium.org>, <tony.luck@intel.com>,
<gpiccoli@igalia.com>, <mathieu.poirier@linaro.org>,
<catalin.marinas@arm.com>, <will@kernel.org>,
<linus.walleij@linaro.org>, <andy.shevchenko@gmail.com>
Cc: <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-arm-msm@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-hardening@vger.kernel.org>,
<linux-remoteproc@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-gpio@vger.kernel.org>,
"Mukesh Ojha" <quic_mojha@quicinc.com>
Subject: [PATCH v4 05/21] soc: qcom: Add linux minidump smem backend driver support
Date: Wed, 28 Jun 2023 18:04:32 +0530 [thread overview]
Message-ID: <1687955688-20809-6-git-send-email-quic_mojha@quicinc.com> (raw)
In-Reply-To: <1687955688-20809-1-git-send-email-quic_mojha@quicinc.com>
Add shared memory based minidump backend driver and hook it
with minidump core (qcom_minidump) by registering SMEM as
backend device.
Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
---
drivers/soc/qcom/Kconfig | 8 +-
drivers/soc/qcom/qcom_minidump_smem.c | 231 +++++++++++++++++++++++++++++++++-
drivers/soc/qcom/smem.c | 9 ++
3 files changed, 240 insertions(+), 8 deletions(-)
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 874ee8c3efe0..1834213fd652 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -298,8 +298,12 @@ config QCOM_MINIDUMP_SMEM
tristate "QCOM Minidump SMEM (as backend) Support"
depends on ARCH_QCOM
depends on QCOM_SMEM
+ select QCOM_MINIDUMP
help
Enablement of core minidump feature is controlled from boot firmware
- side, and this config allow linux to query minidump segments associated
- with the remote processor and check its validity.
+ side, and this config allow linux to query and manages minidump
+ table for remote processors as well as APSS.
+
+ This config should be enabled if the low level minidump is implemented
+ as part of SMEM.
endmenu
diff --git a/drivers/soc/qcom/qcom_minidump_smem.c b/drivers/soc/qcom/qcom_minidump_smem.c
index b588833ea26e..bdc75aa2f518 100644
--- a/drivers/soc/qcom/qcom_minidump_smem.c
+++ b/drivers/soc/qcom/qcom_minidump_smem.c
@@ -2,18 +2,34 @@
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
#include <linux/soc/qcom/smem.h>
-#include <soc/qcom/qcom_minidump.h>
+
+#include "qcom_minidump_internal.h"
#define MAX_NUM_OF_SS 10
-#define MAX_REGION_NAME_LENGTH 16
#define SBL_MINIDUMP_SMEM_ID 602
-#define MINIDUMP_REGION_VALID ('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
-#define MINIDUMP_SS_ENCR_DONE ('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0)
-#define MINIDUMP_SS_ENABLED ('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0)
+
+#define MINIDUMP_REGION_VALID ('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
+#define MINIDUMP_REGION_INVALID ('I' << 24 | 'N' << 16 | 'V' << 8 | 'A' << 0)
+#define MINIDUMP_REGION_INIT ('I' << 24 | 'N' << 16 | 'I' << 8 | 'T' << 0)
+#define MINIDUMP_REGION_NOINIT 0
+
+#define MINIDUMP_SS_ENCR_REQ (0 << 24 | 'Y' << 16 | 'E' << 8 | 'S' << 0)
+#define MINIDUMP_SS_ENCR_NOTREQ (0 << 24 | 0 << 16 | 'N' << 8 | 'R' << 0)
+#define MINIDUMP_SS_ENCR_START ('S' << 24 | 'T' << 16 | 'R' << 8 | 'T' << 0)
+#define MINIDUMP_SS_ENCR_DONE ('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0)
+#define MINIDUMP_SS_ENABLED ('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0)
+
+#define MINIDUMP_APSS_DESC 0
/**
* struct minidump_region - Minidump region
@@ -64,6 +80,16 @@ struct minidump_global_toc {
};
/**
+ * struct minidump_ss_data - Minidump subsystem private data
+ * @md_ss_toc : Application Subsystem TOC pointer
+ * @md_regions : Application Subsystem region base pointer
+ */
+struct minidump_ss_data {
+ struct minidump_subsystem *md_ss_toc;
+ struct minidump_region *md_regions;
+};
+
+/**
* qcom_ss_md_mapped_base() - For getting subsystem iomapped base segment address
* for given minidump index.
*
@@ -143,5 +169,198 @@ int qcom_ss_valid_segment_info(void *ptr, int i, char **name, dma_addr_t *da, si
}
EXPORT_SYMBOL_GPL(qcom_ss_valid_segment_info);
+static int smem_md_get_region_index(struct minidump_ss_data *mdss_data,
+ const struct qcom_minidump_region *region)
+{
+ struct minidump_subsystem *mdss_toc = mdss_data->md_ss_toc;
+ struct minidump_region *mdr;
+ unsigned int i;
+ unsigned int count;
+
+ count = le32_to_cpu(mdss_toc->region_count);
+ for (i = 0; i < count; i++) {
+ mdr = &mdss_data->md_regions[i];
+ if (!strcmp(mdr->name, region->name))
+ return i;
+ }
+
+ return -ENOENT;
+}
+
+static void smem_md_add_region(struct minidump_ss_data *mdss_data,
+ const struct qcom_minidump_region *region)
+{
+ struct minidump_subsystem *mdss_toc = mdss_data->md_ss_toc;
+ struct minidump_region *mdr;
+ unsigned int region_cnt;
+
+ region_cnt = le32_to_cpu(mdss_toc->region_count);
+ mdr = &mdss_data->md_regions[region_cnt];
+ strscpy(mdr->name, region->name, sizeof(mdr->name));
+ mdr->address = cpu_to_le64(region->phys_addr);
+ mdr->size = cpu_to_le64(region->size);
+ mdr->valid = cpu_to_le32(MINIDUMP_REGION_VALID);
+ region_cnt++;
+ mdss_toc->region_count = cpu_to_le32(region_cnt);
+}
+
+static int smem_md_region_register(struct minidump *md,
+ const struct qcom_minidump_region *region)
+{
+ struct minidump_ss_data *mdss_data = md->apss_data;
+ struct minidump_subsystem *mdss_toc = mdss_data->md_ss_toc;
+ unsigned int num_region;
+ int ret;
+
+ ret = smem_md_get_region_index(mdss_data, region);
+ if (ret >= 0) {
+ dev_info(md->dev, "%s region is already registered\n", region->name);
+ return -EEXIST;
+ }
+
+ /* Check if there is a room for a new entry */
+ num_region = le32_to_cpu(mdss_toc->region_count);
+ if (num_region >= md->max_region_limit) {
+ dev_err(md->dev, "maximum region limit %u reached\n", num_region);
+ return -ENOSPC;
+ }
+
+ smem_md_add_region(mdss_data, region);
+
+ return 0;
+}
+
+static int smem_md_region_unregister(struct minidump *md,
+ const struct qcom_minidump_region *region)
+{
+ struct minidump_ss_data *mdss_data = md->apss_data;
+ struct minidump_subsystem *mdss_toc = mdss_data->md_ss_toc;
+ struct minidump_region *mdr;
+ unsigned int region_cnt;
+ unsigned int idx;
+ int ret;
+
+ ret = smem_md_get_region_index(mdss_data, region);
+ if (ret < 0) {
+ dev_err(md->dev, "%s region is not present\n", region->name);
+ return ret;
+ }
+
+ idx = ret;
+ mdr = &mdss_data->md_regions[0];
+ region_cnt = le32_to_cpu(mdss_toc->region_count);
+ /*
+ * Left shift all the regions exist after this removed region
+ * index by 1 to fill the gap and zero out the last region
+ * present at the end.
+ */
+ memmove(&mdr[idx], &mdr[idx + 1],
+ (region_cnt - idx - 1) * sizeof(struct minidump_region));
+ memset(&mdr[region_cnt - 1], 0, sizeof(struct minidump_region));
+ region_cnt--;
+ mdss_toc->region_count = cpu_to_le32(region_cnt);
+
+ return 0;
+}
+
+static int smem_md_table_init(struct minidump *md)
+{
+ struct minidump_global_toc *mdgtoc;
+ struct minidump_ss_data *mdss_data;
+ struct minidump_subsystem *mdss_toc;
+ size_t size;
+ int ret;
+
+ mdgtoc = qcom_smem_get(QCOM_SMEM_HOST_ANY, SBL_MINIDUMP_SMEM_ID, &size);
+ if (IS_ERR(mdgtoc)) {
+ ret = PTR_ERR(mdgtoc);
+ dev_err(md->dev, "Couldn't find minidump smem item: %d\n", ret);
+ return ret;
+ }
+
+ if (size < sizeof(mdgtoc) || !mdgtoc->status) {
+ ret = -EINVAL;
+ dev_err(md->dev, "minidump table is not initialized: %d\n", ret);
+ return ret;
+ }
+
+ mdss_data = devm_kzalloc(md->dev, sizeof(*mdss_data), GFP_KERNEL);
+ if (!mdss_data)
+ return -ENOMEM;
+
+ mdss_data->md_ss_toc = &mdgtoc->subsystems[MINIDUMP_APSS_DESC];
+ mdss_data->md_regions = devm_kcalloc(md->dev, md->max_region_limit,
+ sizeof(struct minidump_region), GFP_KERNEL);
+ if (!mdss_data->md_regions)
+ return -ENOMEM;
+
+ mdss_toc = mdss_data->md_ss_toc;
+ mdss_toc->regions_baseptr = cpu_to_le64(virt_to_phys(mdss_data->md_regions));
+ mdss_toc->enabled = cpu_to_le32(MINIDUMP_SS_ENABLED);
+ mdss_toc->status = cpu_to_le32(1);
+ mdss_toc->region_count = cpu_to_le32(0);
+
+ /* Tell bootloader not to encrypt the regions of this subsystem */
+ mdss_toc->encryption_status = cpu_to_le32(MINIDUMP_SS_ENCR_DONE);
+ mdss_toc->encryption_required = cpu_to_le32(MINIDUMP_SS_ENCR_NOTREQ);
+ md->apss_data = mdss_data;
+
+ return 0;
+}
+
+static int smem_md_table_exit(struct minidump *md)
+{
+ struct minidump_ss_data *mdss_data;
+
+ mdss_data = md->apss_data;
+ memset(mdss_data->md_ss_toc,
+ cpu_to_le32(0), sizeof(struct minidump_subsystem));
+
+ return 0;
+}
+
+static struct minidump_ops smem_md_ops = {
+ .md_table_init = smem_md_table_init,
+ .md_table_exit = smem_md_table_exit,
+ .md_region_register = smem_md_region_register,
+ .md_region_unregister = smem_md_region_unregister,
+};
+
+static int qcom_minidump_smem_probe(struct platform_device *pdev)
+{
+ struct minidump *md;
+
+ md = devm_kzalloc(&pdev->dev, sizeof(*md), GFP_KERNEL);
+ if (!md)
+ return -ENOMEM;
+
+ md->dev = &pdev->dev;
+ md->ops = &smem_md_ops;
+ md->name = "smem";
+ platform_set_drvdata(pdev, md);
+
+ return qcom_minidump_backend_register(md);
+}
+
+static int qcom_minidump_smem_remove(struct platform_device *pdev)
+{
+ struct minidump *md = platform_get_drvdata(pdev);
+
+ qcom_minidump_backend_unregister(md);
+
+ return 0;
+}
+
+static struct platform_driver qcom_minidump_smem_driver = {
+ .probe = qcom_minidump_smem_probe,
+ .remove = qcom_minidump_smem_remove,
+ .driver = {
+ .name = "qcom-minidump-smem",
+ },
+};
+
+module_platform_driver(qcom_minidump_smem_driver);
+
MODULE_DESCRIPTION("Qualcomm Minidump SMEM as backend driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:qcom-minidump-smem");
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 6be7ea93c78c..af582aa7f9a3 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -269,6 +269,7 @@ struct smem_region {
* @partitions: list of partitions of current processor/host
* @item_count: max accepted item number
* @socinfo: platform device pointer
+ * @minidump: minidump platform device pointer
* @num_regions: number of @regions
* @regions: list of the memory regions defining the shared memory
*/
@@ -279,6 +280,7 @@ struct qcom_smem {
u32 item_count;
struct platform_device *socinfo;
+ struct platform_device *minidump;
struct smem_ptable *ptable;
struct smem_partition global_partition;
struct smem_partition partitions[SMEM_HOST_COUNT];
@@ -1151,11 +1153,18 @@ static int qcom_smem_probe(struct platform_device *pdev)
if (IS_ERR(smem->socinfo))
dev_dbg(&pdev->dev, "failed to register socinfo device\n");
+ smem->minidump = platform_device_register_data(&pdev->dev, "qcom-minidump-smem",
+ PLATFORM_DEVID_NONE, NULL,
+ 0);
+ if (IS_ERR(smem->minidump))
+ dev_dbg(&pdev->dev, "failed to register minidump device\n");
+
return 0;
}
static int qcom_smem_remove(struct platform_device *pdev)
{
+ platform_device_unregister(__smem->minidump);
platform_device_unregister(__smem->socinfo);
hwspin_lock_free(__smem->hwlock);
--
2.7.4
next prev parent reply other threads:[~2023-06-28 12:36 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-28 12:34 [PATCH v4 00/21] Add Qualcomm Minidump kernel driver related support Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 01/21] docs: qcom: Add qualcomm minidump guide Mukesh Ojha
2023-06-28 23:21 ` Rob Herring
2023-06-28 12:34 ` [PATCH v4 02/21] kallsyms: Export kallsyms_lookup_name Mukesh Ojha
2023-06-28 13:24 ` Andy Shevchenko
2023-06-28 15:04 ` Mukesh Ojha
2023-06-28 13:53 ` Pavan Kondeti
2023-06-28 15:22 ` Mukesh Ojha
2023-06-28 15:32 ` Will Deacon
2023-06-28 15:43 ` Greg KH
2023-06-28 12:34 ` [PATCH v4 03/21] soc: qcom: Add qcom_minidump_smem module Mukesh Ojha
2023-06-28 13:31 ` Andy Shevchenko
2023-06-28 15:47 ` Greg KH
2023-06-28 12:34 ` [PATCH v4 04/21] soc: qcom: Add Qualcomm APSS minidump (frontend) feature support Mukesh Ojha
2023-06-28 13:43 ` Andy Shevchenko
2023-06-29 2:33 ` Pavan Kondeti
2023-06-30 7:15 ` Mukesh Ojha
2023-06-30 8:38 ` Pavan Kondeti
2023-06-28 12:34 ` Mukesh Ojha [this message]
2023-06-28 13:51 ` [PATCH v4 05/21] soc: qcom: Add linux minidump smem backend driver support Andy Shevchenko
2023-06-28 12:34 ` [PATCH v4 06/21] soc: qcom: minidump: Add pending region registration support Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 07/21] soc: qcom: minidump: Add update region support Mukesh Ojha
2023-06-29 2:49 ` Pavan Kondeti
2023-06-28 12:34 ` [PATCH v4 08/21] dt-bindings: reserved-memory: Add qcom,ramoops binding Mukesh Ojha
2023-06-28 14:10 ` Pavan Kondeti
2023-06-28 23:17 ` Rob Herring
2023-06-29 1:45 ` Pavan Kondeti
2023-06-28 14:47 ` Rob Herring
2023-06-28 15:01 ` Mukesh Ojha
2023-07-02 8:12 ` Krzysztof Kozlowski
2023-07-03 6:21 ` Mukesh Ojha
2023-07-03 7:20 ` Krzysztof Kozlowski
2023-07-03 15:55 ` Mukesh Ojha
2023-07-04 5:57 ` Krzysztof Kozlowski
2023-07-19 10:29 ` Luca Stefani
2023-06-28 12:34 ` [PATCH v4 09/21] pstore/ram : Export ramoops_parse_dt() symbol Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 10/21] soc: qcom: Add qcom's pstore minidump driver support Mukesh Ojha
2023-06-28 22:57 ` Rob Herring
2023-06-29 9:16 ` Mukesh Ojha
2023-07-05 23:27 ` Rob Herring
2023-06-28 12:34 ` [PATCH v4 11/21] soc: qcom: Register pstore frontend region with minidump Mukesh Ojha
2023-06-30 4:55 ` Pavan Kondeti
2023-06-30 9:25 ` Andy Shevchenko
2023-06-28 12:34 ` [PATCH v4 12/21] remoteproc: qcom: Expand MD_* as MINIDUMP_* Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 13/21] remoterproc: qcom: refactor to leverage exported minidump symbol Mukesh Ojha
2023-06-28 15:51 ` Pavan Kondeti
2023-06-29 9:20 ` Mukesh Ojha
2023-06-30 3:41 ` Pavan Kondeti
2023-06-28 12:34 ` [PATCH v4 14/21] MAINTAINERS: Add entry for minidump driver related support Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 15/21] arm64: defconfig: Enable Qualcomm Minidump related drivers Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 16/21] arm64: dts: qcom: sm8450: Add Qualcomm ramoops minidump node Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 17/21] firmware: qcom_scm: provide a read-modify-write function Mukesh Ojha
2023-06-30 5:01 ` Pavan Kondeti
2023-06-28 12:34 ` [PATCH v4 18/21] pinctrl: qcom: Use qcom_scm_io_update_field() Mukesh Ojha
2023-06-28 13:44 ` Andy Shevchenko
2023-06-30 14:58 ` Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 19/21] firmware: scm: Modify only the download bits in TCSR register Mukesh Ojha
2023-06-28 15:20 ` Konrad Dybcio
2023-06-30 14:57 ` Mukesh Ojha
2023-06-28 12:34 ` [PATCH v4 20/21] firmware: qcom_scm: Refactor code to support multiple download mode Mukesh Ojha
2023-06-30 5:25 ` Pavan Kondeti
2023-06-30 9:28 ` Andy Shevchenko
2023-06-28 12:34 ` [PATCH v4 21/21] firmware: qcom_scm: Add multiple download mode support Mukesh Ojha
2023-06-28 15:45 ` [PATCH v4 00/21] Add Qualcomm Minidump kernel driver related support Greg KH
2023-06-28 16:20 ` Mukesh Ojha
2023-06-28 16:53 ` Greg KH
2023-06-28 23:12 ` Rob Herring
2023-06-30 16:04 ` Mukesh Ojha
2023-07-02 8:29 ` Krzysztof Kozlowski
2023-07-03 21:05 ` Trilok Soni
2023-07-06 17:20 ` Mathieu Poirier
2023-07-18 15:03 ` Mukesh Ojha
2023-08-07 13:46 ` Mukesh Ojha
2023-07-06 17:40 ` Rob Herring
2023-07-06 18:07 ` Trilok Soni
2023-08-10 16:47 ` Mukesh Ojha
2023-07-04 9:27 ` Linus Walleij
2023-07-05 17:29 ` Trilok Soni
2023-07-14 23:45 ` Trilok Soni
2023-07-18 5:47 ` Mukesh Ojha
2023-07-18 13:35 ` Greg KH
2023-07-18 13:55 ` Mukesh Ojha
2023-07-18 14:41 ` Greg KH
2023-07-18 16:22 ` Trilok Soni
2023-07-02 8:08 ` Krzysztof Kozlowski
2023-07-13 4:39 ` Kathiravan T
2023-07-14 15:25 ` Mukesh Ojha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1687955688-20809-6-git-send-email-quic_mojha@quicinc.com \
--to=quic_mojha@quicinc.com \
--cc=agross@kernel.org \
--cc=andersson@kernel.org \
--cc=andy.shevchenko@gmail.com \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=corbet@lwn.net \
--cc=devicetree@vger.kernel.org \
--cc=gpiccoli@igalia.com \
--cc=keescook@chromium.org \
--cc=konrad.dybcio@linaro.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
--cc=robh+dt@kernel.org \
--cc=tony.luck@intel.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).