Skip to content

Commit 22349e7

Browse files
committed
Merge branches 'acpi-pm', 'acpi-video', 'acpi-apei' and 'acpi-extlog'
Merge an ACPI power management change, ACPI backlight driver changes, APEI updates and ACPI extlog driver changes for 6.8-rc1: - Modify the ACPI LPIT table handling code to avoid u32 multiplication overflows in state residency computations (Nikita Kiryushin). - Drop an unused helper function from the ACPI backlight (video) driver and add a clarifying comment to it (Hans de Goede). - Update the ACPI backlight driver to avoid using uninitialized memory in some cases (Nikita Kiryushin). - Add ACPI backlight quirk for the Colorful X15 AT 23 laptop (Yuluo Qiu). - Add support for vendor-defined error types to the ACPI APEI error injection code (Avadhut Naik). - Adjust APEI to properly set MF_ACTION_REQUIRED on synchronous memory failure events, so they are handled differently from the asynchronous ones (Shuai Xue). - Fix NULL pointer dereference check in the ACPI extlog driver (Prarit Bhargava). - Adjust the ACPI extlog driver to clear the Extended Error Log status when RAS_CEC handled the error (Tony Luck). * acpi-pm: ACPI: LPIT: Avoid u32 multiplication overflow * acpi-video: ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop ACPI: video: check for error while searching for backlight device parent ACPI: video: Drop should_check_lcd_flag() ACPI: video: Add comment about acpi_video_backlight_use_native() usage * acpi-apei: ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous events ACPI: APEI: EINJ: Add support for vendor defined error types platform/chrome: cros_ec_debugfs: Fix permissions for panicinfo fs: debugfs: Add write functionality to debugfs blobs ACPI: APEI: EINJ: Refactor available_error_type_show() * acpi-extlog: ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error ACPI: extlog: fix NULL pointer dereference check
5 parents f845351 + 56d2eed + 143176a + a70297d + 38c872a commit 22349e7

File tree

8 files changed

+130
-100
lines changed

8 files changed

+130
-100
lines changed

drivers/acpi/acpi_extlog.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
145145
static u32 err_seq;
146146

147147
estatus = extlog_elog_entry_check(cpu, bank);
148-
if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC))
148+
if (!estatus)
149149
return NOTIFY_DONE;
150150

