public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] x86-32: Clean up GS segment handling
@ 2022-03-25 15:39 Brian Gerst
  2022-03-25 15:39 ` [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS Brian Gerst
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Brian Gerst @ 2022-03-25 15:39 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Brian Gerst

Since commit 3fb0fdb3bbe ("Make the canary into a regular percpu
variable"), the GS segment is no longer switched on kernel entry for
32-bit kernels.  Clean up the remaining code that handled lazy GS
switching.

Brian Gerst (4):
  x86-32: Simplify ELF_CORE_COPY_REGS
  ELF: Remove elf_core_copy_kernel_regs()
  x86-32: Remove lazy GS macros
  x86: Merge load_gs_index()

 arch/powerpc/kernel/fadump.c               |  2 +-
 arch/powerpc/platforms/powernv/opal-core.c |  2 +-
 arch/x86/include/asm/elf.h                 | 15 ++-------------
 arch/x86/include/asm/mmu_context.h         |  2 +-
 arch/x86/include/asm/segment.h             | 12 ------------
 arch/x86/include/asm/special_insns.h       |  7 ++++---
 arch/x86/kernel/process.c                  |  5 +----
 arch/x86/kernel/process_32.c               | 11 ++++-------
 arch/x86/kernel/ptrace.c                   |  6 +++---
 arch/x86/kernel/signal.c                   |  8 +++++---
 arch/x86/kernel/vm86_32.c                  |  4 ++--
 arch/x86/lib/insn-eval.c                   |  5 +++--
 arch/x86/math-emu/get_address.c            |  2 +-
 include/linux/elfcore.h                    |  9 ---------
 kernel/kexec_core.c                        |  2 +-
 15 files changed, 29 insertions(+), 63 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
@ 2022-03-25 15:39 ` Brian Gerst
  2022-04-15  9:42   ` [tip: x86/core] x86/32: " tip-bot2 for Brian Gerst
  2022-03-25 15:39 ` [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs() Brian Gerst
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Brian Gerst @ 2022-03-25 15:39 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Brian Gerst

GS is now always a user segment, so there is no difference between
user and kernel registers.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
 arch/x86/include/asm/elf.h | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 29fea180a665..cb0ff1055ab1 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -116,7 +116,7 @@ extern unsigned int vdso32_enabled;
  * now struct_user_regs, they are different)
  */
 
