Skip to content

Commit 298bd7f

Browse files
committed
Merge branches 'acpi-sysfs', 'acpi-apei' and 'acpi-blacklist'
* acpi-sysfs: ACPI / sysfs: Extend ACPI sysfs to provide access to boot error region * acpi-apei: ACPI / APEI: Suppress message if HEST not present ACPI, APEI, EINJ: Subtract any matching Register Region from Trigger resources ACPI: APEI: fix the wrong iteration of generic error status block ACPI: APEI: Enable APEI multiple GHES source to share a single external IRQ * acpi-blacklist: intel_pstate: convert to use acpi_match_platform_list() ACPI / blacklist: add acpi_match_platform_list()
4 parents 940c8df + 7dae632 + e931d0d + 5e93232 commit 298bd7f

File tree

12 files changed

+203
-133
lines changed

12 files changed

+203
-133
lines changed

drivers/acpi/apei/apei-internal.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,6 @@ int apei_exec_collect_resources(struct apei_exec_context *ctx,
120120
struct dentry;
121121
struct dentry *apei_get_debugfs_dir(void);
122122

123-
#define apei_estatus_for_each_section(estatus, section) \
124-
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
125-
(void *)section - (void *)estatus < estatus->data_length; \
126-
section = (void *)(section+1) + section->error_data_length)
127-
128123
static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)
129124
{
130125
if (estatus->raw_data_length)

drivers/acpi/apei/einj.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ static struct acpi_generic_address *einj_get_trigger_parameter_region(
281281
((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
282282
for (i = 0; i < trigger_tab->entry_count; i++) {
283283
if (entry->action == ACPI_EINJ_TRIGGER_ERROR &&
284-
entry->instruction == ACPI_EINJ_WRITE_REGISTER_VALUE &&
284+
entry->instruction <= ACPI_EINJ_WRITE_REGISTER_VALUE &&
285285
entry->register_region.space_id ==
286286
ACPI_ADR_SPACE_SYSTEM_MEMORY &&
287287
(entry->register_region.address & param2) == (param1 & param2))

drivers/acpi/apei/ghes.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,8 @@ static int ghes_probe(struct platform_device *ghes_dev)
11571157
generic->header.source_id);
11581158
goto err_edac_unreg;
11591159
}
1160-
rc = request_irq(ghes->irq, ghes_irq_func, 0, "GHES IRQ", ghes);
1160+
rc = request_irq(ghes->irq, ghes_irq_func, IRQF_SHARED,
1161+
"GHES IRQ", ghes);
11611162
if (rc) {
11621163
pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
11631164
generic->header.source_id);
@@ -1265,9 +1266,14 @@ static int __init ghes_init(void)
12651266
if (acpi_disabled)
12661267
return -ENODEV;
12671268

1268-
if (hest_disable) {
1269+
switch (hest_disable) {
1270+
case HEST_NOT_FOUND:
1271+
return -ENODEV;
1272+
case HEST_DISABLED:
12691273
pr_info(GHES_PFX "HEST is not enabled!\n");
12701274
return -EINVAL;
1275+
default:
1276+
break;
12711277
}
12721278

12731279
if (ghes_disable) {

drivers/acpi/apei/hest.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
#define HEST_PFX "HEST: "
3939

40-
bool hest_disable;
40+
int hest_disable;
4141
EXPORT_SYMBOL_GPL(hest_disable);
4242

4343
/* HEST table parsing */
@@ -213,7 +213,7 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count)
213213

214214
static int __init setup_hest_disable(char *str)
215215
{
216-
hest_disable = 1;
216+
hest_disable = HEST_DISABLED;
217217
return 0;
218218
}
219219

@@ -232,9 +232,10 @@ void __init acpi_hest_init(void)
232232

233233
status = acpi_get_table(ACPI_SIG_HEST, 0,
234234
(struct acpi_table_header **)&hest_tab);
235-
if (status == AE_NOT_FOUND)
236-
goto err;
237-
else if (ACPI_FAILURE(status)) {
235+
if (status == AE_NOT_FOUND) {
236+
hest_disable = HEST_NOT_FOUND;
237+
return;
238+
} else if (ACPI_FAILURE(status)) {
238239
const char *msg = acpi_format_exception(status);
239240
pr_err(HEST_PFX "Failed to get table, %s\n", msg);
240241
rc = -EINVAL;
@@ -257,5 +258,5 @@ void __init acpi_hest_init(void)
257258
pr_info(HEST_PFX "Table parsing has been initialized.\n");
258259
return;
259260
err:
260-
hest_disable = 1;
261+
hest_disable = HEST_DISABLED;
261262
}

drivers/acpi/blacklist.c

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,13 @@
3030

3131
#include "internal.h"
3232

33-
enum acpi_blacklist_predicates {
34-
all_versions,
35-
less_than_or_equal,
36-
equal,
37-
greater_than_or_equal,
38-
};
39-
40-
struct acpi_blacklist_item {
41-
char oem_id[7];
42-
char oem_table_id[9];
43-
u32 oem_revision;
44-
char *table;
45-
enum acpi_blacklist_predicates oem_revision_predicate;
46-
char *reason;
47-
u32 is_critical_error;
48-
};
49-
5033
static struct dmi_system_id acpi_rev_dmi_table[] __initdata;
5134

5235
/*
5336
* POLICY: If *anything* doesn't work, put it on the blacklist.
5437
* If they are critical errors, mark it critical, and abort driver load.
5538
*/
56-
static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
39+
static struct acpi_platform_list acpi_blacklist[] __initdata = {
5740
/* Compaq Presario 1700 */
5841
{"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
5942
"Multiple problems", 1},
@@ -67,65 +50,27 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
6750
{"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
6851
"Incorrect _ADR", 1},
6952

70-
{""}
53+
{ }
7154
};
7255

7356
int __init acpi_blacklisted(void)
7457
{
75-
int i = 0;
58+
int i;
7659
int blacklisted = 0;
77-
struct acpi_table_header table_header;
78-
79-
while (acpi_blacklist[i].oem_id[0] != '\0') {
80-
if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
81-
i++;
82-
continue;
83-
}
84-
85-
if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
86-
i++;
87-
continue;
88-
}
89-
90-
if (strncmp
91-
(acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
92-
8)) {
93-
i++;
94-
continue;
95-
}
96-
97-
if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
98-
|| (acpi_blacklist[i].oem_revision_predicate ==
99-
less_than_or_equal
100-
&& table_header.oem_revision <=
101-
acpi_blacklist[i].oem_revision)
102-
|| (acpi_blacklist[i].oem_revision_predicate ==
103-
greater_than_or_equal
104-
&& table_header.oem_revision >=
105-
acpi_blacklist[i].oem_revision)
106-
|| (acpi_blacklist[i].oem_revision_predicate == equal
107-
&& table_header.oem_revision ==
108-
acpi_blacklist[i].oem_revision)) {
10960

110-
printk(KERN_ERR PREFIX
111-
"Vendor \"%6.6s\" System \"%8.8s\" "
112-
"Revision 0x%x has a known ACPI BIOS problem.\n",
113-
acpi_blacklist[i].oem_id,
114-
acpi_blacklist[i].oem_table_id,
115-
acpi_blacklist[i].oem_revision);
61+
i = acpi_match_platform_list(acpi_blacklist);
62+
if (i >= 0) {
63+
pr_err(PREFIX "Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n",
64+
acpi_blacklist[i].oem_id,
65+
acpi_blacklist[i].oem_table_id,
66+
acpi_blacklist[i].oem_revision);
11667

117-
printk(KERN_ERR PREFIX
118-
"Reason: %s. This is a %s error\n",
119-
acpi_blacklist[i].reason,
120-
(acpi_blacklist[i].
121-
is_critical_error ? "non-recoverable" :
122-
"recoverable"));
68+
pr_err(PREFIX "Reason: %s. This is a %s error\n",
69+
acpi_blacklist[i].reason,
70+
(acpi_blacklist[i].data ?
71+
"non-recoverable" : "recoverable"));
12372

124-
blacklisted = acpi_blacklist[i].is_critical_error;
125-
break;
126-
} else {
127-
i++;
128-
}
73+
blacklisted = acpi_blacklist[i].data;
12974
}
13075

13176
(void)early_acpi_osi_init();

drivers/acpi/sysfs.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,13 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
308308
/*
309309
* ACPI table sysfs I/F:
310310
* /sys/firmware/acpi/tables/
311+
* /sys/firmware/acpi/tables/data/
311312
* /sys/firmware/acpi/tables/dynamic/
312313
*/
313314

314315
static LIST_HEAD(acpi_table_attr_list);
315316
static struct kobject *tables_kobj;
317+
static struct kobject *tables_data_kobj;
316318
static struct kobject *dynamic_tables_kobj;
317319
static struct kobject *hotplug_kobj;
318320

@@ -327,6 +329,11 @@ struct acpi_table_attr {
327329
struct list_head node;
328330
};
329331

332+
struct acpi_data_attr {
333+
struct bin_attribute attr;
334+
u64 addr;
335+
};
336+
330337
static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,
331338
struct bin_attribute *bin_attr, char *buf,
332339
loff_t offset, size_t count)
@@ -422,6 +429,70 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
422429
return AE_OK;
423430
}
424431

432+
static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
433+
struct bin_attribute *bin_attr, char *buf,
434+
loff_t offset, size_t count)
435+
{
436+
struct acpi_data_attr *data_attr;
437+
void __iomem *base;
438+
ssize_t rc;
439+
440+
data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
441+
442+
base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size);
443+
if (!base)
444+
return -ENOMEM;
445+
rc = memory_read_from_buffer(buf, count, &offset, base,
446+
data_attr->attr.size);
447+
acpi_os_unmap_memory(base, data_attr->attr.size);
448+
449+
return rc;
450+
}
451+
452+
static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
453+
{
454+
struct acpi_table_bert *bert = th;
455+
456+
if (bert->header.length < sizeof(struct acpi_table_bert) ||
457+
bert->region_length < sizeof(struct acpi_hest_generic_status)) {
458+
kfree(data_attr);
459+
return -EINVAL;
460+
}
461+
data_attr->addr = bert->address;
462+
data_attr->attr.size = bert->region_length;
463+
data_attr->attr.attr.name = "BERT";
464+
465+
return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
466+
}
467+
468+
static struct acpi_data_obj {
469+
char *name;
470+
int (*fn)(void *, struct acpi_data_attr *);
471+
} acpi_data_objs[] = {
472+
{ ACPI_SIG_BERT, acpi_bert_data_init },
473+
};
474+
475+
#define NUM_ACPI_DATA_OBJS ARRAY_SIZE(acpi_data_objs)
476+
477+
static int acpi_table_data_init(struct acpi_table_header *th)
478+
{
479+
struct acpi_data_attr *data_attr;
480+
int i;
481+
482+
for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) {
483+
if (ACPI_COMPARE_NAME(th->signature, acpi_data_objs[i].name)) {
484+
data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL);
485+
if (!data_attr)
486+
return -ENOMEM;
487+
sysfs_attr_init(&data_attr->attr.attr);
488+
data_attr->attr.read = acpi_data_show;
489+
data_attr->attr.attr.mode = 0400;
490+
return acpi_data_objs[i].fn(th, data_attr);
491+
}
492+
}
493+
return 0;
494+
}
495+
425496
static int acpi_tables_sysfs_init(void)
426497
{
427498
struct acpi_table_attr *table_attr;
@@ -434,6 +505,10 @@ static int acpi_tables_sysfs_init(void)
434505
if (!tables_kobj)
435506
goto err;
436507

508+
tables_data_kobj = kobject_create_and_add("data", tables_kobj);
509+
if (!tables_data_kobj)
510+
goto err_tables_data;
511+
437512
dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
438513
if (!dynamic_tables_kobj)
439514
goto err_dynamic_tables;
@@ -458,13 +533,17 @@ static int acpi_tables_sysfs_init(void)
458533
return ret;
459534
}
460535
list_add_tail(&table_attr->node, &acpi_table_attr_list);
536+
acpi_table_data_init(table_header);
461537
}
462538

