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

Commit 66e10a44 authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Andi Kleen
Browse files

[PATCH] i386: Fix places where using %gs changes the usermode ABI



There are a few places where the change in struct pt_regs and the use of %gs
affect the userspace ABI.  These are primarily debugging interfaces where
thread state can be inspected or extracted.

Signed-off-by: default avatarJeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
parent f95d47ca
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -315,8 +315,8 @@ void show_regs(struct pt_regs * regs)
		regs->eax,regs->ebx,regs->ecx,regs->edx);
	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
		regs->esi, regs->edi, regs->ebp);
	printk(" DS: %04x ES: %04x\n",
		0xffff & regs->xds,0xffff & regs->xes);
	printk(" DS: %04x ES: %04x GS: %04x\n",
	       0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xgs);

	cr0 = read_cr0();
	cr2 = read_cr2();
@@ -509,7 +509,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
	dump->regs.ds = regs->xds;
	dump->regs.es = regs->xes;
	savesegment(fs,dump->regs.fs);
	savesegment(gs,dump->regs.gs);
	dump->regs.gs = regs->xgs;
	dump->regs.orig_eax = regs->orig_eax;
	dump->regs.eip = regs->eip;
	dump->regs.cs = regs->xcs;
+6 −12
Original line number Diff line number Diff line
@@ -94,13 +94,9 @@ static int putreg(struct task_struct *child,
				return -EIO;
			child->thread.fs = value;
			return 0;
		case GS:
			if (value && (value & 3) != 3)
				return -EIO;
			child->thread.gs = value;
			return 0;
		case DS:
		case ES:
		case GS:
			if (value && (value & 3) != 3)
				return -EIO;
			value &= 0xffff;
@@ -116,8 +112,8 @@ static int putreg(struct task_struct *child,
			value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
			break;
	}
	if (regno > GS*4)
		regno -= 2*4;
	if (regno > ES*4)
		regno -= 1*4;
	put_stack_long(child, regno - sizeof(struct pt_regs), value);
	return 0;
}
@@ -131,18 +127,16 @@ static unsigned long getreg(struct task_struct *child,
		case FS:
			retval = child->thread.fs;
			break;
		case GS:
			retval = child->thread.gs;
			break;
		case DS:
		case ES:
		case GS:
		case SS:
		case CS:
			retval = 0xffff;
			/* fall through */
		default:
			if (regno > GS*4)
				regno -= 2*4;
			if (regno > ES*4)
				regno -= 1*4;
			regno = regno - sizeof(struct pt_regs);
			retval &= get_stack_long(child, regno);
	}
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
	pr_reg[7] = regs->xds;				\
	pr_reg[8] = regs->xes;				\
	savesegment(fs,pr_reg[9]);			\
	savesegment(gs,pr_reg[10]);			\
	pr_reg[10] = regs->xgs;				\
	pr_reg[11] = regs->orig_eax;			\
	pr_reg[12] = regs->eip;				\
	pr_reg[13] = regs->xcs;				\
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
	info->regs.xss = __KERNEL_DS;
	info->regs.xds = __USER_DS;
	info->regs.xes = __USER_DS;
	info->regs.xgs = __KERNEL_PDA;
}

extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,