-#define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs)	\
+#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
 do {						\
 	pr_reg[0] = regs->bx;			\
 	pr_reg[1] = regs->cx;			\
@@ -128,6 +128,7 @@ do {						\
 	pr_reg[7] = regs->ds;			\
 	pr_reg[8] = regs->es;			\
 	pr_reg[9] = regs->fs;			\
+	savesegment(gs, pr_reg[10]);		\
 	pr_reg[11] = regs->orig_ax;		\
 	pr_reg[12] = regs->ip;			\
 	pr_reg[13] = regs->cs;			\
@@ -136,18 +137,6 @@ do {						\
 	pr_reg[16] = regs->ss;			\
 } while (0);
 
-#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
-do {						\
-	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
-	pr_reg[10] = get_user_gs(regs);		\
-} while (0);
-
-#define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs)	\
-do {						\
-	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
-	savesegment(gs, pr_reg[10]);		\
-} while (0);
-
 #define ELF_PLATFORM	(utsname()->machine)
 #define set_personality_64bit()	do { } while (0)
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs()
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
  2022-03-25 15:39 ` [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS Brian Gerst
@ 2022-03-25 15:39 ` Brian Gerst
  2022-04-13 11:41   ` Borislav Petkov
  2022-04-15  9:42   ` [tip: x86/core] " tip-bot2 for Brian Gerst
  2022-03-25 15:39 ` [PATCH 3/4] x86-32: Remove lazy GS macros Brian Gerst
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Brian Gerst @ 2022-03-25 15:39 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Brian Gerst

x86-32 was the last architecture that implemented separate user and
kernel registers.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
 arch/powerpc/kernel/fadump.c               | 2 +-
 arch/powerpc/platforms/powernv/opal-core.c | 2 +-
 include/linux/elfcore.h                    | 9 ---------
 kernel/kexec_core.c                        | 2 +-
 4 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 4fdb7c77fda1..c0cf17196d6c 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -752,7 +752,7 @@ u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
 	 * FIXME: How do i get PID? Do I really need it?
 	 * prstatus.pr_pid = ????
 	 */
-	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
+	elf_core_copy_regs(&prstatus.pr_reg, regs);
 	buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
 			      &prstatus, sizeof(prstatus));
 	return buf;
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index 0331f1973f0e..dd6e99edff76 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
 			  struct pt_regs *regs)
 {
 	memset(prstatus, 0, sizeof(struct elf_prstatus));
-	elf_core_copy_kernel_regs(&(prstatus->pr_reg), regs);
+	elf_core_copy_regs(&(prstatus->pr_reg), regs);
 
 	/*
 	 * Overload PID with PIR value.
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index f8e206e82476..346a8b56cdc8 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -84,15 +84,6 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
 #endif
 }
 
-static inline void elf_core_copy_kernel_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
-{
-#ifdef ELF_CORE_COPY_KERNEL_REGS
-	ELF_CORE_COPY_KERNEL_REGS((*elfregs), regs);
-#else
-	elf_core_copy_regs(elfregs, regs);
-#endif
-}
-
 static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
 {
 #if defined (ELF_CORE_COPY_TASK_REGS)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 68480f731192..be4b54c2c615 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1078,7 +1078,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
 		return;
 	memset(&prstatus, 0, sizeof(prstatus));
 	prstatus.common.pr_pid = current->pid;
-	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
+	elf_core_copy_regs(&prstatus.pr_reg, regs);
 	buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
 			      &prstatus, sizeof(prstatus));
 	final_note(buf);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/4] x86-32: Remove lazy GS macros
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
  2022-03-25 15:39 ` [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS Brian Gerst
  2022-03-25 15:39 ` [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs() Brian Gerst
@ 2022-03-25 15:39 ` Brian Gerst
  2022-04-15  9:42   ` [tip: x86/core] x86/32: " tip-bot2 for Brian Gerst
  2022-03-25 15:39 ` [PATCH 4/4] x86: Merge load_gs_index() Brian Gerst
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Brian Gerst @ 2022-03-25 15:39 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Brian Gerst

GS is always a user segment now.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
 arch/x86/include/asm/mmu_context.h |  2 +-
 arch/x86/include/asm/segment.h     |  5 -----
 arch/x86/kernel/process.c          |  5 +----
 arch/x86/kernel/process_32.c       | 11 ++++-------
 arch/x86/kernel/ptrace.c           |  6 +++---
 arch/x86/kernel/signal.c           |  8 +++++---
 arch/x86/kernel/vm86_32.c          |  4 ++--
 arch/x86/lib/insn-eval.c           |  5 +++--
 arch/x86/math-emu/get_address.c    |  2 +-
 9 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 27516046117a..b8d40ddeab00 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -141,7 +141,7 @@ do {						\
 #ifdef CONFIG_X86_32
 #define deactivate_mm(tsk, mm)			\
 do {						\
-	lazy_load_gs(0);			\
+	loadsegment(gs, 0);			\
 } while (0)
 #else
 #define deactivate_mm(tsk, mm)			\
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 656ed6531d03..617b3663e4dd 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -354,11 +354,6 @@ static inline void __loadsegment_fs(unsigned short value)
  * x86-32 user GS accessors.  This is ugly and could do with some cleaning up.
  */
 #ifdef CONFIG_X86_32
-# 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 */
 
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index b370767f5b19..96a9885b9c3a 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -160,6 +160,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
 	savesegment(ds, p->thread.ds);
 #else
 	p->thread.sp0 = (unsigned long) (childregs + 1);
+	savesegment(gs, p->thread.gs);
 	/*
 	 * Clear all status flags including IF and set fixed bit. 64bit
 	 * does not have this initialization as the frame does not contain
@@ -191,10 +192,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
 	if (sp)
 		childregs->sp = sp;
 
-#ifdef CONFIG_X86_32
-	task_user_gs(p) = get_user_gs(current_pt_regs());
-#endif
-
 	if (unlikely(p->flags & PF_IO_WORKER)) {
 		/*
 		 * An IO thread is a user space thread, but it doesn't
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 26edb1cd07a4..877358f3dba7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -63,10 +63,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned short gs;
 
-	if (user_mode(regs))
-		gs = get_user_gs(regs);
-	else
-		savesegment(gs, gs);
+	savesegment(gs, gs);
 
 	show_ip(regs, log_lvl);
 
@@ -114,7 +111,7 @@ void release_thread(struct task_struct *dead_task)
 void
 start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 {
-	set_user_gs(regs, 0);
+	loadsegment(gs, 0);
 	regs->fs		= 0;
 	regs->ds		= __USER_DS;
 	regs->es		= __USER_DS;
@@ -177,7 +174,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	 * used %fs or %gs (it does not today), or if the kernel is
 	 * running inside of a hypervisor layer.
 	 */
-	lazy_save_gs(prev->gs);
+	savesegment(gs, prev->gs);
 
 	/*
 	 * Load the per-thread Thread-Local Storage descriptor.
@@ -208,7 +205,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	 * Restore %gs if needed (which is common)
 	 */
 	if (prev->gs | next->gs)
-		lazy_load_gs(next->gs);
+		loadsegment(gs, next->gs);
 
 	this_cpu_write(current_task, next_p);
 
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 8d2f2f995539..a2336db1aac1 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -171,9 +171,9 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
 		retval = *pt_regs_access(task_pt_regs(task), offset);
 	else {
 		if (task == current)
-			retval = get_user_gs(task_pt_regs(task));
+			savesegment(gs, retval);
 		else
-			retval = task_user_gs(task);
+			retval = task->thread.gs;
 	}
 	return retval;
 }
@@ -211,7 +211,7 @@ static int set_segment_reg(struct task_struct *task,
 		break;
 
 	case offsetof(struct user_regs_struct, gs):
-		task_user_gs(task) = value;
+		task->thread.gs = value;
 	}
 
 	return 0;
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index ec71e06ae364..add4bb6f9d43 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -94,7 +94,7 @@ static bool restore_sigcontext(struct pt_regs *regs,
 		return false;
 
 #ifdef CONFIG_X86_32
-	set_user_gs(regs, sc.gs);
+	loadsegment(gs, sc.gs);
 	regs->fs = sc.fs;
 	regs->es = sc.es;
 	regs->ds = sc.ds;
@@ -147,8 +147,10 @@ __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
 		     struct pt_regs *regs, unsigned long mask)
 {
 #ifdef CONFIG_X86_32
-	unsafe_put_user(get_user_gs(regs),
-				  (unsigned int __user *)&sc->gs, Efault);
+	unsigned int gs;
+	savesegment(gs, gs);
+
+	unsafe_put_user(gs,	  (unsigned int __user *)&sc->gs, Efault);
 	unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault);
 	unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault);
 	unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault);
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index c21bcd668284..e9e803a4d44c 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -151,7 +151,7 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)
 
 	memcpy(&regs->pt, &vm86->regs32, sizeof(struct pt_regs));
 
