[PATCH v2 1/2] arm64: add tag_mask machdep option
by Vinayak Menon
Raw ramdumps without vmcoreinfo does not work currently
with pointer authentication enabled. The arm capability
array can be queried but that creates a dependency on
the bits identifying the capabilities. Add a machdep
option instead to mask the tags when PAC is enabled.
Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
---
arm64.c | 20 +++++++++++++++-----
crash.8 | 1 +
defs.h | 1 +
help.c | 1 +
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 37aed07..5b59972 100644
--- a/arm64.c
+++ b/arm64.c
@@ -763,6 +763,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
*value = dtol(p, flags, &err);
} else if (STRNEQ(argstring, "vabits_actual")) {
*value = dtol(p, flags, &err);
+ } else if (STRNEQ(argstring, "tag_mask")) {
+ *value = htol(p, flags, &err);
} else if (megabytes) {
*value = dtol(p, flags, &err);
if (!err)
@@ -796,7 +798,6 @@ arm64_parse_cmdline_args(void)
for (index = 0; index < MAX_MACHDEP_ARGS; index++) {
if (!machdep->cmdline_args[index])
break;
-
if (!strstr(machdep->cmdline_args[index], "=")) {
error(WARNING, "ignoring --machdep option: %x\n",
machdep->cmdline_args[index]);
@@ -838,6 +839,12 @@ arm64_parse_cmdline_args(void)
"setting vabits_actual to: %ld\n\n",
machdep->machspec->VA_BITS_ACTUAL);
continue;
+ } else if (arm64_parse_machdep_arg_l(arglist[i], "tag_mask",
+ &machdep->machspec->tag_mask)) {
+ error(NOTE,
+ "setting tag_mask to: %lx\n\n",
+ machdep->machspec->tag_mask);
+ continue;
}
error(WARNING, "ignoring --machdep option: %s\n",
@@ -4124,16 +4131,19 @@ arm64_swp_offset(ulong pte)
static void arm64_calc_KERNELPACMASK(void)
{
- ulong value;
+ ulong value = 0;
char *string;
if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)"))) {
value = htol(string, QUIET, NULL);
free(string);
- machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
- if (CRASHDEBUG(1))
- fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
+ } else if (machdep->machspec->tag_mask) {
+ value = machdep->machspec->tag_mask;
}
+
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
+ if (CRASHDEBUG(1))
+ fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
}
#endif /* ARM64 */
diff --git a/crash.8 b/crash.8
index 5020ce1..de32bdb 100644
--- a/crash.8
+++ b/crash.8
@@ -289,6 +289,7 @@ ARM64:
kimage_voffset=<kimage_voffset-value>
max_physmem_bits=<value>
vabits_actual=<value>
+ tag_mask=<value>
X86:
page_offset=<CONFIG_PAGE_OFFSET-value>
.fi
diff --git a/defs.h b/defs.h
index 35b983a..d406f5f 100644
--- a/defs.h
+++ b/defs.h
@@ -3331,6 +3331,7 @@ struct machine_specific {
ulong VA_START;
ulong CONFIG_ARM64_KERNELPACMASK;
ulong physvirt_offset;
+ ulong tag_mask;
};
struct arm64_stackframe {
diff --git a/help.c b/help.c
index 531f50a..7f619d5 100644
--- a/help.c
+++ b/help.c
@@ -182,6 +182,7 @@ char *program_usage_info[] = {
" kimage_voffset=<kimage_voffset-value>",
" max_physmem_bits=<value>",
" vabits_actual=<value>",
+ " tag_mask=<value>",
" X86:",
" page_offset=<CONFIG_PAGE_OFFSET-value>",
"",
3 years, 3 months
[PATCH] arm64: Add lowercase tcr_el1_t1sz
by HAGIO KAZUHITO(萩尾 一仁)
From: John Donnelly <john.p.donnelly(a)oracle.com>
Commit 1c45cea "arm64: Change tcr_el1_t1sz variable name to
TCR_EL1_T1SZ", renamed the variable to upper case, but there are
kernels in existence that still have the lower case name, which
breaks crash backwards compatibility.
Resolves: https://github.com/crash-utility/crash/pull/82
Signed-off-by: John Donnelly <john.p.donnelly(a)oracle.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
The lowercase tcr_el1_t1sz was not seen upstream, but crash had it
once, we should have added the uppercase name, not replaced it.
So I ack this.
arm64.c | 3 ++-
netdump.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index 4787fa61e3e5..8934961b109d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3936,7 +3936,8 @@ arm64_calc_VA_BITS(void)
} else if (ACTIVE())
error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
else {
- if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)"))) {
+ if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
+ (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
/* See ARMv8 ARM for the description of
* TCR_EL1.T1SZ and how it can be used
* to calculate the vabits_actual
diff --git a/netdump.c b/netdump.c
index c1c9cbfaed94..aaea945aaca7 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1921,7 +1921,8 @@ vmcoreinfo_read_string(const char *key)
sprintf(value, "%ld", nd->arch_data2 & 0xffffffff);
return value;
}
- if (STREQ(key, "NUMBER(TCR_EL1_T1SZ)") && nd->arch_data2) {
+ if ((STREQ(key, "NUMBER(TCR_EL1_T1SZ)") ||
+ STREQ(key, "NUMBER(tcr_el1_t1sz)")) && nd->arch_data2) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lld", ((ulonglong)nd->arch_data2 >> 32) & 0xffffffff);
pc->read_vmcoreinfo = no_vmcoreinfo;
--
2.27.0
3 years, 3 months
[PATCH v3 1/1] tools: list: create O option for specifying head node offset
by Firo Yang
This -O option is very useful to specify the embedded head node's
offset which is different to the offset of other nodes embedded,
e.g. dentry.d_subdirs(the head node) and dentry.d_child.
Signed-off-by: Firo Yang <firo.yang(a)suse.com>
---
defs.h | 1 +
help.c | 32 +++++++++++++++++++++++++++++++-
tools.c | 36 +++++++++++++++++++++++++++++++++---
3 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 396d61a..d5fcd37 100644
--- a/defs.h
+++ b/defs.h
@@ -2613,6 +2613,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index e0c8408..1593f12 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,15 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset Only used in conjunction with -h; it specifies the offset of head",
+" node list_head embedded within a data structure which is different",
+" than the offset of list_head of other nodes embedded within a data",
+" structure.",
+" The offset may be entered in either of the following manners:",
+"",
+" 1. \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
@@ -6116,6 +6125,27 @@ char *help__list[] = {
" comm = \"sudo\"",
" ffff88005ac10180",
" comm = \"crash\"",
+"",
+" To display a liked list whose head node and other nodes are embedded within ",
+" either same or different data structures resulting in different offsets ",
+" for head node and other nodes, e.g. dentry.d_subdirs and dentry.d_child, this",
+" -O option can be used:",
+"",
+" %s> list -o dentry.d_child -s dentry.d_name.name -O dentry.d_subdirs -h ffff9c585b81a180",
+" ffff9c585b9cb140",
+" d_name.name = 0xffff9c585b9cb178 ccc.txt",
+" ffff9c585b9cb980",
+" d_name.name = 0xffff9c585b9cb9b8 bbb.txt",
+" ffff9c585b9cb740",
+" d_name.name = 0xffff9c585b9cb778 aaa.txt",
+"",
+" The dentry.d_subdirs example above is equal to the following sequence:",
+"",
+" %s> struct -o dentry.d_subdirs ffff9c585b81a180",
+" struct dentry {",
+" [ffff9c585b81a220] struct list_head d_subdirs;",
+" }",
+" %s> list -o dentry.d_child -s dentry.d_name.name -H ffff9c585b81a220",
NULL
};
diff --git a/tools.c b/tools.c
index a26b101..636adc6 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset = 0; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,24 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL,
+ "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg,
+ FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg,
+ sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n",
+ optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3618,19 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
+ if (!ld->end)
+ ld->end = ld->start + head_member_offset;
+ readmem(ld->start + head_member_offset, KVADDR,
+ &ld->start, sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ if (ld->start == ld->end) {
+ fprintf(fp, "(empty)\n");
+ return;
+ }
+ } else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.31.1
3 years, 3 months
[PATCH v2 1/1] tools: list: create O option for specifying head node offset
by Firo Yang
This new O option is very useful to specify the head node
offset for listing linked list whose head node embedded has a
different offset to other node, e.g. dentry.d_subdirs(the head node)
and dentry.d_child.
Signed-off-by: Firo Yang <firo.yang(a)suse.com>
---
defs.h | 1 +
help.c | 15 ++++++++++++++-
tools.c | 32 +++++++++++++++++++++++++++++---
3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 396d61a..d5fcd37 100644
--- a/defs.h
+++ b/defs.h
@@ -2613,6 +2613,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index e0c8408..3aa99f0 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,14 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset The -O option works only with -h option.",
+" It is used for specifying the offset of head node embedded in a",
+" structure, like dentry.d_subdirs or cgroup_subsys_state.children.",
+" The offset may be entered in either of two manners:",
+"",
+" 1. \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
@@ -6116,6 +6124,11 @@ char *help__list[] = {
" comm = \"sudo\"",
" ffff88005ac10180",
" comm = \"crash\"",
+"",
+" With the support of '-O' option, we can easily achieve the following convenient",
+" usage: ",
+" %s> alias ls list -O dentry.d_subdirs -o dentry.d_child -s dentry.d_name.name -h ",
+" %s> ls <address of dentry>",
NULL
};
diff --git a/tools.c b/tools.c
index a26b101..6a11670 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset = 0; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,24 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL,
+ "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg,
+ FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg,
+ sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n",
+ optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3618,15 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
+ if (!ld->end)
+ ld->end = ld->start + head_member_offset;
+ readmem(ld->start + head_member_offset, KVADDR,
+ &ld->start, sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ } else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.31.1
3 years, 3 months
[PATCH 1/1] tools: list: create O option for specifying head node offset
by Firo Yang
This new O option is very useful to specify the head node
offset for listing linked list whose head node embedded has a
different offset to other node, e.g. dentry.d_subdirs(the head node)
and dentry.d_child.
Signed-off-by: Firo Yang <firo.yang(a)suse.com>
---
defs.h | 1 +
help.c | 12 +++++++++++-
tools.c | 30 +++++++++++++++++++++++++++---
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 35b983a..764facf 100644
--- a/defs.h
+++ b/defs.h
@@ -2605,6 +2605,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index 531f50a..b561f3b 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,16 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset The -O option works only with -h option.",
+" It is used for specifying the offset of head node embedded in a",
+" structure, like dentry.d_subdirs or cgroup_subsys_state.children.",
+" The offset may be entered in either of two manners:",
+"",
+" 1. \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
+" You can use it like the following:",
+" list -O <head node offset> -o <node offset> -h start -s <...>",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
diff --git a/tools.c b/tools.c
index a26b101..792a567 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,24 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL,
+ "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg,
+ FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg,
+ sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n",
+ optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3618,13 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ readmem(ld->start + head_member_offset, KVADDR,
+ &ld->start, sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.30.2
3 years, 3 months