Commit 64f9111d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-ec', 'acpi-apei', 'acpi-soc' and 'acpi-misc'

* acpi-ec:
  ACPI: EC: trust DSDT GPE for certain HP laptop
  ACPI: EC: Make more Asus laptops use ECDT _GPE

* acpi-apei:
  ACPI: APEI: fix synchronous external aborts in user-mode
  ACPI: APEI: Don't warn if ACPI is disabled

* acpi-soc:
  ACPI: LPSS: Use kstrtol() instead of simple_strtol()

* acpi-misc:
  ACPI: NVS: fix doc warnings in nvs.c
  ACPI: NUMA: fix typo in a comment
  ACPI: OSL: Use DEFINE_RES_IO_NAMED() to simplify code
  ACPI: bus: Call kobject_put() in acpi_init() error path
  ACPI: bus: Remove unneeded assignment
  ACPI: configfs: Replace ACPI_INFO() with pr_debug()
  ACPI: ipmi: Remove address space handler in error path
  ACPI: event: Remove redundant initialization of local variable
  ACPI: sbshc: Fix fall-through warning for Clang
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -13,9 +13,6 @@
#include <linux/acpi.h>
#include <linux/security.h>

#include "acpica/accommon.h"
#include "acpica/actables.h"

static struct config_group *acpi_table_group;

struct acpi_table {
@@ -226,7 +223,7 @@ static void acpi_table_drop_item(struct config_group *group,
{
	struct acpi_table *table = container_of(cfg, struct acpi_table, cfg);

	ACPI_INFO(("Host-directed Dynamic ACPI Table Unload"));
	pr_debug("Host-directed Dynamic ACPI Table Unload\n");
	acpi_unload_table(table->index);
	config_item_put(cfg);
}
+6 −1
Original line number Diff line number Diff line
@@ -597,9 +597,14 @@ static int __init acpi_ipmi_init(void)
		pr_warn("Can't register IPMI opregion space handle\n");
		return -EINVAL;
	}

	result = ipmi_smi_watcher_register(&driver_data.bmc_events);
	if (result)
	if (result) {
		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
										  ACPI_ADR_SPACE_IPMI,
										  &acpi_ipmi_space_handler);
		pr_err("Can't register IPMI system interface watcher\n");
	}

	return result;
}
+6 −7
Original line number Diff line number Diff line
@@ -186,13 +186,12 @@ static void byt_i2c_setup(struct lpss_private_data *pdata)
	long uid = 0;

	/* Expected to always be true, but better safe then sorry */
	if (uid_str)
		uid = simple_strtol(uid_str, NULL, 10);

	if (uid_str && !kstrtol(uid_str, 10, &uid) && uid) {
		/* Detect I2C bus shared with PUNIT and ignore its d3 status */
		status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
	if (ACPI_SUCCESS(status) && shared_host && uid)
		if (ACPI_SUCCESS(status) && shared_host)
			pmc_atom_d3_mask &= ~(BIT_LPSS2_F1_I2C1 << (uid - 1));
	}

	lpss_deassert_reset(pdata);

+1 −1
Original line number Diff line number Diff line
@@ -673,7 +673,7 @@ static int __init einj_init(void)
	struct apei_exec_context ctx;

	if (acpi_disabled) {
		pr_warn("ACPI disabled.\n");
		pr_info("ACPI disabled.\n");
		return -ENODEV;
	}

+64 −17
Original line number Diff line number Diff line
@@ -441,28 +441,35 @@ static void ghes_kick_task_work(struct callback_head *head)
	gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
}

static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
				       int sev)
static bool ghes_do_memory_failure(u64 physical_addr, int flags)
{
	unsigned long pfn;
	int flags = -1;
	int sec_sev = ghes_severity(gdata->error_severity);
	struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);

	if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
		return false;

	if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
		return false;

	pfn = mem_err->physical_addr >> PAGE_SHIFT;
	pfn = PHYS_PFN(physical_addr);
	if (!pfn_valid(pfn)) {
		pr_warn_ratelimited(FW_WARN GHES_PFX
		"Invalid address in generic error data: %#llx\n",
		mem_err->physical_addr);
		physical_addr);
		return false;
	}

	memory_failure_queue(pfn, flags);
	return true;
}

static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
				       int sev)
{
	int flags = -1;
	int sec_sev = ghes_severity(gdata->error_severity);
	struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);

	if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
		return false;

	/* iff following two events can be handled properly by now */
	if (sec_sev == GHES_SEV_CORRECTED &&
	    (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
@@ -470,12 +477,54 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
	if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
		flags = 0;

	if (flags != -1) {
		memory_failure_queue(pfn, flags);
		return true;
	if (flags != -1)
		return ghes_do_memory_failure(mem_err->physical_addr, flags);

	return false;
}

static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
{
	struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
	bool queued = false;
	int sec_sev, i;
	char *p;

	log_arm_hw_error(err);

	sec_sev = ghes_severity(gdata->error_severity);
	if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE)
		return false;

	p = (char *)(err + 1);
	for (i = 0; i < err->err_info_num; i++) {
		struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p;
		bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR);
		bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR);
		const char *error_type = "unknown error";

		/*
		 * The field (err_info->error_info & BIT(26)) is fixed to set to
		 * 1 in some old firmware of HiSilicon Kunpeng920. We assume that
		 * firmware won't mix corrected errors in an uncorrected section,
		 * and don't filter out 'corrected' error here.
		 */
		if (is_cache && has_pa) {
			queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0);
			p += err_info->length;
			continue;
		}

		if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs))
			error_type = cper_proc_error_type_strs[err_info->type];

		pr_warn_ratelimited(FW_WARN GHES_PFX
				    "Unhandled processor error type: %s\n",
				    error_type);
		p += err_info->length;
	}

	return queued;
}

/*
@@ -605,9 +654,7 @@ static bool ghes_do_proc(struct ghes *ghes,
			ghes_handle_aer(gdata);
		}
		else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
			struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);

			log_arm_hw_error(err);
			queued = ghes_handle_arm_hw_error(gdata, sev);
		} else {
			void *err = acpi_hest_get_payload(gdata);

Loading