aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 16:01:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 16:01:40 -0400
commitcf482a49af564a3044de3178ea28f10ad5921b38 (patch)
treeb3ce61fc005f73ac6b7b3dfe4b1a4501910bde51 /drivers/acpi/tables.c
parent01e5d1830cf54ac45768ef9ceb3e79cea2e1198c (diff)
parent70e16a620e075cb916644e06012766639b58b2fb (diff)
Merge tag 'driver-core-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core/kobject updates from Greg KH: "Here is the "big" set of driver core patches for 5.2-rc1 There are a number of ACPI patches in here as well, as Rafael said they should go through this tree due to the driver core changes they required. They have all been acked by the ACPI developers. There are also a number of small subsystem-specific changes in here, due to some changes to the kobject core code. Those too have all been acked by the various subsystem maintainers. As for content, it's pretty boring outside of the ACPI changes: - spdx cleanups - kobject documentation updates - default attribute groups for kobjects - other minor kobject/driver core fixes All have been in linux-next for a while with no reported issues" * tag 'driver-core-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (47 commits) kobject: clean up the kobject add documentation a bit more kobject: Fix kernel-doc comment first line kobject: Remove docstring reference to kset firmware_loader: Fix a typo ("syfs" -> "sysfs") kobject: fix dereference before null check on kobj Revert "driver core: platform: Fix the usage of platform device name(pdev->name)" init/config: Do not select BUILD_BIN2C for IKCONFIG Provide in-kernel headers to make extending kernel easier kobject: Improve doc clarity kobject_init_and_add() kobject: Improve docs for kobject_add/del driver core: platform: Fix the usage of platform device name(pdev->name) livepatch: Replace klp_ktype_patch's default_attrs with groups cpufreq: schedutil: Replace default_attrs field with groups padata: Replace padata_attr_type default_attrs field with groups irqdesc: Replace irq_kobj_type's default_attrs field with groups net-sysfs: Replace ktype default_attrs field with groups block: Replace all ktype default_attrs with groups samples/kobject: Replace foo_ktype's default_attrs field with groups kobject: Add support for default attribute groups to kobj_type driver core: Postpone DMA tear-down until after devres release for probe failure ...
Diffstat (limited to 'drivers/acpi/tables.c')
-rw-r--r--drivers/acpi/tables.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index d7bf936b1646..3b5d04fd5e3e 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -49,6 +49,16 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
49 49
50static int acpi_apic_instance __initdata; 50static int acpi_apic_instance __initdata;
51 51
52enum acpi_subtable_type {
53 ACPI_SUBTABLE_COMMON,
54 ACPI_SUBTABLE_HMAT,
55};
56
57struct acpi_subtable_entry {
58 union acpi_subtable_headers *hdr;
59 enum acpi_subtable_type type;
60};
61
52/* 62/*
53 * Disable table checksum verification for the early stage due to the size 63 * Disable table checksum verification for the early stage due to the size
54 * limitation of the current x86 early mapping implementation. 64 * limitation of the current x86 early mapping implementation.
@@ -217,6 +227,50 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
217 } 227 }
218} 228}
219 229
230static unsigned long __init
231acpi_get_entry_type(struct acpi_subtable_entry *entry)
232{
233 switch (entry->type) {
234 case ACPI_SUBTABLE_COMMON:
235 return entry->hdr->common.type;
236 case ACPI_SUBTABLE_HMAT:
237 return entry->hdr->hmat.type;
238 }
239 return 0;
240}
241
242static unsigned long __init
243acpi_get_entry_length(struct acpi_subtable_entry *entry)
244{
245 switch (entry->type) {
246 case ACPI_SUBTABLE_COMMON:
247 return entry->hdr->common.length;
248 case ACPI_SUBTABLE_HMAT:
249 return entry->hdr->hmat.length;
250 }
251 return 0;
252}
253
254static unsigned long __init
255acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
256{
257 switch (entry->type) {
258 case ACPI_SUBTABLE_COMMON:
259 return sizeof(entry->hdr->common);
260 case ACPI_SUBTABLE_HMAT:
261 return sizeof(entry->hdr->hmat);
262 }
263 return 0;
264}
265
266static enum acpi_subtable_type __init
267acpi_get_subtable_type(char *id)
268{
269 if (strncmp(id, ACPI_SIG_HMAT, 4) == 0)
270 return ACPI_SUBTABLE_HMAT;
271 return ACPI_SUBTABLE_COMMON;
272}
273
220/** 274/**
221 * acpi_parse_entries_array - for each proc_num find a suitable subtable 275 * acpi_parse_entries_array - for each proc_num find a suitable subtable
222 * 276 *
@@ -245,8 +299,8 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
245 struct acpi_subtable_proc *proc, int proc_num, 299 struct acpi_subtable_proc *proc, int proc_num,
246 unsigned int max_entries) 300 unsigned int max_entries)
247{ 301{
248 struct acpi_subtable_header *entry; 302 struct acpi_subtable_entry entry;
249 unsigned long table_end; 303 unsigned long table_end, subtable_len, entry_len;
250 int count = 0; 304 int count = 0;
251 int errs = 0; 305 int errs = 0;
252 int i; 306 int i;
@@ -269,19 +323,20 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
269 323
270 /* Parse all entries looking for a match. */ 324 /* Parse all entries looking for a match. */
271 325
272 entry = (struct acpi_subtable_header *) 326 entry.type = acpi_get_subtable_type(id);
327 entry.hdr = (union acpi_subtable_headers *)
273 ((unsigned long)table_header + table_size); 328 ((unsigned long)table_header + table_size);
329 subtable_len = acpi_get_subtable_header_length(&entry);
274 330
275 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < 331 while (((unsigned long)entry.hdr) + subtable_len < table_end) {
276 table_end) {
277 if (max_entries && count >= max_entries) 332 if (max_entries && count >= max_entries)
278 break; 333 break;
279 334
280 for (i = 0; i < proc_num; i++) { 335 for (i = 0; i < proc_num; i++) {
281 if (entry->type != proc[i].id) 336 if (acpi_get_entry_type(&entry) != proc[i].id)
282 continue; 337 continue;
283 if (!proc[i].handler || 338 if (!proc[i].handler ||
284 (!errs && proc[i].handler(entry, table_end))) { 339 (!errs && proc[i].handler(entry.hdr, table_end))) {
285 errs++; 340 errs++;
286 continue; 341 continue;
287 } 342 }
@@ -296,13 +351,14 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
296 * If entry->length is 0, break from this loop to avoid 351 * If entry->length is 0, break from this loop to avoid
297 * infinite loop. 352 * infinite loop.
298 */ 353 */
299 if (entry->length == 0) { 354 entry_len = acpi_get_entry_length(&entry);
355 if (entry_len == 0) {
300 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id); 356 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id);
301 return -EINVAL; 357 return -EINVAL;
302 } 358 }
303 359
304 entry = (struct acpi_subtable_header *) 360 entry.hdr = (union acpi_subtable_headers *)
305 ((unsigned long)entry + entry->length); 361 ((unsigned long)entry.hdr + entry_len);
306 } 362 }
307 363
308 if (max_entries && count > max_entries) { 364 if (max_entries && count > max_entries) {