-	lazy_load_gs(vm86->regs32.gs);
+	loadsegment(gs, vm86->regs32.gs);
 
 	regs->pt.ax = retval;
 	return;
@@ -325,7 +325,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
  * Save old state
  */
 	vm86->saved_sp0 = tsk->thread.sp0;
-	lazy_save_gs(vm86->regs32.gs);
+	savesegment(gs, vm86->regs32.gs);
 
 	/* make room for real-mode segments */
 	preempt_disable();
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index b781d324211b..21104c41cba0 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -342,9 +342,9 @@ static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
  */
 static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
 {
-#ifdef CONFIG_X86_64
 	unsigned short sel;
 
+#ifdef CONFIG_X86_64
 	switch (seg_reg_idx) {
 	case INAT_SEG_REG_IGNORE:
 		return 0;
@@ -402,7 +402,8 @@ 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:
-		return get_user_gs(regs);
+		savesegment(gs, sel);
+		return sel;
 	case INAT_SEG_REG_IGNORE:
 	default:
 		return -EINVAL;
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index b82ca14ba718..4a9fd9029a53 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -153,7 +153,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
 	switch (segment) {
 	case PREFIX_GS_ - 1:
 		/* user gs handling can be lazy, use special accessors */
-		addr->selector = get_user_gs(FPU_info->regs);
+		savesegment(gs, addr->selector);
 		break;
 	default:
 		addr->selector = PM_REG_(segment);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/4] x86: Merge load_gs_index()
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
                   ` (2 preceding siblings ...)
  2022-03-25 15:39 ` [PATCH 3/4] x86-32: Remove lazy GS macros Brian Gerst
@ 2022-03-25 15:39 ` Brian Gerst
  2022-04-15  9:42   ` [tip: x86/core] x86/asm: " tip-bot2 for Brian Gerst
  2022-03-25 15:45 ` [PATCH 0/4] x86-32: Clean up GS segment handling Andy Lutomirski
  2022-04-05 16:12 ` Thomas Gleixner
  5 siblings, 1 reply; 13+ messages in thread
From: Brian Gerst @ 2022-03-25 15:39 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Brian Gerst

Merge the 32- and 64-bit implementations of load_gs_index().

Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
 arch/x86/include/asm/segment.h       | 7 -------
 arch/x86/include/asm/special_insns.h | 7 ++++---
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 617b3663e4dd..2e7890dd58a4 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -350,13 +350,6 @@ static inline void __loadsegment_fs(unsigned short value)
 #define savesegment(seg, value)				\
 	asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
 
-/*
- * x86-32 user GS accessors.  This is ugly and could do with some cleaning up.
- */
-#ifdef CONFIG_X86_32
-# define load_gs_index(v)		loadsegment(gs, (v))
-#endif	/* X86_32 */
-
 #endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index 68c257a3de0d..45b18eb94fa1 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -184,14 +184,15 @@ static inline void wbinvd(void)
 	native_wbinvd();
 }
 
-#ifdef CONFIG_X86_64
 
 static inline void load_gs_index(unsigned int selector)
 {
+#ifdef CONFIG_X86_64
 	native_load_gs_index(selector);
-}
-
+#else
+	loadsegment(gs, selector);
 #endif
+}
 
 #endif /* CONFIG_PARAVIRT_XXL */
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/4] x86-32: Clean up GS segment handling
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
                   ` (3 preceding siblings ...)
  2022-03-25 15:39 ` [PATCH 4/4] x86: Merge load_gs_index() Brian Gerst
@ 2022-03-25 15:45 ` Andy Lutomirski
  2022-04-05 16:12 ` Thomas Gleixner
  5 siblings, 0 replies; 13+ messages in thread
From: Andy Lutomirski @ 2022-03-25 15:45 UTC (permalink / raw)
  To: Brian Gerst, linux-kernel, x86
  Cc: Borislav Petkov, Thomas Gleixner, H . Peter Anvin, Peter Zijlstra

