Merge tag 'v5.12-rc3' into x86/core
authorBorislav Petkov <bp@suse.de>
Mon, 15 Mar 2021 09:49:00 +0000 (10:49 +0100)
committerBorislav Petkov <bp@suse.de>
Mon, 15 Mar 2021 09:49:00 +0000 (10:49 +0100)
Pick up dependent SEV-ES urgent changes to base new work ontop.

Signed-off-by: Borislav Petkov <bp@suse.de>
19 files changed:
arch/x86/Kconfig
arch/x86/Makefile
arch/x86/entry/entry_32.S
arch/x86/include/asm/processor.h
arch/x86/include/asm/ptrace.h
arch/x86/include/asm/segment.h
arch/x86/include/asm/stackprotector.h
arch/x86/include/asm/suspend_32.h
arch/x86/kernel/asm-offsets_32.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/doublefault_32.c
arch/x86/kernel/head_32.S
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/tls.c
arch/x86/lib/insn-eval.c
arch/x86/platform/pvh/head.S
arch/x86/power/cpu.c
arch/x86/xen/enlighten_pv.c
scripts/gcc-x86_32-has-stack-protector.sh

index 2792879..10cc619 100644 (file)
@@ -360,10 +360,6 @@ config X86_64_SMP
        def_bool y
        depends on X86_64 && SMP
 
-config X86_32_LAZY_GS
-       def_bool y
-       depends on X86_32 && !STACKPROTECTOR
-
 config ARCH_SUPPORTS_UPROBES
        def_bool y
 
@@ -386,7 +382,8 @@ config CC_HAS_SANE_STACKPROTECTOR
        default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC))
        help
           We have to make sure stack protector is unconditionally disabled if
-          the compiler produces broken code.
+          the compiler produces broken code or if it does not let us control
+          the segment on 32-bit kernels.
 
 menu "Processor type and features"
 
index 2d6d5a2..952f534 100644 (file)
@@ -79,6 +79,14 @@ ifeq ($(CONFIG_X86_32),y)
 
         # temporary until string.h is fixed
         KBUILD_CFLAGS += -ffreestanding
+
+       ifeq ($(CONFIG_STACKPROTECTOR),y)
+               ifeq ($(CONFIG_SMP),y)
+                       KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard
+               else
+                       KBUILD_CFLAGS += -mstack-protector-guard=global
+               endif
+       endif
 else
         BITS := 64
         UTS_MACHINE := x86_64
index df8c017..bee9101 100644 (file)
@@ -20,7 +20,7 @@
  *     1C(%esp) - %ds
  *     20(%esp) - %es
  *     24(%esp) - %fs
- *     28(%esp) - %gs          saved iff !CONFIG_X86_32_LAZY_GS
+ *     28(%esp) - unused -- was %gs on old stackprotector kernels
  *     2C(%esp) - orig_eax
  *     30(%esp) - %eip
  *     34(%esp) - %cs
 
 #define PTI_SWITCH_MASK         (1 << PAGE_SHIFT)
 
-/*
- * User gs save/restore
- *
- * %gs is used for userland TLS and kernel only uses it for stack
- * canary which is required to be at %gs:20 by gcc.  Read the comment
- * at the top of stackprotector.h for more info.
- *
- * Local labels 98 and 99 are used.
- */
-#ifdef CONFIG_X86_32_LAZY_GS
-
- /* unfortunately push/pop can't be no-op */
-.macro PUSH_GS
-       pushl   $0
-.endm
-.macro POP_GS pop=0
-       addl    $(4 + \pop), %esp
-.endm
-.macro POP_GS_EX
-.endm
-
- /* all the rest are no-op */
-.macro PTGS_TO_GS
-.endm
-.macro PTGS_TO_GS_EX
-.endm
-.macro GS_TO_REG reg
-.endm
-.macro REG_TO_PTGS reg
-.endm
-.macro SET_KERNEL_GS reg
-.endm
-
-#else  /* CONFIG_X86_32_LAZY_GS */
-
-.macro PUSH_GS
-       pushl   %gs
-.endm
-
-.macro POP_GS pop=0
-98:    popl    %gs
-  .if \pop <> 0
-       add     $\pop, %esp
-  .endif
-.endm
-.macro POP_GS_EX
-.pushsection .fixup, "ax"
-99:    movl    $0, (%esp)
-       jmp     98b
-.popsection
-       _ASM_EXTABLE(98b, 99b)
-.endm
-
-.macro PTGS_TO_GS
-98:    mov     PT_GS(%esp), %gs
-.endm
-.macro PTGS_TO_GS_EX
-.pushsection .fixup, "ax"
-99:    movl    $0, PT_GS(%esp)
-       jmp     98b
-.popsection
-       _ASM_EXTABLE(98b, 99b)
-.endm
-
-.macro GS_TO_REG reg
-       movl    %gs, \reg
-.endm
-.macro REG_TO_PTGS reg
-       movl    \reg, PT_GS(%esp)
-.endm
-.macro SET_KERNEL_GS reg
-       movl    $(__KERNEL_STACK_CANARY), \reg
-       movl    \reg, %gs
-.endm
-
-#endif /* CONFIG_X86_32_LAZY_GS */
-
 /* Unconditionally switch to user cr3 */
 .macro SWITCH_TO_USER_CR3 scratch_reg:req
        ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
 .macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0 skip_gs=0 unwind_espfix=0
        cld
 .if \skip_gs == 0
