aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/ds.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index ac1d5b0586ba..d1a121443bde 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -236,17 +236,33 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task)
236 struct ds_context *context = *p_context; 236 struct ds_context *context = *p_context;
237 237
238 if (!context) { 238 if (!context) {
239 spin_unlock(&ds_lock);
240
239 context = kzalloc(sizeof(*context), GFP_KERNEL); 241 context = kzalloc(sizeof(*context), GFP_KERNEL);
240 242
241 if (!context) 243 if (!context) {
244 spin_lock(&ds_lock);
242 return NULL; 245 return NULL;
246 }
243 247
244 context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); 248 context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
245 if (!context->ds) { 249 if (!context->ds) {
246 kfree(context); 250 kfree(context);
251 spin_lock(&ds_lock);
247 return NULL; 252 return NULL;
248 } 253 }
249 254
255 spin_lock(&ds_lock);
256 /*
257 * Check for race - another CPU could have allocated
258 * it meanwhile:
259 */
260 if (*p_context) {
261 kfree(context->ds);
262 kfree(context);
263 return *p_context;
264 }
265
250 *p_context = context; 266 *p_context = context;
251 267
252 context->this = p_context; 268 context->this = p_context;
@@ -384,15 +400,15 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
384 400
385 spin_lock(&ds_lock); 401 spin_lock(&ds_lock);
386 402
387 error = -EPERM;
388 if (!check_tracer(task))
389 goto out_unlock;
390
391 error = -ENOMEM; 403 error = -ENOMEM;
392 context = ds_alloc_context(task); 404 context = ds_alloc_context(task);
393 if (!context) 405 if (!context)
394 goto out_unlock; 406 goto out_unlock;
395 407
408 error = -EPERM;
409 if (!check_tracer(task))
410 goto out_unlock;
411
396 error = -EALREADY; 412 error = -EALREADY;
397 if (context->owner[qual] == current) 413 if (context->owner[qual] == current)
398 goto out_unlock; 414 goto out_unlock;