Linux-5.10 has introduced SEV-ES support. New (5th) exception
stack was added: 'VC_stack'.
'struct exception_stacks' cannot be used to obtain size of
VC stack, as it equals zero there. Try another structure
'struct cea_exception_stacks' first as it represents actual
CPU entry area with valid stack sizes and guard pages.
Added check for zero size stack to avoid stack parsing
issues.
Signed-off-by: Alexey Makhalov <amakhalov(a)vmware.com>
---
x86_64.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index fc05e8a..ea4a894 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1367,6 +1367,7 @@ x86_64_ist_init(void)
ulong init_tss;
struct machine_specific *ms;
struct syment *boot_sp, *tss_sp, *ist_sp;
+ char *exc_stack_struct_name = NULL;
ms = machdep->machspec;
if (!(tss_sp = per_cpu_symbol_search("per_cpu__init_tss"))) {
@@ -1442,16 +1443,25 @@ x86_64_ist_init(void)
return;
}
- if (MEMBER_EXISTS("exception_stacks", "NMI_stack")) {
+ if (MEMBER_EXISTS("cea_exception_stacks", "NMI_stack")) {
+ /* The effective cpu entry area mapping with guard pages. */
+ exc_stack_struct_name = "cea_exception_stacks";
+ } else if (MEMBER_EXISTS("exception_stacks", "NMI_stack")) {
+ /* The exception stacks' physical storage. No guard pages and no VC stack. */
+ exc_stack_struct_name = "exception_stacks";
+ }
+ if (exc_stack_struct_name) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
if (STREQ(ms->stkinfo.exception_stacks[i], "DEBUG"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks",
"DB_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "DB_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "NMI"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks",
"NMI_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "NMI_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "DOUBLEFAULT"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks",
"DF_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "DF_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "MCE"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks",
"MCE_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "MCE_stack");
+ else if (STREQ(ms->stkinfo.exception_stacks[i], "VC"))
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "VC_stack");
}
/*
* Adjust the top-of-stack addresses down to the base stack address.
@@ -5090,7 +5100,7 @@ skip_stage:
ms->stkinfo.esize[estack];
console("x86_64_get_dumpfile_stack_frame: searching %s estack at %lx\n",
ms->stkinfo.exception_stacks[estack], bt->stackbase);
- if (!(bt->stackbase))
+ if (!(bt->stackbase) || !(ms->stkinfo.esize[estack]))
goto skip_stage;
bt->stackbuf = ms->irqstack;
alter_stackbuf(bt);
@@ -5373,6 +5383,8 @@ x86_64_exception_stacks_init(void)
ms->stkinfo.exception_stacks[ist-1] = "DOUBLEFAULT";
if (strstr(buf, "machine"))
ms->stkinfo.exception_stacks[ist-1] = "MCE";
+ if (strstr(buf, "vmm"))
+ ms->stkinfo.exception_stacks[ist-1] = "VC";
}
}
--
2.11.0