-       PUSH_GS
+       pushl   $0
 .endif
        pushl   %fs
 
        movl    $(__USER_DS), %edx
        movl    %edx, %ds
        movl    %edx, %es
-.if \skip_gs == 0
-       SET_KERNEL_GS %edx
-.endif
        /* Switch to kernel stack if necessary */
 .if \switch_stacks > 0
        SWITCH_TO_KERNEL_STACK
 1:     popl    %ds
 2:     popl    %es
 3:     popl    %fs
-       POP_GS \pop
+       addl    $(4 + \pop), %esp       /* pop the unused "gs" slot */
        IRET_FRAME
 .pushsection .fixup, "ax"
 4:     movl    $0, (%esp)
        _ASM_EXTABLE(1b, 4b)
        _ASM_EXTABLE(2b, 5b)
        _ASM_EXTABLE(3b, 6b)
-       POP_GS_EX
 .endm
 
 .macro RESTORE_ALL_NMI cr3_reg:req pop=0
@@ -779,7 +698,7 @@ SYM_CODE_START(__switch_to_asm)
 
 #ifdef CONFIG_STACKPROTECTOR
        movl    TASK_stack_canary(%edx), %ebx
-       movl    %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset
+       movl    %ebx, PER_CPU_VAR(__stack_chk_guard)
 #endif
 
 #ifdef CONFIG_RETPOLINE
@@ -976,7 +895,6 @@ SYM_FUNC_START(entry_SYSENTER_32)
        movl    PT_EIP(%esp), %edx      /* pt_regs->ip */
        movl    PT_OLDESP(%esp), %ecx   /* pt_regs->sp */
 1:     mov     PT_FS(%esp), %fs
-       PTGS_TO_GS
 
        popl    %ebx                    /* pt_regs->bx */
        addl    $2*4, %esp              /* skip pt_regs->cx and pt_regs->dx */
@@ -1012,7 +930,6 @@ SYM_FUNC_START(entry_SYSENTER_32)
        jmp     1b
 .popsection
        _ASM_EXTABLE(1b, 2b)
-       PTGS_TO_GS_EX
 
 .Lsysenter_fix_flags:
        pushl   $X86_EFLAGS_FIXED
@@ -1154,11 +1071,7 @@ SYM_CODE_START_LOCAL_NOALIGN(handle_exception)
        SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1
        ENCODE_FRAME_POINTER
 
-       /* fixup %gs */
-       GS_TO_REG %ecx
        movl    PT_GS(%esp), %edi               # get the function address
-       REG_TO_PTGS %ecx
-       SET_KERNEL_GS %ecx
 
        /* fixup orig %eax */
        movl    PT_ORIG_EAX(%esp), %edx         # get the error code
