158 lines
5.9 KiB
Diff
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
|
||
|
|