Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
um
syscalls_64.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3
* Copyright 2003 PathScale, Inc.
4
*
5
* Licensed under the GPL
6
*/
7
8
#include <linux/sched.h>
9
#include <
asm/prctl.h
>
/* XXX This should get the constants from libc */
10
#include <os.h>
11
12
long
arch_prctl
(
struct
task_struct
*
task
,
int
code
,
unsigned
long
__user *
addr
)
13
{
14
unsigned
long
*
ptr
=
addr
,
tmp
;
15
long
ret
;
16
int
pid
= task->
mm
->context.id.u.pid;
17
18
/*
19
* With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
20
* be safe), we need to call arch_prctl on the host because
21
* setting %fs may result in something else happening (like a
22
* GDT or thread.fs being set instead). So, we let the host
23
* fiddle the registers and thread struct and restore the
24
* registers afterwards.
25
*
26
* So, the saved registers are stored to the process (this
27
* needed because a stub may have been the last thing to run),
28
* arch_prctl is run on the host, then the registers are read
29
* back.
30
*/
31
switch
(code) {
32
case
ARCH_SET_FS
:
33
case
ARCH_SET_GS
:
34
ret =
restore_registers
(pid, &
current
->thread.regs.regs);
35
if
(ret)
36
return
ret
;
37
break
;
38
case
ARCH_GET_FS
:
39
case
ARCH_GET_GS
:
40
/*
41
* With these two, we read to a local pointer and
42
* put_user it to the userspace pointer that we were
43
* given. If addr isn't valid (because it hasn't been
44
* faulted in or is just bogus), we want put_user to
45
* fault it in (or return -EFAULT) instead of having
46
* the host return -EFAULT.
47
*/
48
ptr = &
tmp
;
49
}
50
51
ret =
os_arch_prctl
(pid, code, ptr);
52
if
(ret)
53
return
ret
;
54
55
switch
(code) {
56
case
ARCH_SET_FS
:
57
current
->thread.arch.fs = (
unsigned
long
) ptr;
58
ret =
save_registers
(pid, &
current
->thread.regs.regs);
59
break
;
60
case
ARCH_SET_GS
:
61
ret =
save_registers
(pid, &
current
->thread.regs.regs);
62
break
;
63
case
ARCH_GET_FS
:
64
ret =
put_user
(tmp, addr);
65
break
;
66
case
ARCH_GET_GS
:
67
ret =
put_user
(tmp, addr);
68
break
;
69
}
70
71
return
ret
;
72
}
73
74
long
sys_arch_prctl
(
int
code
,
unsigned
long
addr
)
75
{
76
return
arch_prctl
(
current
, code, (
unsigned
long
__user
*) addr);
77
}
78
79
void
arch_switch_to
(
struct
task_struct
*to)
80
{
81
if
((to->
thread
.arch.fs == 0) || (to->
mm
==
NULL
))
82
return
;
83
84
arch_prctl
(to,
ARCH_SET_FS
, (
void
__user
*) to->
thread
.arch.fs);
85
}
Generated on Thu Jan 10 2013 13:21:52 for Linux Kernel by
1.8.2