[v3,06/18] soc: qcom: minidump: Add update region support

Message ID 1683133352-10046-7-git-send-email-quic_mojha@quicinc.com
State New
Headers
Series [v3,01/18] remoteproc: qcom: Expand MD_* as MINIDUMP_* |

Commit Message

Mukesh Ojha May 3, 2023, 5:02 p.m. UTC
  Add support to update client's region physical/virtual addresses,
which is useful for dynamic loadable modules, dynamic address
changing clients like if we want to collect current stack
information for each core and the current stack is changing on
each sched_switch event, So here virtual/physical address of
the current stack is changing. So, to cover such use cases
add the update region support in minidump driver.

Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
---
 drivers/soc/qcom/qcom_minidump.c | 57 ++++++++++++++++++++++++++++++++++++++++
 include/soc/qcom/qcom_minidump.h |  7 +++++
 2 files changed, 64 insertions(+)
  

Comments

Krzysztof Kozlowski May 4, 2023, 11:40 a.m. UTC | #1
On 03/05/2023 19:02, Mukesh Ojha wrote:
> Add support to update client's region physical/virtual addresses,
> which is useful for dynamic loadable modules, dynamic address
> changing clients like if we want to collect current stack
> information for each core and the current stack is changing on
> each sched_switch event, So here virtual/physical address of
> the current stack is changing. So, to cover such use cases
> add the update region support in minidump driver.
> 
> Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
> ---
>  drivers/soc/qcom/qcom_minidump.c | 57 ++++++++++++++++++++++++++++++++++++++++
>  include/soc/qcom/qcom_minidump.h |  7 +++++
>  2 files changed, 64 insertions(+)
> 
> diff --git a/drivers/soc/qcom/qcom_minidump.c b/drivers/soc/qcom/qcom_minidump.c
> index 6d29371..853bdda 100644
> --- a/drivers/soc/qcom/qcom_minidump.c
> +++ b/drivers/soc/qcom/qcom_minidump.c
> @@ -561,6 +561,63 @@ int qcom_apss_minidump_region_unregister(const struct qcom_apss_minidump_region
>  }
>  EXPORT_SYMBOL_GPL(qcom_apss_minidump_region_unregister);
>  
> +/**
> + * qcom_apss_minidump_update_region() - Update region in APSS minidump table.

Description of the function is exact copy of function name. This is a
hint for two things:
1. Your function has wrong name.
2. Your description is not helping.



Best regards,
Krzysztof
  

Patch

diff --git a/drivers/soc/qcom/qcom_minidump.c b/drivers/soc/qcom/qcom_minidump.c
index 6d29371..853bdda 100644
--- a/drivers/soc/qcom/qcom_minidump.c
+++ b/drivers/soc/qcom/qcom_minidump.c
@@ -561,6 +561,63 @@  int qcom_apss_minidump_region_unregister(const struct qcom_apss_minidump_region
 }
 EXPORT_SYMBOL_GPL(qcom_apss_minidump_region_unregister);
 
+/**
+ * qcom_apss_minidump_update_region() - Update region in APSS minidump table.
+ * @region: minidump region.
+ *
+ * Return: On success, it returns 0 and negative error value on failure.
+ */
+int qcom_apss_minidump_update_region(const struct qcom_apss_minidump_region *region)
+{
+	struct minidump_pending_region *md_pregion;
+	struct qcom_apss_minidump_region *tmp;
+	struct minidump_region *mdr;
+	struct elfhdr *ehdr;
+	struct elf_shdr *shdr;
+	struct elf_phdr *phdr;
+	int idx;
+	int ret = 0;
+
+	if (!qcom_apss_minidump_valid_region(region))
+		return -EINVAL;
+
+	mutex_lock(&minidump_lock);
+	if (!__md) {
+		md_pregion = get_qcom_apss_pending_region(region);
+		if (!md_pregion) {
+			ret = -ENOENT;
+			goto unlock;
+		}
+		tmp = &md_pregion->region;
+		tmp->phys_addr = region->phys_addr;
+		tmp->virt_addr = region->virt_addr;
+		goto unlock;
+	}
+
+	idx = get_apss_minidump_region_index(region);
+	if (idx < 0) {
+		pr_err("%s region is not present\n", region->name);
+		ret = idx;
+		goto unlock;
+	}
+
+	mdr = &__md->md_regions[idx];
+	mdr->address = cpu_to_le64(region->phys_addr);
+
+	/* Skip predefined shdr/phdr header entry at the start */
+	ehdr = __md->elf.ehdr;
+	shdr = elf_shdr_entry_addr(ehdr, idx + 4);
+	phdr = elf_phdr_entry_addr(ehdr, idx + 1);
+
+	shdr->sh_addr = (elf_addr_t)region->virt_addr;
+	phdr->p_vaddr = (elf_addr_t)region->virt_addr;
+	phdr->p_paddr = region->phys_addr;
+unlock:
+	mutex_unlock(&minidump_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_apss_minidump_update_region);
+
 static int qcom_minidump_init_apss_subsystem(struct minidump *md)
 {
 	struct minidump_subsystem *apsstoc;
diff --git a/include/soc/qcom/qcom_minidump.h b/include/soc/qcom/qcom_minidump.h
index 1872668..0c8cc2d 100644
--- a/include/soc/qcom/qcom_minidump.h
+++ b/include/soc/qcom/qcom_minidump.h
@@ -102,6 +102,8 @@  extern int
 qcom_apss_minidump_region_register(const struct qcom_apss_minidump_region *region);
 extern int
 qcom_apss_minidump_region_unregister(const struct qcom_apss_minidump_region *region);
+extern int
+qcom_apss_minidump_update_region(const struct qcom_apss_minidump_region *region);
 #else
 static inline
 struct minidump_subsystem *qcom_minidump_subsystem_desc(unsigned int minidump_index)
@@ -119,5 +121,10 @@  qcom_apss_minidump_region_unregister(const struct qcom_apss_minidump_region *reg
 {
 	return 0;
 }
+statuc inline int
+int qcom_apss_minidump_update_region(const struct qcom_apss_minidump_region *region)
+{
+	return 0;
+}
 #endif
 #endif  /* _QCOM_MINIDUMP_H_ */