diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-10-09 18:56:53 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-10-09 19:26:38 -0400 |
commit | e634d8fc792c66c3d4ff45518c04848c1e28f221 (patch) | |
tree | d72159bc7b95af55f97ffe4688bee22403c66d79 /arch | |
parent | a6f05a6a0a1713d5b019f096799d49226807d3df (diff) |
x86-64: merge the standard and compat start_thread() functions
The only thing left that differs between the standard and compat
start_thread functions is the actual segment numbers and the
prototype, so have a single common function which contains the guts
and two very small wrappers.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/process_64.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 7cf0a6b6d4bb..eb261c582a44 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -344,18 +344,20 @@ out: | |||
344 | return err; | 344 | return err; |
345 | } | 345 | } |
346 | 346 | ||
347 | void | 347 | static void |
348 | start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | 348 | start_thread_common(struct pt_regs *regs, unsigned long new_ip, |
349 | unsigned long new_sp, | ||
350 | unsigned int _cs, unsigned int _ss, unsigned int _ds) | ||
349 | { | 351 | { |
350 | loadsegment(fs, 0); | 352 | loadsegment(fs, 0); |
351 | loadsegment(es, 0); | 353 | loadsegment(es, _ds); |
352 | loadsegment(ds, 0); | 354 | loadsegment(ds, _ds); |
353 | load_gs_index(0); | 355 | load_gs_index(0); |
354 | regs->ip = new_ip; | 356 | regs->ip = new_ip; |
355 | regs->sp = new_sp; | 357 | regs->sp = new_sp; |
356 | percpu_write(old_rsp, new_sp); | 358 | percpu_write(old_rsp, new_sp); |
357 | regs->cs = __USER_CS; | 359 | regs->cs = _cs; |
358 | regs->ss = __USER_DS; | 360 | regs->ss = _ss; |
359 | regs->flags = X86_EFLAGS_IF; | 361 | regs->flags = X86_EFLAGS_IF; |
360 | set_fs(USER_DS); | 362 | set_fs(USER_DS); |
361 | /* | 363 | /* |
@@ -363,26 +365,19 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
363 | */ | 365 | */ |
364 | free_thread_xstate(current); | 366 | free_thread_xstate(current); |
365 | } | 367 | } |
366 | EXPORT_SYMBOL_GPL(start_thread); | 368 | |
369 | void | ||
370 | start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | ||
371 | { | ||
372 | start_thread_common(regs, new_ip, new_sp, | ||
373 | __USER_CS, __USER_DS, 0); | ||
374 | } | ||
367 | 375 | ||
368 | #ifdef CONFIG_IA32_EMULATION | 376 | #ifdef CONFIG_IA32_EMULATION |
369 | void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp) | 377 | void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp) |
370 | { | 378 | { |
371 | loadsegment(fs, 0); | 379 | start_thread_common(regs, new_ip, new_sp, |
372 | loadsegment(ds, __USER32_DS); | 380 | __USER32_CS, __USER32_DS, __USER32_DS); |
373 | loadsegment(es, __USER32_DS); | ||
374 | load_gs_index(0); | ||
375 | regs->ip = new_ip; | ||
376 | regs->sp = new_sp; | ||
377 | percpu_write(old_rsp, new_sp); | ||
378 | regs->cs = __USER32_CS; | ||
379 | regs->ss = __USER32_DS; | ||
380 | regs->flags = X86_EFLAGS_IF; | ||
381 | set_fs(USER_DS); | ||
382 | /* | ||
383 | * Free the old FP and other extended state | ||
384 | */ | ||
385 | free_thread_xstate(current); | ||
386 | } | 381 | } |
387 | #endif | 382 | #endif |
388 | 383 | ||