index dc6d149..bac2a42 100644 (file)
@@ -439,6 +439,9 @@ struct fixed_percpu_data {
         * GCC hardcodes the stack canary as %gs:40.  Since the
         * irq_stack is the object at %gs:0, we reserve the bottom
         * 48 bytes of the irq stack for the canary.
+        *
+        * Once we are willing to require -mstack-protector-guard-symbol=
+        * support for x86_64 stackprotector, we can get rid of this.
         */
        char            gs_base[40];
        unsigned long   stack_canary;
@@ -460,17 +463,7 @@ extern asmlinkage void ignore_sysret(void);
 void current_save_fsgs(void);
 #else  /* X86_64 */
 #ifdef CONFIG_STACKPROTECTOR
-/*
- * Make sure stack canary segment base is cached-aligned:
- *   "For Intel Atom processors, avoid non zero segment base address
- *    that is not aligned to cache line boundary at all cost."
- * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
- */
-struct stack_canary {
-       char __pad[20];         /* canary at %gs:20 */
-       unsigned long canary;
-};
-DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
+DECLARE_PER_CPU(unsigned long, __stack_chk_guard);
 #endif
 DECLARE_PER_CPU(struct irq_stack *, hardirq_stack_ptr);
 DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);
index 409f661..b94f615 100644 (file)
@@ -37,7 +37,10 @@ struct pt_regs {
        unsigned short __esh;
        unsigned short fs;
        unsigned short __fsh;
-       /* On interrupt, gs and __gsh store the vector number. */
+       /*
+        * On interrupt, gs and __gsh store the vector number.  They never
+        * store gs any more.
+        */
        unsigned short gs;
        unsigned short __gsh;
        /* On interrupt, this is the error code. */
index 7fdd4fa..7204402 100644 (file)
@@ -95,7 +95,7 @@
  *
  *  26 - ESPFIX small SS
  *  27 - per-cpu                       [ offset to per-cpu data area ]
- *  28 - stack_canary-20               [ for stack protector ]         <=== cacheline #8
+ *  28 - unused
  *  29 - unused
  *  30 - unused
  *  31 - TSS for double fault handler
 
 #define GDT_ENTRY_ESPFIX_SS            26
 #define GDT_ENTRY_PERCPU               27
-#define GDT_ENTRY_STACK_CANARY         28
 
 #define GDT_ENTRY_DOUBLEFAULT_TSS      31
 
 # define __KERNEL_PERCPU               0
 #endif
 
-#ifdef CONFIG_STACKPROTECTOR
-# define __KERNEL_STACK_CANARY         (GDT_ENTRY_STACK_CANARY*8)
-#else
-# define __KERNEL_STACK_CANARY         0
-#endif
-
 #else /* 64-bit: */
 
 #include <asm/cache.h>
@@ -364,22 +357,15 @@ static inline void __loadsegment_fs(unsigned short value)
        asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
 
 /*
- * x86-32 user GS accessors:
+ * x86-32 user GS accessors.  This is ugly and could do with some cleaning up.
  */
 #ifdef CONFIG_X86_32
-# ifdef CONFIG_X86_32_LAZY_GS
-#  define get_user_gs(regs)            (u16)({ unsigned long v; savesegment(gs, v); v; })
-#  define set_user_gs(regs, v)         loadsegment(gs, (unsigned long)(v))
-#  define task_user_gs(tsk)            ((tsk)->thread.gs)
-#  define lazy_save_gs(v)              savesegment(gs, (v))
-#  define lazy_load_gs(v)              loadsegment(gs, (v))
-# else /* X86_32_LAZY_GS */
-#  define get_user_gs(regs)            (u16)((regs)->gs)
-#  define set_user_gs(regs, v)         do { (regs)->gs = (v); } while (0)
-#  define task_user_gs(tsk)            (task_pt_regs(tsk)->gs)
-#  define lazy_save_gs(v)              do { } while (0)
-#  define lazy_load_gs(v)              do { } while (0)
-# endif        /* X86_32_LAZY_GS */
+# define get_user_gs(regs)             (u16)({ unsigned long v; savesegment(gs, v); v; })
+# define set_user_gs(regs, v)          loadsegment(gs, (unsigned long)(v))
+# define task_user_gs(tsk)             ((tsk)->thread.gs)
+# define lazy_save_gs(v)               savesegment(gs, (v))
+# define lazy_load_gs(v)               loadsegment(gs, (v))
+# define load_gs_index(v)              loadsegment(gs, (v))
 #endif /* X86_32 */
 
 #endif /* !__ASSEMBLY__ */
index 7fb482f..b6ffe58 100644 (file)
@@ -5,30 +5,23 @@
  * Stack protector works by putting predefined pattern at the start of
  * the stack frame and verifying that it hasn't been overwritten when
  * returning from the function.  The pattern is called stack canary
- * and unfortunately gcc requires it to be at a fixed offset from %gs.
- * On x86_64, the offset is 40 bytes and on x86_32 20 bytes.  x86_64
- * and x86_32 use segment registers differently and thus handles this
- * requirement differently.
+ * and unfortunately gcc historically required it to be at a fixed offset
+ * from the percpu segment base.  On x86_64, the offset is 40 bytes.
  *
- * On x86_64, %gs is shared by percpu area and stack canary.  All
- * percpu symbols are zero based and %gs points to the base of percpu
- * area.  The first occupant of the percpu area is always
- * fixed_percpu_data which contains stack_canary at offset 40.  Userland
- * %gs is always saved and restored on kernel entry and exit using
- * swapgs, so stack protector doesn't add any complexity there.
+ * The same segment is shared by percpu area and stack canary.  On
+ * x86_64, percpu symbols are zero based and %gs (64-bit) points to the
+ * base of percpu area.  The first occupant of the percpu area is always
+ * fixed_percpu_data which contains stack_canary at the approproate
+ * offset.  On x86_32, the stack canary is just a regular percpu
+ * variable.
  *
- * On x86_32, it's slightly more complicated.  As in x86_64, %gs is
- * used for userland TLS.  Unfortunately, some processors are much
- * slower at loading segment registers with different value when
- * entering and leaving the kernel, so the kernel uses %fs for percpu
- * area and manages %gs lazily so that %gs is switched only when
- * necessary, usually during task switch.
+ * Putting percpu data in %fs on 32-bit is a minor optimization compared to
+ * using %gs.  Since 32-bit userspace normally has %fs == 0, we are likely
+ * to load 0 into %fs on exit to usermode, whereas with percpu data in
+ * %gs, we are likely to load a non-null %gs on return to user mode.
  *
- * As gcc requires the stack canary at %gs:20, %gs can't be managed
- * lazily if stack protector is enabled, so the kernel saves and
- * restores userland %gs on kernel entry and exit.  This behavior is
- * controlled by CONFIG_X86_32_LAZY_GS and accessors are defined in
- * system.h to hide the details.
+ * Once we are willing to require GCC 8.1 or better for 64-bit stackprotector
+ * support, we can remove some of this complexity.
  */
 
 #ifndef _ASM_STACKPROTECTOR_H
 #include <linux/random.h>
 #include <linux/sched.h>
 
-/*
- * 24 byte read-only segment initializer for stack canary.  Linker
- * can't handle the address bit shifting.  Address will be set in
- * head_32 for boot CPU and setup_per_cpu_areas() for others.
- */
-#define GDT_STACK_CANARY_INIT                                          \
-       [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
-
 /*
  * Initialize the stackprotector canary value.
  *
@@ -86,7 +71,7 @@ static __always_inline void boot_init_stack_canary(void)
 #ifdef CONFIG_X86_64
        this_cpu_write(fixed_percpu_data.stack_canary, canary);
 #else
-       this_cpu_write(stack_canary.canary, canary);
+       this_cpu_write(__stack_chk_guard, canary);
 #endif
 }
 
@@ -95,48 +80,16 @@ static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
 #ifdef CONFIG_X86_64
        per_cpu(fixed_percpu_data.stack_canary, cpu) = idle->stack_canary;
 #else
-       per_cpu(stack_canary.canary, cpu) = idle->stack_canary;
-#endif
-}
-
-static inline void setup_stack_canary_segment(int cpu)
-{
-#ifdef CONFIG_X86_32
-       unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-       struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
-       struct desc_struct desc;
-
-       desc = gdt_table[GDT_ENTRY_STACK_CANARY];
-       set_desc_base(&desc, canary);
-       write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
-#endif
-}
-
-static inline void load_stack_canary_segment(void)
-{
-#ifdef CONFIG_X86_32
-       asm("mov %0, %%gs" : : "r" (__KERNEL_STACK_CANARY) : "memory");
+       per_cpu(__stack_chk_guard, cpu) = idle->stack_canary;
 #endif
 }
 
 #else  /* STACKPROTECTOR */
 
-#define GDT_STACK_CANARY_INIT
-
 /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */
 
-static inline void setup_stack_canary_segment(int cpu)
-{ }
-
 static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
 { }
 
-static inline void load_stack_canary_segment(void)
-{
-#ifdef CONFIG_X86_32
-       asm volatile ("mov %0, %%gs" : : "r" (0));
-#endif
-}
-
 #endif /* STACKPROTECTOR */
 #endif /* _ASM_STACKPROTECTOR_H */
index fdbd9d7..7b132d0 100644 (file)
 /* image of the saved processor state */
 struct saved_context {
        /*
-        * On x86_32, all segment registers, with the possible exception of
-        * gs, are saved at kernel entry in pt_regs.
+        * On x86_32, all segment registers except gs are saved at kernel
+        * entry in pt_regs.
         */
-#ifdef CONFIG_X86_32_LAZY_GS
        u16 gs;
-#endif
        unsigned long cr0, cr2, cr3, cr4;
        u64 misc_enable;
        bool misc_enable_saved;
index 6e043f2..2b411cd 100644 (file)
@@ -53,11 +53,6 @@ void foo(void)
               offsetof(struct cpu_entry_area, tss.x86_tss.sp1) -
               offsetofend(struct cpu_entry_area, entry_stack_page.stack));
 
-#ifdef CONFIG_STACKPROTECTOR
-       BLANK();
-       OFFSET(stack_canary_offset, stack_canary, canary);
-#endif
-
        BLANK();
        DEFINE(EFI_svam, offsetof(efi_runtime_services_t, set_virtual_address_map));
 }
index ab640ab..23cb9d6 100644 (file)
@@ -161,7 +161,6 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 
        [GDT_ENTRY_ESPFIX_SS]           = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
        [GDT_ENTRY_PERCPU]              = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
-       GDT_STACK_CANARY_INIT
 #endif
 } };
 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
