diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 35 | ||||
-rw-r--r-- | kernel/sys.c | 13 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 2 |
3 files changed, 43 insertions, 7 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 9c042f901570..89fe414645e9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -132,6 +132,14 @@ void __put_task_struct(struct task_struct *tsk) | |||
132 | free_task(tsk); | 132 | free_task(tsk); |
133 | } | 133 | } |
134 | 134 | ||
135 | /* | ||
136 | * macro override instead of weak attribute alias, to workaround | ||
137 | * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions. | ||
138 | */ | ||
139 | #ifndef arch_task_cache_init | ||
140 | #define arch_task_cache_init() | ||
141 | #endif | ||
142 | |||
135 | void __init fork_init(unsigned long mempages) | 143 | void __init fork_init(unsigned long mempages) |
136 | { | 144 | { |
137 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR | 145 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR |
@@ -144,6 +152,9 @@ void __init fork_init(unsigned long mempages) | |||
144 | ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); | 152 | ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); |
145 | #endif | 153 | #endif |
146 | 154 | ||
155 | /* do the arch specific task caches init */ | ||
156 | arch_task_cache_init(); | ||
157 | |||
147 | /* | 158 | /* |
148 | * The default maximum number of threads is set to a safe | 159 | * The default maximum number of threads is set to a safe |
149 | * value: the thread structures can take up at most half | 160 | * value: the thread structures can take up at most half |
@@ -163,6 +174,13 @@ void __init fork_init(unsigned long mempages) | |||
163 | init_task.signal->rlim[RLIMIT_NPROC]; | 174 | init_task.signal->rlim[RLIMIT_NPROC]; |
164 | } | 175 | } |
165 | 176 | ||
177 | int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst, | ||
178 | struct task_struct *src) | ||
179 | { | ||
180 | *dst = *src; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
166 | static struct task_struct *dup_task_struct(struct task_struct *orig) | 184 | static struct task_struct *dup_task_struct(struct task_struct *orig) |
167 | { | 185 | { |
168 | struct task_struct *tsk; | 186 | struct task_struct *tsk; |
@@ -181,15 +199,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
181 | return NULL; | 199 | return NULL; |
182 | } | 200 | } |
183 | 201 | ||
184 | *tsk = *orig; | 202 | err = arch_dup_task_struct(tsk, orig); |
203 | if (err) | ||
204 | goto out; | ||
205 | |||
185 | tsk->stack = ti; | 206 | tsk->stack = ti; |
186 | 207 | ||
187 | err = prop_local_init_single(&tsk->dirties); | 208 | err = prop_local_init_single(&tsk->dirties); |
188 | if (err) { | 209 | if (err) |
189 | free_thread_info(ti); | 210 | goto out; |
190 | free_task_struct(tsk); | ||
191 | return NULL; | ||
192 | } | ||
193 | 211 | ||
194 | setup_thread_stack(tsk, orig); | 212 | setup_thread_stack(tsk, orig); |
195 | 213 | ||
@@ -205,6 +223,11 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
205 | #endif | 223 | #endif |
206 | tsk->splice_pipe = NULL; | 224 | tsk->splice_pipe = NULL; |
207 | return tsk; | 225 | return tsk; |
226 | |||
227 | out: | ||
228 | free_thread_info(ti); | ||
229 | free_task_struct(tsk); | ||
230 | return NULL; | ||
208 | } | 231 | } |
209 | 232 | ||
210 | #ifdef CONFIG_MMU | 233 | #ifdef CONFIG_MMU |
diff --git a/kernel/sys.c b/kernel/sys.c index a626116af5db..6a0cc71ee88d 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -67,6 +67,12 @@ | |||
67 | #ifndef SET_ENDIAN | 67 | #ifndef SET_ENDIAN |
68 | # define SET_ENDIAN(a,b) (-EINVAL) | 68 | # define SET_ENDIAN(a,b) (-EINVAL) |
69 | #endif | 69 | #endif |
70 | #ifndef GET_TSC_CTL | ||
71 | # define GET_TSC_CTL(a) (-EINVAL) | ||
72 | #endif | ||
73 | #ifndef SET_TSC_CTL | ||
74 | # define SET_TSC_CTL(a) (-EINVAL) | ||
75 | #endif | ||
70 | 76 | ||
71 | /* | 77 | /* |
72 | * this is where the system-wide overflow UID and GID are defined, for | 78 | * this is where the system-wide overflow UID and GID are defined, for |
@@ -1737,7 +1743,12 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1737 | #else | 1743 | #else |
1738 | return -EINVAL; | 1744 | return -EINVAL; |
1739 | #endif | 1745 | #endif |
1740 | 1746 | case PR_GET_TSC: | |
1747 | error = GET_TSC_CTL(arg2); | ||
1748 | break; | ||
1749 | case PR_SET_TSC: | ||
1750 | error = SET_TSC_CTL(arg2); | ||
1751 | break; | ||
1741 | default: | 1752 | default: |
1742 | error = -EINVAL; | 1753 | error = -EINVAL; |
1743 | break; | 1754 | break; |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index a3fa587c350c..2d6087c7cf98 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -178,6 +178,7 @@ static void change_clocksource(void) | |||
178 | if (clock == new) | 178 | if (clock == new) |
179 | return; | 179 | return; |
180 | 180 | ||
181 | new->cycle_last = 0; | ||
181 | now = clocksource_read(new); | 182 | now = clocksource_read(new); |
182 | nsec = __get_nsec_offset(); | 183 | nsec = __get_nsec_offset(); |
183 | timespec_add_ns(&xtime, nsec); | 184 | timespec_add_ns(&xtime, nsec); |
@@ -295,6 +296,7 @@ static int timekeeping_resume(struct sys_device *dev) | |||
295 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); | 296 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); |
296 | update_xtime_cache(0); | 297 | update_xtime_cache(0); |
297 | /* re-base the last cycle value */ | 298 | /* re-base the last cycle value */ |
299 | clock->cycle_last = 0; | ||
298 | clock->cycle_last = clocksource_read(clock); | 300 | clock->cycle_last = clocksource_read(clock); |
299 | clock->error = 0; | 301 | clock->error = 0; |
300 | timekeeping_suspended = 0; | 302 | timekeeping_suspended = 0; |