crash/0001-x86_64-VC-exception-stack-support.patch
DistroBaker 7920ddfe25 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/crash.git#5a0c1d8fb7fcd83df5c5f5de38d3c32d4aa4200b
2021-02-06 13:06:37 +00:00

158 lines
5.9 KiB
Diff

From 9c881ab372010b46655dfed0a3c5cd78b3ff8fa0 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Mon, 30 Nov 2020 09:48:29 -0800
Subject: [PATCH 01/13] x86_64: VC exception stack support
Linux 5.10 has introduced SEV-ES support. New (5th) exception
stack was added: 'VC_stack'.
'struct exception_stacks' cannot be used to obtain the size
of VC stack, as the size of VC stack is zero there. Try
another structure 'struct cea_exception_stacks' first as it
represents actual CPU entry area with valid stack sizes and
guard pages.
Handled the case if VC stack is not mapped (present).
It happens when SEV-ES is not active or not supported.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
x86_64.c | 48 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/defs.h b/defs.h
index e1a18e9d0b4d..e468b1d99fcf 100644
--- a/defs.h
+++ b/defs.h
@@ -5938,6 +5938,7 @@ struct x86_64_pt_regs_offsets {
struct x86_64_stkinfo {
ulong ebase[NR_CPUS][MAX_EXCEPTION_STACKS];
int esize[MAX_EXCEPTION_STACKS];
+ char available[NR_CPUS][MAX_EXCEPTION_STACKS];
ulong ibase[NR_CPUS];
int isize;
int NMI_stack_index;
diff --git a/x86_64.c b/x86_64.c
index 939c8a9fddd4..23a40a04bbc4 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1369,6 +1369,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"))) {
@@ -1444,25 +1445,40 @@ 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.
+ * Adjust the top-of-stack addresses down to the base stack address
+ * and set stack page availabilituy flag.
*/
for (c = 0; c < kt->cpus; c++) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
- continue;
- ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+ if (ms->stkinfo.ebase[c][i])
+ ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+
+ ms->stkinfo.available[c][i] = TRUE;
+ /* VC stack can be unmapped if SEV-ES is disabled or not supported. */
+ if (STREQ(ms->stkinfo.exception_stacks[i], "VC") &&
+ !accessible(ms->stkinfo.ebase[c][i]))
+ ms->stkinfo.available[c][i] = FALSE;
}
}
@@ -1487,6 +1503,7 @@ x86_64_ist_init(void)
else
ms->stkinfo.esize[i] = esize;
ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+ ms->stkinfo.available[c][i] = TRUE;
}
}
@@ -2842,7 +2859,8 @@ x86_64_eframe_search(struct bt_info *bt)
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
+ if (ms->stkinfo.ebase[c][i] == 0 ||
+ !ms->stkinfo.available[c][i])
break;
bt->hp->esp = ms->stkinfo.ebase[c][i];
fprintf(fp, "CPU %d %s EXCEPTION STACK:",
@@ -3288,7 +3306,8 @@ x86_64_in_exception_stack(struct bt_info *bt, int *estack_index)
for (c = 0; !estack && (c < kt->cpus); c++) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
+ if (ms->stkinfo.ebase[c][i] == 0 ||
+ !ms->stkinfo.available[c][i])
break;
if ((rsp >= ms->stkinfo.ebase[c][i]) &&
(rsp < (ms->stkinfo.ebase[c][i] +
@@ -5097,7 +5116,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.available[bt->tc->processor][estack]))
goto skip_stage;
bt->stackbuf = ms->irqstack;
alter_stackbuf(bt);
@@ -5380,6 +5399,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";
}
}
@@ -5737,6 +5758,9 @@ x86_64_display_machine_stats(void)
fprintf(fp, "%22s: %016lx",
buf, machdep->machspec->stkinfo.ebase[c][i]);
+ if (!machdep->machspec->stkinfo.available[c][i])
+ fprintf(fp, " [unavailable]");
+
if (hide_offline_cpu(c))
fprintf(fp, " [OFFLINE]\n");
else
--
2.17.1