x86/sev: Make the #VC exception stacks part of the default stacks storage
authorBorislav Petkov <bp@suse.de>
Fri, 1 Oct 2021 19:41:20 +0000 (21:41 +0200)
committerBorislav Petkov <bp@suse.de>
Wed, 6 Oct 2021 19:48:27 +0000 (21:48 +0200)
The size of the exception stacks was increased by the commit in Fixes,
resulting in stack sizes greater than a page in size. The #VC exception
handling was only mapping the first (bottom) page, resulting in an
SEV-ES guest failing to boot.

Make the #VC exception stacks part of the default exception stacks
storage and allocate them with a CONFIG_AMD_MEM_ENCRYPT=y .config. Map
them only when a SEV-ES guest has been detected.

Rip out the custom VC stacks mapping and storage code.

 [ bp: Steal and adapt Tom's commit message. ]

Fixes: 7fae4c24a2b8 ("x86: Increase exception stack sizes")
Signed-off-by: Borislav Petkov <bp@suse.de>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Link: https://lkml.kernel.org/r/YVt1IMjIs7pIZTRR@zn.tnic
arch/x86/include/asm/cpu_entry_area.h
arch/x86/kernel/sev.c
arch/x86/mm/cpu_entry_area.c

index 3d52b09..dd5ea1b 100644 (file)
 
 #ifdef CONFIG_X86_64
 
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+#define VC_EXCEPTION_STKSZ     EXCEPTION_STKSZ
+#else
+#define VC_EXCEPTION_STKSZ     0
+#endif
+
 /* Macro to enforce the same ordering and stack sizes */
 #define ESTACKS_MEMBERS(guardsize, optional_stack_size)                \
        char    DF_stack_guard[guardsize];                      \
@@ -28,7 +34,7 @@
 
 /* The exception stacks' physical storage. No guard pages required */
 struct exception_stacks {
-       ESTACKS_MEMBERS(0, 0)
+       ESTACKS_MEMBERS(0, VC_EXCEPTION_STKSZ)
 };
 
 /* The effective cpu entry area mapping with guard pages. */
index 53a6837..4d0d1c2 100644 (file)
@@ -46,16 +46,6 @@ static struct ghcb __initdata *boot_ghcb;
 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);
-
        /*
         * Reserve one page per CPU as backup storage for the unencrypted GHCB.
         * It is needed when an NMI happens while the #VC handler uses the real
@@ -99,27 +89,6 @@ DEFINE_STATIC_KEY_FALSE(sev_es_enable_key);
 /* Needed in vc_early_forward_exception */
 void do_early_exception(struct pt_regs *regs, int trapnr);
 
-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);
-}
-
 static __always_inline bool on_vc_stack(struct pt_regs *regs)
 {
        unsigned long sp = regs->sp;
@@ -787,7 +756,6 @@ void __init sev_es_init_vc_handling(void)
        for_each_possible_cpu(cpu) {
                alloc_runtime_data(cpu);
                init_ghcb(cpu);
-               setup_vc_stacks(cpu);
        }
 
        sev_es_setup_play_dead();
index f5e1e60..6c2f1b7 100644 (file)
@@ -110,6 +110,13 @@ static void __init percpu_setup_exception_stacks(unsigned int cpu)
        cea_map_stack(NMI);
        cea_map_stack(DB);
        cea_map_stack(MCE);
+
+       if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+               if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) {
+                       cea_map_stack(VC);
+                       cea_map_stack(VC2);
+               }
+       }
 }
 #else
 static inline void percpu_setup_exception_stacks(unsigned int cpu)