151+
if (mce->kflags & MCE_HANDLED_CEC) {
152+
estatus->block_status = 0;
153+
return NOTIFY_DONE;
154+
}
155+
151156
memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
152157
/* clear record status to enable BIOS to update it again */
153158
estatus->block_status = 0;
@@ -303,9 +308,10 @@ static int __init extlog_init(void)
303308
static void __exit extlog_exit(void)
304309
{
305310
mce_unregister_decode_chain(&extlog_mce_dec);
306-
((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
307-
if (extlog_l1_addr)
311+
if (extlog_l1_addr) {
312+
((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
308313
acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
314+
}
309315
if (elog_addr)
310316
acpi_os_unmap_iomem(elog_addr, elog_size);
311317
release_mem_region(elog_base, elog_size);

drivers/acpi/acpi_lpit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static void lpit_update_residency(struct lpit_residency_info *info,
105105
return;
106106

107107
info->frequency = lpit_native->counter_frequency ?
108-
lpit_native->counter_frequency : tsc_khz * 1000;
108+
lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U);
109109
if (!info->frequency)
110110
info->frequency = 1;
111111

drivers/acpi/acpi_video.c

Lines changed: 16 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ MODULE_PARM_DESC(hw_changes_brightness,
6767
static bool device_id_scheme = false;
6868
module_param(device_id_scheme, bool, 0444);
6969

70-
static int only_lcd = -1;
70+
static int only_lcd;
7171
module_param(only_lcd, int, 0444);
7272

7373
static bool may_report_brightness_keys;
@@ -500,6 +500,15 @@ static const struct dmi_system_id video_dmi_table[] = {
500500
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"),
501501
},
502502
},
503+
{
504+
.callback = video_set_report_key_events,
505+
.driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS),
506+
.ident = "COLORFUL X15 AT 23",
507+
.matches = {
508+
DMI_MATCH(DMI_SYS_VENDOR, "COLORFUL"),
509+
DMI_MATCH(DMI_PRODUCT_NAME, "X15 AT 23"),
510+
},
511+
},
503512
/*
504513
* Some machines change the brightness themselves when a brightness
505514
* hotkey gets pressed, despite us telling them not to. In this case
@@ -1713,12 +1722,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
17131722
return;
17141723
count++;
17151724

1716-
acpi_get_parent(device->dev->handle, &acpi_parent);
1717-
1718-
pdev = acpi_get_pci_dev(acpi_parent);
1719-
if (pdev) {
1720-
parent = &pdev->dev;
1721-
pci_dev_put(pdev);
1725+
if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) {
1726+
pdev = acpi_get_pci_dev(acpi_parent);
1727+
if (pdev) {
1728+
parent = &pdev->dev;
1729+
pci_dev_put(pdev);
1730+
}
17221731
}
17231732

17241733
memset(&props, 0, sizeof(struct backlight_properties));
@@ -2137,57 +2146,6 @@ static int __init intel_opregion_present(void)
21372146
return opregion;
21382147
}
21392148

2140-
/* Check if the chassis-type indicates there is no builtin LCD panel */
2141-
static bool dmi_is_desktop(void)
2142-
{
2143-
const char *chassis_type;
2144-
unsigned long type;
2145-
2146-
chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
2147-
if (!chassis_type)
2148-
return false;
2149-
2150-
if (kstrtoul(chassis_type, 10, &type) != 0)
2151-
return false;
2152-
2153-
switch (type) {
2154-
case 0x03: /* Desktop */
2155-
case 0x04: /* Low Profile Desktop */
2156-
case 0x05: /* Pizza Box */
2157-
case 0x06: /* Mini Tower */
2158-
case 0x07: /* Tower */
2159-
case 0x10: /* Lunch Box */
2160-
case 0x11: /* Main Server Chassis */
2161-
return true;
2162-
}
2163-
2164-
return false;
2165-
}
2166-
2167-
/*
2168-
* We're seeing a lot of bogus backlight interfaces on newer machines
2169-
* without a LCD such as desktops, servers and HDMI sticks. Checking the
2170-
* lcd flag fixes this, enable this by default on any machines which are:
2171-
* 1. Win8 ready (where we also prefer the native backlight driver, so
2172-
* normally the acpi_video code should not register there anyways); *and*
2173-
* 2.1 Report a desktop/server DMI chassis-type, or
2174-
* 2.2 Are an ACPI-reduced-hardware platform (and thus won't use the EC for
2175-
backlight control)
2176-
*/
2177-
static bool should_check_lcd_flag(void)
2178-
{
2179-
if (!acpi_osi_is_win8())
2180-
return false;
2181-
2182-
if (dmi_is_desktop())
2183-
return true;
2184-
2185-
if (acpi_reduced_hardware())
2186-
return true;
2187-
2188-
return false;
2189-
}
2190-
21912149
int acpi_video_register(void)
21922150
{
21932151
int ret = 0;
@@ -2201,9 +2159,6 @@ int acpi_video_register(void)
22012159
goto leave;
22022160
}
22032161

2204-
if (only_lcd == -1)
2205-
only_lcd = should_check_lcd_flag();
2206-
22072162
dmi_check_system(video_dmi_table);
22082163

22092164
ret = acpi_bus_register_driver(&acpi_video_bus);

drivers/acpi/apei/einj.c

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ static u32 notrigger;
7373

7474
static u32 vendor_flags;
7575
static struct debugfs_blob_wrapper vendor_blob;
76+
static struct debugfs_blob_wrapper vendor_errors;
7677
static char vendor_dev[64];
7778

7879
/*
@@ -182,6 +183,21 @@ static int einj_timedout(u64 *t)
182183
return 0;
183184
}
184185

186+
static void get_oem_vendor_struct(u64 paddr, int offset,
187+
struct vendor_error_type_extension *v)
188+
{
189+
unsigned long vendor_size;
190+
u64 target_pa = paddr + offset + sizeof(struct vendor_error_type_extension);
191+
192+
vendor_size = v->length - sizeof(struct vendor_error_type_extension);
193+
194+
if (vendor_size)
195+
vendor_errors.data = acpi_os_map_memory(target_pa, vendor_size);
196+
197+
if (vendor_errors.data)
198+
vendor_errors.size = vendor_size;
199+
}
200+
185201
static void check_vendor_extension(u64 paddr,
186202
struct set_error_type_with_address *v5param)
187203
{
@@ -194,6 +210,7 @@ static void check_vendor_extension(u64 paddr,
194210
v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
195211
if (!v)
196212
return;
213+
get_oem_vendor_struct(paddr, offset, v);
197214
sbdf = v->pcie_sbdf;
198215
sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
199216
sbdf >> 24, (sbdf >> 16) & 0xff,
@@ -577,38 +594,40 @@ static u64 error_param2;
577594
static u64 error_param3;
578595
static u64 error_param4;
579596
static struct dentry *einj_debug_dir;
580-
static const char * const einj_error_type_string[] = {
581-
"0x00000001\tProcessor Correctable\n",
582-
"0x00000002\tProcessor Uncorrectable non-fatal\n",
583-
"0x00000004\tProcessor Uncorrectable fatal\n",
584-
"0x00000008\tMemory Correctable\n",
585-
"0x00000010\tMemory Uncorrectable non-fatal\n",
586-
"0x00000020\tMemory Uncorrectable fatal\n",
587-
"0x00000040\tPCI Express Correctable\n",
588-
"0x00000080\tPCI Express Uncorrectable non-fatal\n",
589-
"0x00000100\tPCI Express Uncorrectable fatal\n",
590-
"0x00000200\tPlatform Correctable\n",
591-
"0x00000400\tPlatform Uncorrectable non-fatal\n",
592-
"0x00000800\tPlatform Uncorrectable fatal\n",
593-
"0x00001000\tCXL.cache Protocol Correctable\n",
594-
"0x00002000\tCXL.cache Protocol Uncorrectable non-fatal\n",
595-
"0x00004000\tCXL.cache Protocol Uncorrectable fatal\n",
596-
"0x00008000\tCXL.mem Protocol Correctable\n",
597-
"0x00010000\tCXL.mem Protocol Uncorrectable non-fatal\n",
598-
"0x00020000\tCXL.mem Protocol Uncorrectable fatal\n",
597+
static struct { u32 mask; const char *str; } const einj_error_type_string[] = {
598+
{ BIT(0), "Processor Correctable" },
599+
{ BIT(1), "Processor Uncorrectable non-fatal" },
600+
{ BIT(2), "Processor Uncorrectable fatal" },
601+
{ BIT(3), "Memory Correctable" },
602+
{ BIT(4), "Memory Uncorrectable non-fatal" },
603+
{ BIT(5), "Memory Uncorrectable fatal" },
604+
{ BIT(6), "PCI Express Correctable" },
605+
{ BIT(7), "PCI Express Uncorrectable non-fatal" },
606+
{ BIT(8), "PCI Express Uncorrectable fatal" },
607+
{ BIT(9), "Platform Correctable" },
608+
{ BIT(10), "Platform Uncorrectable non-fatal" },
609+
{ BIT(11), "Platform Uncorrectable fatal"},
610+
{ BIT(12), "CXL.cache Protocol Correctable" },
611+
{ BIT(13), "CXL.cache Protocol Uncorrectable non-fatal" },
612+
{ BIT(14), "CXL.cache Protocol Uncorrectable fatal" },
613+
{ BIT(15), "CXL.mem Protocol Correctable" },
614+
{ BIT(16), "CXL.mem Protocol Uncorrectable non-fatal" },
615+
{ BIT(17), "CXL.mem Protocol Uncorrectable fatal" },
616+
{ BIT(31), "Vendor Defined Error Types" },
599617
};
600618

601619
static int available_error_type_show(struct seq_file *m, void *v)
602620
{
603621
int rc;
604-
u32 available_error_type = 0;
622+
u32 error_type = 0;
605623

606-
rc = einj_get_available_error_type(&available_error_type);
624+
rc = einj_get_available_error_type(&error_type);
607625
if (rc)
608626
return rc;
609627
for (int pos = 0; pos < ARRAY_SIZE(einj_error_type_string); pos++)
610-
if (available_error_type & BIT(pos))
611-
seq_puts(m, einj_error_type_string[pos]);
628+
if (error_type & einj_error_type_string[pos].mask)
629+
seq_printf(m, "0x%08x\t%s\n", einj_error_type_string[pos].mask,
630+
einj_error_type_string[pos].str);
612631

613632
return 0;
614633
}
@@ -767,6 +786,10 @@ static int __init einj_init(void)
767786
einj_debug_dir, &vendor_flags);
768787
}
769788

789+
if (vendor_errors.size)
790+
debugfs_create_blob("oem_error", 0600, einj_debug_dir,
791+
&vendor_errors);
792+
770793
pr_info("Error INJection is initialized.\n");
771794

772795
return 0;
@@ -792,6 +815,8 @@ static void __exit einj_exit(void)
792815
sizeof(struct einj_parameter);
793816

794817
acpi_os_unmap_iomem(einj_param, size);
818+
if (vendor_errors.size)
819+
acpi_os_unmap_memory(vendor_errors.data, vendor_errors.size);
795820
}
796821
einj_exec_ctx_init(&ctx);
797822
apei_exec_post_unmap_gars(&ctx);

drivers/acpi/apei/ghes.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@ static inline bool is_hest_type_generic_v2(struct ghes *ghes)
101101
return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2;
102102
}
103103

104+
/*
105+
* A platform may describe one error source for the handling of synchronous
106+
* errors (e.g. MCE or SEA), or for handling asynchronous errors (e.g. SCI
107+
* or External Interrupt). On x86, the HEST notifications are always
108+
* asynchronous, so only SEA on ARM is delivered as a synchronous
109+
* notification.
110+
*/
111+
static inline bool is_hest_sync_notify(struct ghes *ghes)
112+
{
113+
u8 notify_type = ghes->generic->notify.type;
114+
115+
return notify_type == ACPI_HEST_NOTIFY_SEA;
116+
}
117+
104118
/*
105119
* This driver isn't really modular, however for the time being,
106120
* continuing to use module_param is the easiest way to remain
@@ -489,7 +503,7 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags)
489503
}
490504

491505
static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
492-
int sev)
506+
int sev, bool sync)
493507
{
494508
int flags = -1;
495509
int sec_sev = ghes_severity(gdata->error_severity);
@@ -503,17 +517,19 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
503517
(gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
504518
flags = MF_SOFT_OFFLINE;
505519
if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
506-
flags = 0;
520+
flags = sync ? MF_ACTION_REQUIRED : 0;
507521

508522
if (flags != -1)
509523
return ghes_do_memory_failure(mem_err->physical_addr, flags);
510524

511525
return false;
512526
}
513527

514-
static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
528+
static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
529+
int sev, bool sync)
515530
{
516531
struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
532+
int flags = sync ? MF_ACTION_REQUIRED : 0;
517533
bool queued = false;
518534
int sec_sev, i;
519535
char *p;
@@ -538,7 +554,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int s
538554
* and don't filter out 'corrected' error here.
539555
*/
540556
if (is_cache && has_pa) {
541-
queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0);
557+
queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags);
542558
p += err_info->length;
543559
continue;
544560
}
@@ -666,6 +682,7 @@ static bool ghes_do_proc(struct ghes *ghes,
666682
const guid_t *fru_id = &guid_null;
667683
char *fru_text = "";
668684
bool queued = false;
685+
bool sync = is_hest_sync_notify(ghes);
669686

670687
sev = ghes_severity(estatus->error_severity);
671688
apei_estatus_for_each_section(estatus, gdata) {
@@ -683,13 +700,13 @@ static bool ghes_do_proc(struct ghes *ghes,
683700
atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
684701

685702
arch_apei_report_mem_error(sev, mem_err);
686-
queued = ghes_handle_memory_failure(gdata, sev);
703+
queued = ghes_handle_memory_failure(gdata, sev, sync);
687704
}
688705
else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
689706
ghes_handle_aer(gdata);
690707
}
691708
else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
692-
queued = ghes_handle_arm_hw_error(gdata, sev);
709+
queued = ghes_handle_arm_hw_error(gdata, sev, sync);
693710
} else {
694711
void *err = acpi_hest_get_payload(gdata);
695712

drivers/platform/chrome/cros_ec_debugfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
454454
debug_info->panicinfo_blob.data = data;
455455
debug_info->panicinfo_blob.size = ret;
456456

457-
debugfs_create_blob("panicinfo", S_IFREG | 0444, debug_info->dir,
457+
debugfs_create_blob("panicinfo", 0444, debug_info->dir,
458458
&debug_info->panicinfo_blob);
459459

460460
return 0;

0 commit comments

Comments
 (0)