Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9a89a26 authored by Tejun Heo's avatar Tejun Heo Committed by Ingo Molnar
Browse files

x86: add %gs accessors for x86_32



Impact: cleanup

On x86_32, %gs is handled lazily.  It's not saved and restored on
kernel entry/exit but only when necessary which usually is during task
switch but there are few other places.  Currently, it's done by
calling savesegment() and loadsegment() explicitly.  Define
get_user_gs(), set_user_gs() and task_user_gs() and use them instead.

While at it, clean up register access macros in signal.c.

This cleans up code a bit and will help future changes.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent f0d96110
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
	dump->regs.ds = (u16)regs->ds;
	dump->regs.es = (u16)regs->es;
	dump->regs.fs = (u16)regs->fs;
	savesegment(gs, dump->regs.gs);
	dump->regs.gs = get_user_gs(regs);
	dump->regs.orig_ax = regs->orig_ax;
	dump->regs.ip = regs->ip;
	dump->regs.cs = (u16)regs->cs;
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ do { \
	pr_reg[7] = regs->ds & 0xffff;		\
	pr_reg[8] = regs->es & 0xffff;		\
	pr_reg[9] = regs->fs & 0xffff;		\
	savesegment(gs, pr_reg[10]);		\
	pr_reg[10] = get_user_gs(regs);		\
	pr_reg[11] = regs->orig_ax;		\
	pr_reg[12] = regs->ip;			\
	pr_reg[13] = regs->cs & 0xffff;		\
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ do { \
#ifdef CONFIG_X86_32
#define deactivate_mm(tsk, mm)			\
do {						\
	loadsegment(gs, 0);			\
	set_user_gs(task_pt_regs(tsk), 0);	\
} while (0)
#else
#define deactivate_mm(tsk, mm)			\
+9 −0
Original line number Diff line number Diff line
@@ -182,6 +182,15 @@ extern void native_load_gs_index(unsigned);
#define savesegment(seg, value)				\
	asm("mov %%" #seg ",%0":"=r" (value) : : "memory")

/*
 * x86_32 user gs accessors.
 */
#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)
#endif

static inline unsigned long get_limit(unsigned long segment)
{
	unsigned long __limit;
+3 −3
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ void __show_regs(struct pt_regs *regs, int all)
	if (user_mode_vm(regs)) {
		sp = regs->sp;
		ss = regs->ss & 0xffff;
		savesegment(gs, gs);
		gs = get_user_gs(regs);
	} else {
		sp = (unsigned long) (&regs->sp);
		savesegment(ss, ss);
@@ -304,7 +304,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,

	p->thread.ip = (unsigned long) ret_from_fork;

	savesegment(gs, p->thread.gs);
	task_user_gs(p) = get_user_gs(regs);

	tsk = current;
	if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
@@ -342,7 +342,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
void
start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
{
	__asm__("movl %0, %%gs" : : "r"(0));
	set_user_gs(regs, 0);
	regs->fs		= 0;
	set_fs(USER_DS);
	regs->ds		= __USER_DS;
Loading