@@ -599,7 +598,6 @@ void load_percpu_segment(int cpu)
        __loadsegment_simple(gs, 0);
        wrmsrl(MSR_GS_BASE, cpu_kernelmode_gs_base(cpu));
 #endif
-       load_stack_canary_segment();
 }
 
 #ifdef CONFIG_X86_32
@@ -1796,7 +1794,8 @@ DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) =
 EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack);
 
 #ifdef CONFIG_STACKPROTECTOR
-DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
+DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
+EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
 #endif
 
 #endif /* CONFIG_X86_64 */
index 759d392..d1d49e3 100644 (file)
@@ -100,9 +100,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack) = {
                .ss             = __KERNEL_DS,
                .ds             = __USER_DS,
                .fs             = __KERNEL_PERCPU,
-#ifndef CONFIG_X86_32_LAZY_GS
-               .gs             = __KERNEL_STACK_CANARY,
-#endif
+               .gs             = 0,
 
                .__cr3          = __pa_nodebug(swapper_pg_dir),
        },
index 7ed84c2..67f5904 100644 (file)
@@ -318,8 +318,8 @@ SYM_FUNC_START(startup_32_smp)
        movl $(__KERNEL_PERCPU), %eax
        movl %eax,%fs                   # set this cpu's percpu
 