On 3/25/22 08:39, Brian Gerst wrote:
> Since commit 3fb0fdb3bbe ("Make the canary into a regular percpu
> variable"), the GS segment is no longer switched on kernel entry for
> 32-bit kernels.  Clean up the remaining code that handled lazy GS
> switching.
> 

Acked-by: Andy Lutomirski <luto@kernel.org>

Thanks!

> Brian Gerst (4):
>    x86-32: Simplify ELF_CORE_COPY_REGS
>    ELF: Remove elf_core_copy_kernel_regs()
>    x86-32: Remove lazy GS macros
>    x86: Merge load_gs_index()
> 
>   arch/powerpc/kernel/fadump.c               |  2 +-
>   arch/powerpc/platforms/powernv/opal-core.c |  2 +-
>   arch/x86/include/asm/elf.h                 | 15 ++-------------
>   arch/x86/include/asm/mmu_context.h         |  2 +-
>   arch/x86/include/asm/segment.h             | 12 ------------
>   arch/x86/include/asm/special_insns.h       |  7 ++++---
>   arch/x86/kernel/process.c                  |  5 +----
>   arch/x86/kernel/process_32.c               | 11 ++++-------
>   arch/x86/kernel/ptrace.c                   |  6 +++---
>   arch/x86/kernel/signal.c                   |  8 +++++---
>   arch/x86/kernel/vm86_32.c                  |  4 ++--
>   arch/x86/lib/insn-eval.c                   |  5 +++--
>   arch/x86/math-emu/get_address.c            |  2 +-
>   include/linux/elfcore.h                    |  9 ---------
>   kernel/kexec_core.c                        |  2 +-
>   15 files changed, 29 insertions(+), 63 deletions(-)
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/4] x86-32: Clean up GS segment handling
  2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
                   ` (4 preceding siblings ...)
  2022-03-25 15:45 ` [PATCH 0/4] x86-32: Clean up GS segment handling Andy Lutomirski
