Currently the logic for reading registers from each type of dumpfile is
separated into different functions depending on the vmcore type.
This causes duplication of code when any architecture wants to support
reading registers from multiple vmcore types, by having a if-else ladder
calling respective function to read registers, depending on vmcore type.
Instead, implement 'get_dumpfile_regs' to handle this and call the
appropriate function for reading the registers, based on vmcore type and
architecture. It is architecture agnostic, and can be used by all
supported architectures and all supported vmcores
Also, on PPC64, 'ppc64_get_dumpfile_stack_frame' also prints the registers,
but now 'ppc64_get_dumpfile_stack_frame' gets called more frequently and
printed registers everytime 'bt' is run in gdb mode. 'BT_NO_PRINT_REGS'
flag has been introduced, so it can be set in 'bt->flags' by the caller to
convey that we don't want the registers to be printed
'get_dumpfile_regs' is used in later patches crash to fix gdb passthrough by
providing it register values
Signed-off-by: Aditya Gupta <adityag(a)linux.ibm.com>
---
defs.h | 2 ++
kernel.c | 33 +++++++++++++++++++++++++++++++++
ppc64.c | 8 +++++---
3 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 358f365585cf..b6f213120975 100644
--- a/defs.h
+++ b/defs.h
@@ -6021,6 +6021,7 @@ int load_module_symbols_helper(char *);
void unlink_module(struct load_module *);
int check_specified_module_tree(char *, char *);
int is_system_call(char *, ulong);
+void get_dumpfile_regs(struct bt_info*, ulong*, ulong*);
void generic_dump_irq(int);
void generic_get_irq_affinity(int);
void generic_show_interrupts(int, ulong *);
@@ -6117,6 +6118,7 @@ ulong cpu_map_addr(const char *type);
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
#define BT_OVERFLOW_STACK (0x8000000000000ULL)
#define BT_SKIP_IDLE (0x10000000000000ULL)
+#define BT_NO_PRINT_REGS (0x20000000000000ULL)
#define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
#define BT_REF_HEXVAL (0x1)
diff --git a/kernel.c b/kernel.c
index 2114700eecc8..e6920e241c4e 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3514,6 +3514,39 @@ get_lkcd_regs(struct bt_info *bt, ulong *eip, ulong *esp)
machdep->get_stack_frame(bt, eip, esp);
}
+void
+get_dumpfile_regs(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+ bt->flags |= BT_NO_PRINT_REGS;
+
+ if (NETDUMP_DUMPFILE())
+ get_netdump_regs(bt, eip, esp);
+ else if (KDUMP_DUMPFILE())
+ get_kdump_regs(bt, eip, esp);
+ else if (DISKDUMP_DUMPFILE())
+ get_diskdump_regs(bt, eip, esp);
+ else if (KVMDUMP_DUMPFILE())
+ get_kvmdump_regs(bt, eip, esp);
+ else if (LKCD_DUMPFILE())
+ get_lkcd_regs(bt, eip, esp);
+ else if (XENDUMP_DUMPFILE())
+ get_xendump_regs(bt, eip, esp);
+ else if (SADUMP_DUMPFILE())
+ get_sadump_regs(bt, eip, esp);
+ else if (VMSS_DUMPFILE())
+ get_vmware_vmss_regs(bt, eip, esp);
+ else if (REMOTE_PAUSED()) {
+ if (!is_task_active(bt->task) || !get_remote_regs(bt, eip, esp))
+ machdep->get_stack_frame(bt, eip, esp);
+ } else
+ machdep->get_stack_frame(bt, eip, esp);
+
+ bt->flags &= ~BT_NO_PRINT_REGS;
+
+ bt->instptr = *eip;
+ bt->stkptr = *esp;
+}
+
/*
* Store the head of the kernel module list for future use.
diff --git a/ppc64.c b/ppc64.c
index fc34006f4863..7622f68289e7 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2584,9 +2584,11 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip,
ulong *ksp)
pt_regs = (struct ppc64_pt_regs *)bt->machdep;
ur_nip = pt_regs->nip;
ur_ksp = pt_regs->gpr[1];
- /* Print the collected regs for panic task. */
- ppc64_print_regs(pt_regs);
- ppc64_print_nip_lr(pt_regs, 1);
+ if (!(bt->flags & BT_NO_PRINT_REGS)) {
+ /* Print the collected regs for panic task. */
+ ppc64_print_regs(pt_regs);
+ ppc64_print_nip_lr(pt_regs, 1);
+ }
} else if ((pc->flags & KDUMP) ||
((pc->flags & DISKDUMP) &&
(*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
--
2.41.0