-       movl $(__KERNEL_STACK_CANARY),%eax
-       movl %eax,%gs
+       xorl %eax,%eax
+       movl %eax,%gs                   # clear possible garbage in %gs
 
        xorl %eax,%eax                  # Clear LDT
        lldt %ax
@@ -339,20 +339,6 @@ SYM_FUNC_END(startup_32_smp)
  */
 __INIT
 setup_once:
-#ifdef CONFIG_STACKPROTECTOR
-       /*
-        * Configure the stack canary. The linker can't handle this by
-        * relocation.  Manually set base address in stack canary
-        * segment descriptor.
-        */
-       movl $gdt_page,%eax
-       movl $stack_canary,%ecx
-       movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
-       shrl $16, %ecx
-       movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
-       movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
-#endif
-
        andl $0,setup_once_ref  /* Once is enough, thanks */
        ret
 
index fd945ce..0941d2f 100644 (file)
@@ -224,7 +224,6 @@ void __init setup_per_cpu_areas(void)
                per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
                per_cpu(cpu_number, cpu) = cpu;
                setup_percpu_segment(cpu);
-               setup_stack_canary_segment(cpu);
                /*
                 * Copy data used in early init routines from the
                 * initial arrays to the per cpu data areas.  These
index 64a496a..3c883e0 100644 (file)
@@ -164,17 +164,11 @@ int do_set_thread_area(struct task_struct *p, int idx,
                savesegment(fs, sel);
                if (sel == modified_sel)
                        loadsegment(fs, sel);
-
-               savesegment(gs, sel);
-               if (sel == modified_sel)
-                       load_gs_index(sel);
 #endif
 
-#ifdef CONFIG_X86_32_LAZY_GS
                savesegment(gs, sel);
                if (sel == modified_sel)
-                       loadsegment(gs, sel);
-#endif
+                       load_gs_index(sel);
        } else {
 #ifdef CONFIG_X86_64
                if (p->thread.fsindex == modified_sel)
index bb0b3fe..8cec461 100644 (file)
@@ -404,10 +404,6 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
        case INAT_SEG_REG_FS:
                return (unsigned short)(regs->fs & 0xffff);
        case INAT_SEG_REG_GS:
-               /*
-                * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS.
-                * The macro below takes care of both cases.
-                */
                return get_user_gs(regs);
        case INAT_SEG_REG_IGNORE:
        default:
