diff options
| -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 | ||
