diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-10-15 13:35:20 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-10-16 07:02:45 -0400 |
commit | 2d8b39a62a5d386a73f339e46fe05354a3a4895b (patch) | |
tree | 278bb10df8488575ff7e8fb9d52cd09ebeda2180 | |
parent | 65650b35133ff20f0c9ef0abd5c3c66dbce3ae57 (diff) |
ACPI: processor: Avoid NULL pointer dereferences at init time
If there are neither processor objects nor processor device objects
in the ACPI tables, the per-CPU processors table will not be
initialized and attempting to dereference pointers from there will
cause the kernel to crash. This happens in acpi_processor_ppc_init()
and acpi_thermal_cpufreq_init() after commit d15ce412737a ("ACPI:
cpufreq: Switch to QoS requests instead of cpufreq notifier")
which didn't add the requisite NULL pointer checks in there.
Add the NULL pointer checks to acpi_processor_ppc_init() and
acpi_thermal_cpufreq_init(), and to the corresponding "exit"
routines.
While at it, drop redundant return instructions from
acpi_processor_ppc_init() and acpi_thermal_cpufreq_init().
Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier")
Reported-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r-- | drivers/acpi/processor_perflib.c | 10 | ||||
-rw-r--r-- | drivers/acpi/processor_thermal.c | 10 |
2 files changed, 12 insertions, 8 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 2261713d1aec..930a49fa4dfc 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -162,21 +162,23 @@ void acpi_processor_ppc_init(int cpu) | |||
162 | struct acpi_processor *pr = per_cpu(processors, cpu); | 162 | struct acpi_processor *pr = per_cpu(processors, cpu); |
163 | int ret; | 163 | int ret; |
164 | 164 | ||
165 | if (!pr) | ||
166 | return; | ||
167 | |||
165 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), | 168 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), |
166 | &pr->perflib_req, DEV_PM_QOS_MAX_FREQUENCY, | 169 | &pr->perflib_req, DEV_PM_QOS_MAX_FREQUENCY, |
167 | INT_MAX); | 170 | INT_MAX); |
168 | if (ret < 0) { | 171 | if (ret < 0) |
169 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, | 172 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, |
170 | ret); | 173 | ret); |
171 | return; | ||
172 | } | ||
173 | } | 174 | } |
174 | 175 | ||
175 | void acpi_processor_ppc_exit(int cpu) | 176 | void acpi_processor_ppc_exit(int cpu) |
176 | { | 177 | { |
177 | struct acpi_processor *pr = per_cpu(processors, cpu); | 178 | struct acpi_processor *pr = per_cpu(processors, cpu); |
178 | 179 | ||
179 | dev_pm_qos_remove_request(&pr->perflib_req); | 180 | if (pr) |
181 | dev_pm_qos_remove_request(&pr->perflib_req); | ||
180 | } | 182 | } |
181 | 183 | ||
182 | static int acpi_processor_get_performance_control(struct acpi_processor *pr) | 184 | static int acpi_processor_get_performance_control(struct acpi_processor *pr) |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ec2638f1df4f..8227c7dd75b1 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -130,21 +130,23 @@ void acpi_thermal_cpufreq_init(int cpu) | |||
130 | struct acpi_processor *pr = per_cpu(processors, cpu); | 130 | struct acpi_processor *pr = per_cpu(processors, cpu); |
131 | int ret; | 131 | int ret; |
132 | 132 | ||
133 | if (!pr) | ||
134 | return; | ||
135 | |||
133 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), | 136 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), |
134 | &pr->thermal_req, DEV_PM_QOS_MAX_FREQUENCY, | 137 | &pr->thermal_req, DEV_PM_QOS_MAX_FREQUENCY, |
135 | INT_MAX); | 138 | INT_MAX); |
136 | if (ret < 0) { | 139 | if (ret < 0) |
137 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, | 140 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, |
138 | ret); | 141 | ret); |
139 | return; | ||
140 | } | ||
141 | } | 142 | } |
142 | 143 | ||
143 | void acpi_thermal_cpufreq_exit(int cpu) | 144 | void acpi_thermal_cpufreq_exit(int cpu) |
144 | { | 145 | { |
145 | struct acpi_processor *pr = per_cpu(processors, cpu); | 146 | struct acpi_processor *pr = per_cpu(processors, cpu); |
146 | 147 | ||
147 | dev_pm_qos_remove_request(&pr->thermal_req); | 148 | if (pr) |
149 | dev_pm_qos_remove_request(&pr->thermal_req); | ||
148 | } | 150 | } |
149 | #else /* ! CONFIG_CPU_FREQ */ | 151 | #else /* ! CONFIG_CPU_FREQ */ |
150 | static int cpufreq_get_max_state(unsigned int cpu) | 152 | static int cpufreq_get_max_state(unsigned int cpu) |