463539
kobject_uevent(tables_kobj, KOBJ_ADD);
540+
kobject_uevent(tables_data_kobj, KOBJ_ADD);
464541
kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
465542

466543
return 0;
467544
err_dynamic_tables:
545+
kobject_put(tables_data_kobj);
546+
err_tables_data:
468547
kobject_put(tables_kobj);
469548
err:
470549
return -ENOMEM;

drivers/acpi/utils.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,3 +816,39 @@ static int __init acpi_backlight(char *str)
816816
return 1;
817817
}
818818
__setup("acpi_backlight=", acpi_backlight);
819+
820+
/**
821+
* acpi_match_platform_list - Check if the system matches with a given list
822+
* @plat: pointer to acpi_platform_list table terminated by a NULL entry
823+
*
824+
* Return the matched index if the system is found in the platform list.
825+
* Otherwise, return a negative error code.
826+
*/
827+
int acpi_match_platform_list(const struct acpi_platform_list *plat)
828+
{
829+
struct acpi_table_header hdr;
830+
int idx = 0;
831+
832+
if (acpi_disabled)
833+
return -ENODEV;
834+
835+
for (; plat->oem_id[0]; plat++, idx++) {
836+
if (ACPI_FAILURE(acpi_get_table_header(plat->table, 0, &hdr)))
837+
continue;
838+
839+
if (strncmp(plat->oem_id, hdr.oem_id, ACPI_OEM_ID_SIZE))
840+
continue;
841+
842+
if (strncmp(plat->oem_table_id, hdr.oem_table_id, ACPI_OEM_TABLE_ID_SIZE))
843+
continue;
844+
845+
if ((plat->pred == all_versions) ||
846+
(plat->pred == less_than_or_equal && hdr.oem_revision <= plat->oem_revision) ||
847+
(plat->pred == greater_than_or_equal && hdr.oem_revision >= plat->oem_revision) ||
848+
(plat->pred == equal && hdr.oem_revision == plat->oem_revision))
849+
return idx;
850+
}
851+
852+
return -ENODEV;
853+
}
854+
EXPORT_SYMBOL(acpi_match_platform_list);

0 commit comments

Comments
 (0)