]>
Commit | Line | Data |
---|---|---|
299543a1 GKH |
1 | From 625c85a62cb7d3c79f6e16de3cfa972033658250 Mon Sep 17 00:00:00 2001 |
2 | From: Viresh Kumar <viresh.kumar@linaro.org> | |
3 | Date: Fri, 25 Jan 2019 12:53:07 +0530 | |
4 | Subject: cpufreq: Use struct kobj_attribute instead of struct global_attr | |
5 | ||
6 | From: Viresh Kumar <viresh.kumar@linaro.org> | |
7 | ||
8 | commit 625c85a62cb7d3c79f6e16de3cfa972033658250 upstream. | |
9 | ||
10 | The cpufreq_global_kobject is created using kobject_create_and_add() | |
11 | helper, which assigns the kobj_type as dynamic_kobj_ktype and show/store | |
12 | routines are set to kobj_attr_show() and kobj_attr_store(). | |
13 | ||
14 | These routines pass struct kobj_attribute as an argument to the | |
15 | show/store callbacks. But all the cpufreq files created using the | |
16 | cpufreq_global_kobject expect the argument to be of type struct | |
17 | attribute. Things work fine currently as no one accesses the "attr" | |
18 | argument. We may not see issues even if the argument is used, as struct | |
19 | kobj_attribute has struct attribute as its first element and so they | |
20 | will both get same address. | |
21 | ||
22 | But this is logically incorrect and we should rather use struct | |
23 | kobj_attribute instead of struct global_attr in the cpufreq core and | |
24 | drivers and the show/store callbacks should take struct kobj_attribute | |
25 | as argument instead. | |
26 | ||
27 | This bug is caught using CFI CLANG builds in android kernel which | |
28 | catches mismatch in function prototypes for such callbacks. | |
29 | ||
30 | Reported-by: Donghee Han <dh.han@samsung.com> | |
31 | Reported-by: Sangkyu Kim <skwith.kim@samsung.com> | |
32 | Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> | |
33 | Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
34 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
35 | ||
36 | ||
37 | --- | |
38 | drivers/cpufreq/cpufreq.c | 6 +++--- | |
39 | drivers/cpufreq/cpufreq_governor.h | 10 +++++----- | |
40 | drivers/cpufreq/intel_pstate.c | 14 +++++++------- | |
41 | include/linux/cpufreq.h | 12 ++---------- | |
42 | 4 files changed, 17 insertions(+), 25 deletions(-) | |
43 | ||
44 | --- a/drivers/cpufreq/cpufreq.c | |
45 | +++ b/drivers/cpufreq/cpufreq.c | |
46 | @@ -474,13 +474,13 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_transitio | |
47 | * SYSFS INTERFACE * | |
48 | *********************************************************************/ | |
49 | static ssize_t show_boost(struct kobject *kobj, | |
50 | - struct attribute *attr, char *buf) | |
51 | + struct kobj_attribute *attr, char *buf) | |
52 | { | |
53 | return sprintf(buf, "%d\n", cpufreq_driver->boost_enabled); | |
54 | } | |
55 | ||
56 | -static ssize_t store_boost(struct kobject *kobj, struct attribute *attr, | |
57 | - const char *buf, size_t count) | |
58 | +static ssize_t store_boost(struct kobject *kobj, struct kobj_attribute *attr, | |
59 | + const char *buf, size_t count) | |
60 | { | |
61 | int ret, enable; | |
62 | ||
63 | --- a/drivers/cpufreq/cpufreq_governor.h | |
64 | +++ b/drivers/cpufreq/cpufreq_governor.h | |
65 | @@ -48,11 +48,11 @@ enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; | |
66 | ||
67 | /* Create attributes */ | |
68 | #define gov_sys_attr_ro(_name) \ | |
69 | -static struct global_attr _name##_gov_sys = \ | |
70 | +static struct kobj_attribute _name##_gov_sys = \ | |
71 | __ATTR(_name, 0444, show_##_name##_gov_sys, NULL) | |
72 | ||
73 | #define gov_sys_attr_rw(_name) \ | |
74 | -static struct global_attr _name##_gov_sys = \ | |
75 | +static struct kobj_attribute _name##_gov_sys = \ | |
76 | __ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys) | |
77 | ||
78 | #define gov_pol_attr_ro(_name) \ | |
79 | @@ -74,7 +74,7 @@ __ATTR(_name, 0644, show_##_name##_gov_p | |
80 | /* Create show/store routines */ | |
81 | #define show_one(_gov, file_name) \ | |
82 | static ssize_t show_##file_name##_gov_sys \ | |
83 | -(struct kobject *kobj, struct attribute *attr, char *buf) \ | |
84 | +(struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ | |
85 | { \ | |
86 | struct _gov##_dbs_tuners *tuners = _gov##_dbs_cdata.gdbs_data->tuners; \ | |
87 | return sprintf(buf, "%u\n", tuners->file_name); \ | |
88 | @@ -90,7 +90,7 @@ static ssize_t show_##file_name##_gov_po | |
89 | ||
90 | #define store_one(_gov, file_name) \ | |
91 | static ssize_t store_##file_name##_gov_sys \ | |
92 | -(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) \ | |
93 | +(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) \ | |
94 | { \ | |
95 | struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ | |
96 | return store_##file_name(dbs_data, buf, count); \ | |
97 | @@ -254,7 +254,7 @@ static inline int delay_for_sampling_rat | |
98 | ||
99 | #define declare_show_sampling_rate_min(_gov) \ | |
100 | static ssize_t show_sampling_rate_min_gov_sys \ | |
101 | -(struct kobject *kobj, struct attribute *attr, char *buf) \ | |
102 | +(struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ | |
103 | { \ | |
104 | struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ | |
105 | return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ | |
106 | --- a/drivers/cpufreq/intel_pstate.c | |
107 | +++ b/drivers/cpufreq/intel_pstate.c | |
108 | @@ -368,13 +368,13 @@ static void __init intel_pstate_debug_ex | |
109 | /************************** sysfs begin ************************/ | |
110 | #define show_one(file_name, object) \ | |
111 | static ssize_t show_##file_name \ | |
112 | - (struct kobject *kobj, struct attribute *attr, char *buf) \ | |
113 | + (struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ | |
114 | { \ | |
115 | return sprintf(buf, "%u\n", limits->object); \ | |
116 | } | |
117 | ||
118 | static ssize_t show_turbo_pct(struct kobject *kobj, | |
119 | - struct attribute *attr, char *buf) | |
120 | + struct kobj_attribute *attr, char *buf) | |
121 | { | |
122 | struct cpudata *cpu; | |
123 | int total, no_turbo, turbo_pct; | |
124 | @@ -390,7 +390,7 @@ static ssize_t show_turbo_pct(struct kob | |
125 | } | |
126 | ||
127 | static ssize_t show_num_pstates(struct kobject *kobj, | |
128 | - struct attribute *attr, char *buf) | |
129 | + struct kobj_attribute *attr, char *buf) | |
130 | { | |
131 | struct cpudata *cpu; | |
132 | int total; | |
133 | @@ -401,7 +401,7 @@ static ssize_t show_num_pstates(struct k | |
134 | } | |
135 | ||
136 | static ssize_t show_no_turbo(struct kobject *kobj, | |
137 | - struct attribute *attr, char *buf) | |
138 | + struct kobj_attribute *attr, char *buf) | |
139 | { | |
140 | ssize_t ret; | |
141 | ||
142 | @@ -414,7 +414,7 @@ static ssize_t show_no_turbo(struct kobj | |
143 | return ret; | |
144 | } | |
145 | ||
146 | -static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, | |
147 | +static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, | |
148 | const char *buf, size_t count) | |
149 | { | |
150 | unsigned int input; | |
151 | @@ -438,7 +438,7 @@ static ssize_t store_no_turbo(struct kob | |
152 | return count; | |
153 | } | |
154 | ||
155 | -static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, | |
156 | +static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b, | |
157 | const char *buf, size_t count) | |
158 | { | |
159 | unsigned int input; | |
160 | @@ -463,7 +463,7 @@ static ssize_t store_max_perf_pct(struct | |
161 | return count; | |
162 | } | |
163 | ||
164 | -static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |
165 | +static ssize_t store_min_perf_pct(struct kobject *a, struct kobj_attribute *b, | |
166 | const char *buf, size_t count) | |
167 | { | |
168 | unsigned int input; | |
169 | --- a/include/linux/cpufreq.h | |
170 | +++ b/include/linux/cpufreq.h | |
171 | @@ -203,20 +203,12 @@ __ATTR(_name, _perm, show_##_name, NULL) | |
172 | static struct freq_attr _name = \ | |
173 | __ATTR(_name, 0644, show_##_name, store_##_name) | |
174 | ||
175 | -struct global_attr { | |
176 | - struct attribute attr; | |
177 | - ssize_t (*show)(struct kobject *kobj, | |
178 | - struct attribute *attr, char *buf); | |
179 | - ssize_t (*store)(struct kobject *a, struct attribute *b, | |
180 | - const char *c, size_t count); | |
181 | -}; | |
182 | - | |
183 | #define define_one_global_ro(_name) \ | |
184 | -static struct global_attr _name = \ | |
185 | +static struct kobj_attribute _name = \ | |
186 | __ATTR(_name, 0444, show_##_name, NULL) | |
187 | ||
188 | #define define_one_global_rw(_name) \ | |
189 | -static struct global_attr _name = \ | |
190 | +static struct kobj_attribute _name = \ | |
191 | __ATTR(_name, 0644, show_##_name, store_##_name) | |
192 | ||
193 |