@ 2022-04-05 16:12 ` Thomas Gleixner
  5 siblings, 0 replies; 13+ messages in thread
From: Thomas Gleixner @ 2022-04-05 16:12 UTC (permalink / raw)
  To: Brian Gerst, linux-kernel, x86
  Cc: Andy Lutomirski, Borislav Petkov, H . Peter Anvin, Peter Zijlstra,
	Brian Gerst

On Fri, Mar 25 2022 at 11:39, Brian Gerst wrote:
> Since commit 3fb0fdb3bbe ("Make the canary into a regular percpu
> variable"), the GS segment is no longer switched on kernel entry for
> 32-bit kernels.  Clean up the remaining code that handled lazy GS
> switching.

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs()
  2022-03-25 15:39 ` [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs() Brian Gerst
@ 2022-04-13 11:41   ` Borislav Petkov
  2022-04-13 12:31     ` Michael Ellerman
  2022-04-15  9:42   ` [tip: x86/core] " tip-bot2 for Brian Gerst
  1 sibling, 1 reply; 13+ messages in thread
From: Borislav Petkov @ 2022-04-13 11:41 UTC (permalink / raw)
  To: Brian Gerst, linuxppc-dev
  Cc: linux-kernel, x86, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra

+ PPC ML as an FYI that this change will come through tip.

On Fri, Mar 25, 2022 at 11:39:51AM -0400, Brian Gerst wrote:
> x86-32 was the last architecture that implemented separate user and
> kernel registers.
> 
> Signed-off-by: Brian Gerst <brgerst@gmail.com>
> ---
>  arch/powerpc/kernel/fadump.c               | 2 +-
>  arch/powerpc/platforms/powernv/opal-core.c | 2 +-
>  include/linux/elfcore.h                    | 9 ---------
>  kernel/kexec_core.c                        | 2 +-
>  4 files changed, 3 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 4fdb7c77fda1..c0cf17196d6c 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -752,7 +752,7 @@ u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
>  	 * FIXME: How do i get PID? Do I really need it?
>  	 * prstatus.pr_pid = ????
>  	 */
> -	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
> +	elf_core_copy_regs(&prstatus.pr_reg, regs);
>  	buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
>  			      &prstatus, sizeof(prstatus));
>  	return buf;
> diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
> index 0331f1973f0e..dd6e99edff76 100644
> --- a/arch/powerpc/platforms/powernv/opal-core.c
> +++ b/arch/powerpc/platforms/powernv/opal-core.c
> @@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
>  			  struct pt_regs *regs)
>  {
>  	memset(prstatus, 0, sizeof(struct elf_prstatus));
> -	elf_core_copy_kernel_regs(&(prstatus->pr_reg), regs);
> +	elf_core_copy_regs(&(prstatus->pr_reg), regs);
>  
>  	/*
>  	 * Overload PID with PIR value.
> diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
> index f8e206e82476..346a8b56cdc8 100644
> --- a/include/linux/elfcore.h
> +++ b/include/linux/elfcore.h
> @@ -84,15 +84,6 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
>  #endif
>  }
>  
> -static inline void elf_core_copy_kernel_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
> -{
> -#ifdef ELF_CORE_COPY_KERNEL_REGS
> -	ELF_CORE_COPY_KERNEL_REGS((*elfregs), regs);
> -#else
> -	elf_core_copy_regs(elfregs, regs);
> -#endif
> -}
> -
>  static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
>  {
>  #if defined (ELF_CORE_COPY_TASK_REGS)
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index 68480f731192..be4b54c2c615 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -1078,7 +1078,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
>  		return;
>  	memset(&prstatus, 0, sizeof(prstatus));
>  	prstatus.common.pr_pid = current->pid;
> -	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
> +	elf_core_copy_regs(&prstatus.pr_reg, regs);
>  	buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
>  			      &prstatus, sizeof(prstatus));
>  	final_note(buf);
> -- 
> 2.35.1
> 

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs()
  2022-04-13 11:41   ` Borislav Petkov
@ 2022-04-13 12:31     ` Michael Ellerman
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2022-04-13 12:31 UTC (permalink / raw)
  To: Borislav Petkov, Brian Gerst, linuxppc-dev
  Cc: linux-kernel, x86, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra

Borislav Petkov <bp@alien8.de> writes:
> + PPC ML as an FYI that this change will come through tip.

Ack.

cheers

> On Fri, Mar 25, 2022 at 11:39:51AM -0400, Brian Gerst wrote:
>> x86-32 was the last architecture that implemented separate user and
>> kernel registers.
>> 
>> Signed-off-by: Brian Gerst <brgerst@gmail.com>
>> ---
>>  arch/powerpc/kernel/fadump.c               | 2 +-
>>  arch/powerpc/platforms/powernv/opal-core.c | 2 +-
>>  include/linux/elfcore.h                    | 9 ---------
>>  kernel/kexec_core.c                        | 2 +-
>>  4 files changed, 3 insertions(+), 12 deletions(-)
>> 
>> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
>> index 4fdb7c77fda1..c0cf17196d6c 100644
>> --- a/arch/powerpc/kernel/fadump.c
>> +++ b/arch/powerpc/kernel/fadump.c
>> @@ -752,7 +752,7 @@ u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
>>  	 * FIXME: How do i get PID? Do I really need it?
>>  	 * prstatus.pr_pid = ????
>>  	 */
>> -	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
>> +	elf_core_copy_regs(&prstatus.pr_reg, regs);
>>  	buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
>>  			      &prstatus, sizeof(prstatus));
>>  	return buf;
>> diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
>> index 0331f1973f0e..dd6e99edff76 100644
>> --- a/arch/powerpc/platforms/powernv/opal-core.c
>> +++ b/arch/powerpc/platforms/powernv/opal-core.c
>> @@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
>>  			  struct pt_regs *regs)
>>  {
>>  	memset(prstatus, 0, sizeof(struct elf_prstatus));
>> -	elf_core_copy_kernel_regs(&(prstatus->pr_reg), regs);
>> +	elf_core_copy_regs(&(prstatus->pr_reg), regs);
>>  
>>  	/*
>>  	 * Overload PID with PIR value.
>> diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
>> index f8e206e82476..346a8b56cdc8 100644
>> --- a/include/linux/elfcore.h
>> +++ b/include/linux/elfcore.h
>> @@ -84,15 +84,6 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
>>  #endif
>>  }
>>  
>> -static inline void elf_core_copy_kernel_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
>> -{
>> -#ifdef ELF_CORE_COPY_KERNEL_REGS
>> -	ELF_CORE_COPY_KERNEL_REGS((*elfregs), regs);
>> -#else
>> -	elf_core_copy_regs(elfregs, regs);
>> -#endif
>> -}
>> -
>>  static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
>>  {
>>  #if defined (ELF_CORE_COPY_TASK_REGS)
>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>> index 68480f731192..be4b54c2c615 100644
>> --- a/kernel/kexec_core.c
>> +++ b/kernel/kexec_core.c
>> @@ -1078,7 +1078,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
>>  		return;
>>  	memset(&prstatus, 0, sizeof(prstatus));
>>  	prstatus.common.pr_pid = current->pid;
>> -	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
>> +	elf_core_copy_regs(&prstatus.pr_reg, regs);
>>  	buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
>>  			      &prstatus, sizeof(prstatus));
>>  	final_note(buf);
>> -- 
>> 2.35.1
>> 
>
> -- 
> Regards/Gruss,
>     Boris.
>
> https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip: x86/core] x86/asm: Merge load_gs_index()
  2022-03-25 15:39 ` [PATCH 4/4] x86: Merge load_gs_index() Brian Gerst
@ 2022-04-15  9:42   ` tip-bot2 for Brian Gerst
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Brian Gerst @ 2022-04-15  9:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brian Gerst, Borislav Petkov, Thomas Gleixner, Andy Lutomirski,
	x86, linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     203d8919a9eda5d1bc68ac3cd7637588334c9dc1
Gitweb:        https://git.kernel.org/tip/203d8919a9eda5d1bc68ac3cd7637588334c9dc1
Author:        Brian Gerst <brgerst@gmail.com>
AuthorDate:    Fri, 25 Mar 2022 11:39:53 -04:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Thu, 14 Apr 2022 14:15:54 +02:00

x86/asm: Merge load_gs_index()

Merge the 32- and 64-bit implementations of load_gs_index().

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Andy Lutomirski <luto@kernel.org>
Link: https://lore.kernel.org/r/20220325153953.162643-5-brgerst@gmail.com
---
 arch/x86/include/asm/segment.h       | 7 -------
 arch/x86/include/asm/special_insns.h | 7 ++++---
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 617b366..2e7890d 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -350,13 +350,6 @@ static inline void __loadsegment_fs(unsigned short value)
 #define savesegment(seg, value)				\
 	asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
 
-/*
- * x86-32 user GS accessors.  This is ugly and could do with some cleaning up.
- */
-#ifdef CONFIG_X86_32
-# define load_gs_index(v)		loadsegment(gs, (v))
-#endif	/* X86_32 */
-
 #endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index 68c257a..45b18eb 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -184,14 +184,15 @@ static inline void wbinvd(void)
 	native_wbinvd();
 }
 
-#ifdef CONFIG_X86_64
 
 static inline void load_gs_index(unsigned int selector)
 {
+#ifdef CONFIG_X86_64
 	native_load_gs_index(selector);
-}
-
+#else
+	loadsegment(gs, selector);
 #endif
+}
 
 #endif /* CONFIG_PARAVIRT_XXL */
 

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [tip: x86/core] x86/32: Remove lazy GS macros
  2022-03-25 15:39 ` [PATCH 3/4] x86-32: Remove lazy GS macros Brian Gerst
@ 2022-04-15  9:42   ` tip-bot2 for Brian Gerst
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Brian Gerst @ 2022-04-15  9:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brian Gerst, Borislav Petkov, Thomas Gleixner, Andy Lutomirski,
	x86, linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     3a24a60854d2ef19e0edcd11cdbbb4fabc655dde
Gitweb:        https://git.kernel.org/tip/3a24a60854d2ef19e0edcd11cdbbb4fabc655dde
Author:        Brian Gerst <brgerst@gmail.com>
AuthorDate:    Fri, 25 Mar 2022 11:39:52 -04:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Thu, 14 Apr 2022 14:09:43 +02:00

x86/32: Remove lazy GS macros

GS is always a user segment now.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Andy Lutomirski <luto@kernel.org>
Link: https://lore.kernel.org/r/20220325153953.162643-4-brgerst@gmail.com
---
 arch/x86/include/asm/mmu_context.h |  2 +-
 arch/x86/include/asm/segment.h     |  5 -----
 arch/x86/kernel/process.c          |  5 +----
 arch/x86/kernel/process_32.c       | 11 ++++-------
 arch/x86/kernel/ptrace.c           |  6 +++---
 arch/x86/kernel/signal.c           |  8 +++++---
 arch/x86/kernel/vm86_32.c          |  4 ++--
 arch/x86/lib/insn-eval.c           |  5 +++--
 arch/x86/math-emu/get_address.c    |  2 +-
 9 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 2751604..b8d40dd 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -141,7 +141,7 @@ do {						\
 #ifdef CONFIG_X86_32
 #define deactivate_mm(tsk, mm)			\
 do {						\
-	lazy_load_gs(0);			\
+	loadsegment(gs, 0);			\
 } while (0)
 #else
 #define deactivate_mm(tsk, mm)			\
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 656ed65..617b366 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -354,11 +354,6 @@ static inline void __loadsegment_fs(unsigned short value)
  * x86-32 user GS accessors.  This is ugly and could do with some cleaning up.
  */
 #ifdef CONFIG_X86_32
-# 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 */
 
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index b370767..96a9885 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -160,6 +160,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
 	savesegment(ds, p->thread.ds);
 #else
 	p->thread.sp0 = (unsigned long) (childregs + 1);
+	savesegment(gs, p->thread.gs);
 	/*
 	 * Clear all status flags including IF and set fixed bit. 64bit
 	 * does not have this initialization as the frame does not contain
@@ -191,10 +192,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
 	if (sp)
 		childregs->sp = sp;
 
-#ifdef CONFIG_X86_32
-	task_user_gs(p) = get_user_gs(current_pt_regs());
-#endif
-
 	if (unlikely(p->flags & PF_IO_WORKER)) {
 		/*
 		 * An IO thread is a user space thread, but it doesn't
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 26edb1c..877358f 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -63,10 +63,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned short gs;
 
-	if (user_mode(regs))
-		gs = get_user_gs(regs);
-	else
-		savesegment(gs, gs);
+	savesegment(gs, gs);
 
 	show_ip(regs, log_lvl);
 
@@ -114,7 +111,7 @@ void release_thread(struct task_struct *dead_task)
 void
 start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 {
-	set_user_gs(regs, 0);
+	loadsegment(gs, 0);
 	regs->fs		= 0;
 	regs->ds		= __USER_DS;
 	regs->es		= __USER_DS;
@@ -177,7 +174,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	 * used %fs or %gs (it does not today), or if the kernel is
 	 * running inside of a hypervisor layer.
 	 */
-	lazy_save_gs(prev->gs);
+	savesegment(gs, prev->gs);
 
 	/*
 	 * Load the per-thread Thread-Local Storage descriptor.
@@ -208,7 +205,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	 * Restore %gs if needed (which is common)
 	 */
 	if (prev->gs | next->gs)
-		lazy_load_gs(next->gs);
+		loadsegment(gs, next->gs);
 
 	this_cpu_write(current_task, next_p);
 
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 98d10ef..37c12fb 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -170,9 +170,9 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
 		retval = *pt_regs_access(task_pt_regs(task), offset);
 	else {
 		if (task == current)
-			retval = get_user_gs(task_pt_regs(task));
+			savesegment(gs, retval);
 		else
-			retval = task_user_gs(task);
+			retval = task->thread.gs;
 	}
 	return retval;
 }
@@ -210,7 +210,7 @@ static int set_segment_reg(struct task_struct *task,
 		break;
 
 	case offsetof(struct user_regs_struct, gs):
-		task_user_gs(task) = value;
+		task->thread.gs = value;
 	}
 
 	return 0;
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index e439eb1..9c7265b 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -93,7 +93,7 @@ static bool restore_sigcontext(struct pt_regs *regs,
 		return false;
 
 #ifdef CONFIG_X86_32
-	set_user_gs(regs, sc.gs);
+	loadsegment(gs, sc.gs);
 	regs->fs = sc.fs;
 	regs->es = sc.es;
 	regs->ds = sc.ds;
@@ -146,8 +146,10 @@ __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
 		     struct pt_regs *regs, unsigned long mask)
 {
 #ifdef CONFIG_X86_32
-	unsafe_put_user(get_user_gs(regs),
-				  (unsigned int __user *)&sc->gs, Efault);
+	unsigned int gs;
+	savesegment(gs, gs);
+
+	unsafe_put_user(gs,	  (unsigned int __user *)&sc->gs, Efault);
 	unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault);
 	unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault);
 	unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault);
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index c21bcd6..e9e803a 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -151,7 +151,7 @@ exit_vm86:
 
 	memcpy(&regs->pt, &vm86->regs32, sizeof(struct pt_regs));
 
-	lazy_load_gs(vm86->regs32.gs);
+	loadsegment(gs, vm86->regs32.gs);
 
 	regs->pt.ax = retval;
 	return;
@@ -325,7 +325,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
  * Save old state
  */
 	vm86->saved_sp0 = tsk->thread.sp0;
-	lazy_save_gs(vm86->regs32.gs);
+	savesegment(gs, vm86->regs32.gs);
 
 	/* make room for real-mode segments */
 	preempt_disable();
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index b781d32..21104c4 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -342,9 +342,9 @@ static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
  */
 static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
 {
-#ifdef CONFIG_X86_64
 	unsigned short sel;
 
+#ifdef CONFIG_X86_64
 	switch (seg_reg_idx) {
 	case INAT_SEG_REG_IGNORE:
 		return 0;
@@ -402,7 +402,8 @@ 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:
-		return get_user_gs(regs);
+		savesegment(gs, sel);
+		return sel;
 	case INAT_SEG_REG_IGNORE:
 	default:
 		return -EINVAL;
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index b82ca14..4a9fd90 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -153,7 +153,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
 	switch (segment) {
 	case PREFIX_GS_ - 1:
 		/* user gs handling can be lazy, use special accessors */
-		addr->selector = get_user_gs(FPU_info->regs);
+		savesegment(gs, addr->selector);
 		break;
 	default:
 		addr->selector = PM_REG_(segment);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [tip: x86/core] ELF: Remove elf_core_copy_kernel_regs()
  2022-03-25 15:39 ` [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs() Brian Gerst
  2022-04-13 11:41   ` Borislav Petkov
@ 2022-04-15  9:42   ` tip-bot2 for Brian Gerst
  1 sibling, 0 replies; 13+ messages in thread
From: tip-bot2 for Brian Gerst @ 2022-04-15  9:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brian Gerst, Borislav Petkov, Thomas Gleixner, Andy Lutomirski,
	Michael Ellerman, x86, linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     9554e908fb5d02e48a681d1eca180225bf109e83
Gitweb:        https://git.kernel.org/tip/9554e908fb5d02e48a681d1eca180225bf109e83
Author:        Brian Gerst <brgerst@gmail.com>
AuthorDate:    Fri, 25 Mar 2022 11:39:51 -04:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Thu, 14 Apr 2022 14:08:26 +02:00

ELF: Remove elf_core_copy_kernel_regs()

x86-32 was the last architecture that implemented separate user and
kernel registers.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220325153953.162643-3-brgerst@gmail.com
---
 arch/powerpc/kernel/fadump.c               |  2 +-
 arch/powerpc/platforms/powernv/opal-core.c |  2 +-
 include/linux/elfcore.h                    |  9 ---------
 kernel/kexec_core.c                        |  2 +-
 4 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 65562c4..4c09c66 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -752,7 +752,7 @@ u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
 	 * FIXME: How do i get PID? Do I really need it?
 	 * prstatus.pr_pid = ????
 	 */
-	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
+	elf_core_copy_regs(&prstatus.pr_reg, regs);
 	buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
 			      &prstatus, sizeof(prstatus));
 	return buf;
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index b97bc17..adcb1a1 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
 			  struct pt_regs *regs)
 {
 	memset(prstatus, 0, sizeof(struct elf_prstatus));
-	elf_core_copy_kernel_regs(&(prstatus->pr_reg), regs);
+	elf_core_copy_regs(&(prstatus->pr_reg), regs);
 
 	/*
 	 * Overload PID with PIR value.
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index f8e206e..346a8b5 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -84,15 +84,6 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
 #endif
 }
 
-static inline void elf_core_copy_kernel_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
-{
-#ifdef ELF_CORE_COPY_KERNEL_REGS
-	ELF_CORE_COPY_KERNEL_REGS((*elfregs), regs);
-#else
-	elf_core_copy_regs(elfregs, regs);
-#endif
-}
-
 static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
 {
 #if defined (ELF_CORE_COPY_TASK_REGS)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 68480f7..be4b54c 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1078,7 +1078,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
 		return;
 	memset(&prstatus, 0, sizeof(prstatus));
 	prstatus.common.pr_pid = current->pid;
-	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
+	elf_core_copy_regs(&prstatus.pr_reg, regs);
 	buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
 			      &prstatus, sizeof(prstatus));
 	final_note(buf);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [tip: x86/core] x86/32: Simplify ELF_CORE_COPY_REGS
  2022-03-25 15:39 ` [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS Brian Gerst
@ 2022-04-15  9:42   ` tip-bot2 for Brian Gerst
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Brian Gerst @ 2022-04-15  9:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brian Gerst, Borislav Petkov, Thomas Gleixner, Andy Lutomirski,
	x86, linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     f5d9283ecb33329073033029fe427155aa0abfb1
Gitweb:        https://git.kernel.org/tip/f5d9283ecb33329073033029fe427155aa0abfb1
Author:        Brian Gerst <brgerst@gmail.com>
AuthorDate:    Fri, 25 Mar 2022 11:39:50 -04:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Tue, 12 Apr 2022 15:42:59 +02:00

x86/32: Simplify ELF_CORE_COPY_REGS

GS is now always a user segment, so there is no difference between user
and kernel registers.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Andy Lutomirski <luto@kernel.org>
Link: https://lore.kernel.org/r/20220325153953.162643-2-brgerst@gmail.com
---
 arch/x86/include/asm/elf.h | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 29fea18..cb0ff10 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -116,7 +116,7 @@ extern unsigned int vdso32_enabled;
  * now struct_user_regs, they are different)
  */
 
-#define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs)	\
+#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
 do {						\
 	pr_reg[0] = regs->bx;			\
 	pr_reg[1] = regs->cx;			\
@@ -128,6 +128,7 @@ do {						\
 	pr_reg[7] = regs->ds;			\
 	pr_reg[8] = regs->es;			\
 	pr_reg[9] = regs->fs;			\
+	savesegment(gs, pr_reg[10]);		\
 	pr_reg[11] = regs->orig_ax;		\
 	pr_reg[12] = regs->ip;			\
 	pr_reg[13] = regs->cs;			\
@@ -136,18 +137,6 @@ do {						\
 	pr_reg[16] = regs->ss;			\
 } while (0);
 
-#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
-do {						\
-	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
-	pr_reg[10] = get_user_gs(regs);		\
-} while (0);
-
-#define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs)	\
-do {						\
-	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
-	savesegment(gs, pr_reg[10]);		\
-} while (0);
-
 #define ELF_PLATFORM	(utsname()->machine)
 #define set_personality_64bit()	do { } while (0)
 

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-04-15  9:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-25 15:39 [PATCH 0/4] x86-32: Clean up GS segment handling Brian Gerst
2022-03-25 15:39 ` [PATCH 1/4] x86-32: Simplify ELF_CORE_COPY_REGS Brian Gerst
2022-04-15  9:42   ` [tip: x86/core] x86/32: " tip-bot2 for Brian Gerst
2022-03-25 15:39 ` [PATCH 2/4] ELF: Remove elf_core_copy_kernel_regs() Brian Gerst
2022-04-13 11:41   ` Borislav Petkov
2022-04-13 12:31     ` Michael Ellerman
2022-04-15  9:42   ` [tip: x86/core] " tip-bot2 for Brian Gerst
2022-03-25 15:39 ` [PATCH 3/4] x86-32: Remove lazy GS macros Brian Gerst
2022-04-15  9:42   ` [tip: x86/core] x86/32: " tip-bot2 for Brian Gerst
2022-03-25 15:39 ` [PATCH 4/4] x86: Merge load_gs_index() Brian Gerst
2022-04-15  9:42   ` [tip: x86/core] x86/asm: " tip-bot2 for Brian Gerst
2022-03-25 15:45 ` [PATCH 0/4] x86-32: Clean up GS segment handling Andy Lutomirski
2022-04-05 16:12 ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox