@@ -5272,20 +5272,16 @@ static int __perf_read_group_add(struct perf_event *leader,
5272
5272
}
5273
5273
5274
5274
static int perf_read_group (struct perf_event * event ,
5275
- u64 read_format , char __user * buf )
5275
+ u64 read_format , char __user * buf ,
5276
+ u64 * values )
5276
5277
{
5277
5278
struct perf_event * leader = event -> group_leader , * child ;
5278
5279
struct perf_event_context * ctx = leader -> ctx ;
5279
5280
int ret ;
5280
- u64 * values ;
5281
5281
5282
5282
lockdep_assert_held (& ctx -> mutex );
5283
5283
5284
- values = kzalloc (event -> read_size , GFP_KERNEL );
5285
- if (!values )
5286
- return - ENOMEM ;
5287
-
5288
- values [0 ] = 1 + leader -> nr_siblings ;
5284
+ * values = 1 + leader -> nr_siblings ;
5289
5285
5290
5286
/*
5291
5287
* By locking the child_mutex of the leader we effectively
@@ -5303,25 +5299,17 @@ static int perf_read_group(struct perf_event *event,
5303
5299
goto unlock ;
5304
5300
}
5305
5301
5306
- mutex_unlock (& leader -> child_mutex );
5307
-
5308
5302
ret = event -> read_size ;
5309
- if (copy_to_user (buf , values , event -> read_size ))
5310
- ret = - EFAULT ;
5311
- goto out ;
5312
-
5313
5303
unlock :
5314
5304
mutex_unlock (& leader -> child_mutex );
5315
- out :
5316
- kfree (values );
5317
5305
return ret ;
5318
5306
}
5319
5307
5320
5308
static int perf_read_one (struct perf_event * event ,
5321
- u64 read_format , char __user * buf )
5309
+ u64 read_format , char __user * buf ,
5310
+ u64 * values )
5322
5311
{
5323
5312
u64 enabled , running ;
5324
- u64 values [4 ];
5325
5313
int n = 0 ;
5326
5314
5327
5315
values [n ++ ] = __perf_event_read_value (event , & enabled , & running );
@@ -5332,9 +5320,6 @@ static int perf_read_one(struct perf_event *event,
5332
5320
if (read_format & PERF_FORMAT_ID )
5333
5321
values [n ++ ] = primary_event_id (event );
5334
5322
5335
- if (copy_to_user (buf , values , n * sizeof (u64 )))
5336
- return - EFAULT ;
5337
-
5338
5323
return n * sizeof (u64 );
5339
5324
}
5340
5325
@@ -5355,7 +5340,8 @@ static bool is_event_hup(struct perf_event *event)
5355
5340
* Read the performance event - simple non blocking version for now
5356
5341
*/
5357
5342
static ssize_t
5358
- __perf_read (struct perf_event * event , char __user * buf , size_t count )
5343
+ __perf_read (struct perf_event * event , char __user * buf ,
5344
+ size_t count , u64 * values )
5359
5345
{
5360
5346
u64 read_format = event -> attr .read_format ;
5361
5347
int ret ;
@@ -5373,9 +5359,9 @@ __perf_read(struct perf_event *event, char __user *buf, size_t count)
5373
5359
5374
5360
WARN_ON_ONCE (event -> ctx -> parent_ctx );
5375
5361
if (read_format & PERF_FORMAT_GROUP )
5376
- ret = perf_read_group (event , read_format , buf );
5362
+ ret = perf_read_group (event , read_format , buf , values );
5377
5363
else
5378
- ret = perf_read_one (event , read_format , buf );
5364
+ ret = perf_read_one (event , read_format , buf , values );
5379
5365
5380
5366
return ret ;
5381
5367
}
@@ -5385,16 +5371,31 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
5385
5371
{
5386
5372
struct perf_event * event = file -> private_data ;
5387
5373
struct perf_event_context * ctx ;
5374
+ u64 stack_values [8 ];
5375
+ u64 * values ;
5388
5376
int ret ;
5389
5377
5390
5378
ret = security_perf_event_read (event );
5391
5379
if (ret )
5392
5380
return ret ;
5393
5381
5382
+ if (event -> read_size <= sizeof (stack_values ))
5383
+ values = memset (stack_values , 0 , event -> read_size );
5384
+ else
5385
+ values = kzalloc (event -> read_size , GFP_KERNEL );
5386
+ if (!values )
5387
+ return - ENOMEM ;
5388
+
5394
5389
ctx = perf_event_ctx_lock (event );
5395
- ret = __perf_read (event , buf , count );
5390
+ ret = __perf_read (event , buf , count , values );
5396
5391
perf_event_ctx_unlock (event , ctx );
5397
5392
5393
+ if (ret > 0 && copy_to_user (buf , values , ret ))
5394
+ ret = - EFAULT ;
5395
+
5396
+ if (values != stack_values )
5397
+ kfree (values );
5398
+
5398
5399
return ret ;
5399
5400
}
5400
5401
@@ -11203,7 +11204,8 @@ void perf_pmu_unregister(struct pmu *pmu)
11203
11204
device_del (pmu -> dev );
11204
11205
put_device (pmu -> dev );
11205
11206
}
11206
- free_pmu_context (pmu );
11207
+ if (!find_pmu_context (pmu -> task_ctx_nr ))
11208
+ free_pmu_context (pmu );
11207
11209
mutex_unlock (& pmus_lock );
11208
11210
}
11209
11211
EXPORT_SYMBOL_GPL (perf_pmu_unregister );
0 commit comments