index d2ccadc..b049070 100644 (file)
 
 #define PVH_GDT_ENTRY_CS       1
 #define PVH_GDT_ENTRY_DS       2
-#define PVH_GDT_ENTRY_CANARY   3
 #define PVH_CS_SEL             (PVH_GDT_ENTRY_CS * 8)
 #define PVH_DS_SEL             (PVH_GDT_ENTRY_DS * 8)
-#define PVH_CANARY_SEL         (PVH_GDT_ENTRY_CANARY * 8)
 
 SYM_CODE_START_LOCAL(pvh_start_xen)
        cld
@@ -111,17 +109,6 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
 
 #else /* CONFIG_X86_64 */
 
-       /* Set base address in stack canary descriptor. */
-       movl $_pa(gdt_start),%eax
-       movl $_pa(canary),%ecx
-       movw %cx, (PVH_GDT_ENTRY_CANARY * 8) + 2(%eax)
-       shrl $16, %ecx
-       movb %cl, (PVH_GDT_ENTRY_CANARY * 8) + 4(%eax)
-       movb %ch, (PVH_GDT_ENTRY_CANARY * 8) + 7(%eax)
-
-       mov $PVH_CANARY_SEL,%eax
-       mov %eax,%gs
-
        call mk_early_pgtbl_32
 
        mov $_pa(initial_page_table), %eax
@@ -165,7 +152,6 @@ SYM_DATA_START_LOCAL(gdt_start)
        .quad GDT_ENTRY(0xc09a, 0, 0xfffff) /* PVH_CS_SEL */
 #endif
        .quad GDT_ENTRY(0xc092, 0, 0xfffff) /* PVH_DS_SEL */
-       .quad GDT_ENTRY(0x4090, 0, 0x18)    /* PVH_CANARY_SEL */
 SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end)
 
        .balign 16
index db1378c..ef4329d 100644 (file)
@@ -99,11 +99,8 @@ static void __save_processor_state(struct saved_context *ctxt)
        /*
         * segment registers
         */
-#ifdef CONFIG_X86_32_LAZY_GS
        savesegment(gs, ctxt->gs);
-#endif
 #ifdef CONFIG_X86_64
-       savesegment(gs, ctxt->gs);
        savesegment(fs, ctxt->fs);
        savesegment(ds, ctxt->ds);
        savesegment(es, ctxt->es);
@@ -232,7 +229,6 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
        wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base);
 #else
        loadsegment(fs, __KERNEL_PERCPU);
-       loadsegment(gs, __KERNEL_STACK_CANARY);
 #endif
 
        /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */
@@ -255,7 +251,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
         */
        wrmsrl(MSR_FS_BASE, ctxt->fs_base);
        wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base);
-#elif defined(CONFIG_X86_32_LAZY_GS)
+#else
        loadsegment(gs, ctxt->gs);
 #endif
 
index dc0a337..33e797b 100644 (file)
@@ -1204,7 +1204,6 @@ static void __init xen_setup_gdt(int cpu)
        pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot;
        pv_ops.cpu.load_gdt = xen_load_gdt_boot;
 
-       setup_stack_canary_segment(cpu);
        switch_to_new_gdt(cpu);
 
        pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry;
index f5c1194..825c75c 100755 (executable)
@@ -1,4 +1,8 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+# This requires GCC 8.1 or better.  Specifically, we require
+# -mstack-protector-guard-reg, added by
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708
+
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs"