diff options
| author | Joerg Roedel <jroedel@suse.de> | 2020-09-07 15:15:43 +0200 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2020-09-09 11:33:19 +0200 |
| commit | 02772fb9b68e6a72a5e17f994048df832fe2b15e (patch) | |
| tree | ac6c3c2e41d924a7ddd9bbce6d605b0790dbc978 /arch/x86/kernel/sev-es.c | |
| parent | 885689e47dfa1499b756a07237eb645234d93cf9 (diff) | |
| download | linux-02772fb9b68e6a72a5e17f994048df832fe2b15e.tar.gz linux-02772fb9b68e6a72a5e17f994048df832fe2b15e.tar.bz2 linux-02772fb9b68e6a72a5e17f994048df832fe2b15e.zip | |
x86/sev-es: Allocate and map an IST stack for #VC handler
Allocate and map an IST stack and an additional fall-back stack for
the #VC handler. The memory for the stacks is allocated only when
SEV-ES is active.
The #VC handler needs to use an IST stack because a #VC exception can be
raised from kernel space with unsafe stack, e.g. in the SYSCALL entry
path.
Since the #VC exception can be nested, the #VC handler switches back to
the interrupted stack when entered from kernel space. If switching back
is not possible, the fall-back stack is used.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200907131613.12703-43-joro@8bytes.org
Diffstat (limited to 'arch/x86/kernel/sev-es.c')
| -rw-r--r-- | arch/x86/kernel/sev-es.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 720b1b671812..fae8145e4acf 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -17,6 +17,7 @@ #include <linux/kernel.h> #include <linux/mm.h> +#include <asm/cpu_entry_area.h> #include <asm/sev-es.h> #include <asm/insn-eval.h> #include <asm/fpu/internal.h> @@ -37,10 +38,41 @@ static struct ghcb __initdata *boot_ghcb; /* #VC handler runtime per-CPU data */ struct sev_es_runtime_data { struct ghcb ghcb_page; + + /* Physical storage for the per-CPU IST stack of the #VC handler */ + char ist_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); + + /* + * Physical storage for the per-CPU fall-back stack of the #VC handler. + * The fall-back stack is used when it is not safe to switch back to the + * interrupted stack in the #VC entry code. + */ + char fallback_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); }; static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); +static void __init setup_vc_stacks(int cpu) +{ + struct sev_es_runtime_data *data; + struct cpu_entry_area *cea; + unsigned long vaddr; + phys_addr_t pa; + + data = per_cpu(runtime_data, cpu); + cea = get_cpu_entry_area(cpu); + + /* Map #VC IST stack */ + vaddr = CEA_ESTACK_BOT(&cea->estacks, VC); + pa = __pa(data->ist_stack); + cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); + + /* Map VC fall-back stack */ + vaddr = CEA_ESTACK_BOT(&cea->estacks, VC2); + pa = __pa(data->fallback_stack); + cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); +} + /* Needed in vc_early_forward_exception */ void do_early_exception(struct pt_regs *regs, int trapnr); @@ -249,6 +281,7 @@ void __init sev_es_init_vc_handling(void) for_each_possible_cpu(cpu) { alloc_runtime_data(cpu); init_ghcb(cpu); + setup_vc_stacks(cpu); } } |
