@@ -5102,20 +5102,16 @@ static int __perf_read_group_add(struct perf_event *leader,
51025102}
51035103
51045104static int perf_read_group (struct perf_event * event ,
5105- u64 read_format , char __user * buf )
5105+ u64 read_format , char __user * buf ,
5106+ u64 * values )
51065107{
51075108 struct perf_event * leader = event -> group_leader , * child ;
51085109 struct perf_event_context * ctx = leader -> ctx ;
51095110 int ret ;
5110- u64 * values ;
51115111
51125112 lockdep_assert_held (& ctx -> mutex );
51135113
5114- values = kzalloc (event -> read_size , GFP_KERNEL );
5115- if (!values )
5116- return - ENOMEM ;
5117-
5118- values [0 ] = 1 + leader -> nr_siblings ;
5114+ * values = 1 + leader -> nr_siblings ;
51195115
51205116 /*
51215117 * By locking the child_mutex of the leader we effectively
@@ -5133,25 +5129,17 @@ static int perf_read_group(struct perf_event *event,
51335129 goto unlock ;
51345130 }
51355131
5136- mutex_unlock (& leader -> child_mutex );
5137-
51385132 ret = event -> read_size ;
5139- if (copy_to_user (buf , values , event -> read_size ))
5140- ret = - EFAULT ;
5141- goto out ;
5142-
51435133unlock :
51445134 mutex_unlock (& leader -> child_mutex );
5145- out :
5146- kfree (values );
51475135 return ret ;
51485136}
51495137
51505138static int perf_read_one (struct perf_event * event ,
5151- u64 read_format , char __user * buf )
5139+ u64 read_format , char __user * buf ,
5140+ u64 * values )
51525141{
51535142 u64 enabled , running ;
5154- u64 values [4 ];
51555143 int n = 0 ;
51565144
51575145 values [n ++ ] = __perf_event_read_value (event , & enabled , & running );
@@ -5162,9 +5150,6 @@ static int perf_read_one(struct perf_event *event,
51625150 if (read_format & PERF_FORMAT_ID )
51635151 values [n ++ ] = primary_event_id (event );
51645152
5165- if (copy_to_user (buf , values , n * sizeof (u64 )))
5166- return - EFAULT ;
5167-
51685153 return n * sizeof (u64 );
51695154}
51705155
@@ -5185,7 +5170,8 @@ static bool is_event_hup(struct perf_event *event)
51855170 * Read the performance event - simple non blocking version for now
51865171 */
51875172static ssize_t
5188- __perf_read (struct perf_event * event , char __user * buf , size_t count )
5173+ __perf_read (struct perf_event * event , char __user * buf ,
5174+ size_t count , u64 * values )
51895175{
51905176 u64 read_format = event -> attr .read_format ;
51915177 int ret ;
@@ -5203,9 +5189,9 @@ __perf_read(struct perf_event *event, char __user *buf, size_t count)
52035189
52045190 WARN_ON_ONCE (event -> ctx -> parent_ctx );
52055191 if (read_format & PERF_FORMAT_GROUP )
5206- ret = perf_read_group (event , read_format , buf );
5192+ ret = perf_read_group (event , read_format , buf , values );
52075193 else
5208- ret = perf_read_one (event , read_format , buf );
5194+ ret = perf_read_one (event , read_format , buf , values );
52095195
52105196 return ret ;
52115197}
@@ -5215,16 +5201,31 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
52155201{
52165202 struct perf_event * event = file -> private_data ;
52175203 struct perf_event_context * ctx ;
5204+ u64 stack_values [8 ];
5205+ u64 * values ;
52185206 int ret ;
52195207
52205208 ret = security_perf_event_read (event );
52215209 if (ret )
52225210 return ret ;
52235211
5212+ if (event -> read_size <= sizeof (stack_values ))
5213+ values = memset (stack_values , 0 , event -> read_size );
5214+ else
5215+ values = kzalloc (event -> read_size , GFP_KERNEL );
5216+ if (!values )
5217+ return - ENOMEM ;
5218+
52245219 ctx = perf_event_ctx_lock (event );
5225- ret = __perf_read (event , buf , count );
5220+ ret = __perf_read (event , buf , count , values );
52265221 perf_event_ctx_unlock (event , ctx );
52275222
5223+ if (ret > 0 && copy_to_user (buf , values , ret ))
5224+ ret = - EFAULT ;
5225+
5226+ if (values != stack_values )
5227+ kfree (values );
5228+
52285229 return ret ;
52295230}
52305231
@@ -10740,7 +10741,8 @@ void perf_pmu_unregister(struct pmu *pmu)
1074010741 device_del (pmu -> dev );
1074110742 put_device (pmu -> dev );
1074210743 }
10743- free_pmu_context (pmu );
10744+ if (!find_pmu_context (pmu -> task_ctx_nr ))
10745+ free_pmu_context (pmu );
1074410746 mutex_unlock (& pmus_lock );
1074510747}
1074610748EXPORT_SYMBOL_GPL (perf_pmu_unregister );
0 commit comments