Commit e729dbe8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more ACPI updates from Rafael Wysocki:
 "These are fixes and cleanup on top of the previously merged ACPI
  material.

  Specifics:

   - Avoid out-of-bounds access when parsing _CPC data (Rafael Wysocki)

   - Change default error code and clean up debug messages in ACPI CPPC
     probe (Rafael Wysocki)

   - Replace usage of found with dedicated list iterator variable in the
     ACPI IPMI driver (Jakob Koschel)

   - Clean up variable name confusion in APEI (Jakob Koschel)

   - Make LAPIC_ADDR_OVR address readable in a message parsed during
     MADT parsing (Vasant Hegde)"

* tag 'acpi-5.18-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: CPPC: Change default error code and clean up debug messages in probe
  ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
  ACPI: tables: Make LAPIC_ADDR_OVR address readable in message
  ACPI: IPMI: replace usage of found with dedicated list iterator variable
  ACPI, APEI: Use the correct variable for sizeof()
parents b4a5ea09 4a13e559
Loading
Loading
Loading
Loading
+18 −21
Original line number Diff line number Diff line
@@ -353,29 +353,27 @@ static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
static void ipmi_cancel_tx_msg(struct acpi_ipmi_device *ipmi,
			       struct acpi_ipmi_msg *msg)
{
	struct acpi_ipmi_msg *tx_msg, *temp;
	bool msg_found = false;
	struct acpi_ipmi_msg *tx_msg = NULL, *iter, *temp;
	unsigned long flags;

	spin_lock_irqsave(&ipmi->tx_msg_lock, flags);
	list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) {
		if (msg == tx_msg) {
			msg_found = true;
			list_del(&tx_msg->head);
	list_for_each_entry_safe(iter, temp, &ipmi->tx_msg_list, head) {
		if (msg == iter) {
			tx_msg = iter;
			list_del(&iter->head);
			break;
		}
	}
	spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags);

	if (msg_found)
	if (tx_msg)
		acpi_ipmi_msg_put(tx_msg);
}

static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
{
	struct acpi_ipmi_device *ipmi_device = user_msg_data;
	bool msg_found = false;
	struct acpi_ipmi_msg *tx_msg, *temp;
	struct acpi_ipmi_msg *tx_msg = NULL, *iter, *temp;
	struct device *dev = ipmi_device->dev;
	unsigned long flags;

@@ -387,16 +385,16 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
	}

	spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
	list_for_each_entry_safe(tx_msg, temp, &ipmi_device->tx_msg_list, head) {
		if (msg->msgid == tx_msg->tx_msgid) {
			msg_found = true;
			list_del(&tx_msg->head);
	list_for_each_entry_safe(iter, temp, &ipmi_device->tx_msg_list, head) {
		if (msg->msgid == iter->tx_msgid) {
			tx_msg = iter;
			list_del(&iter->head);
			break;
		}
	}
	spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);

	if (!msg_found) {
	if (!tx_msg) {
		dev_warn(dev,
			 "Unexpected response (msg id %ld) is returned.\n",
			 msg->msgid);
@@ -482,15 +480,14 @@ static void ipmi_register_bmc(int iface, struct device *dev)

static void ipmi_bmc_gone(int iface)
{
	struct acpi_ipmi_device *ipmi_device, *temp;
	bool dev_found = false;
	struct acpi_ipmi_device *ipmi_device = NULL, *iter, *temp;

	mutex_lock(&driver_data.ipmi_lock);
	list_for_each_entry_safe(ipmi_device, temp,
	list_for_each_entry_safe(iter, temp,
				 &driver_data.ipmi_devices, head) {
		if (ipmi_device->ipmi_ifnum != iface) {
			dev_found = true;
			__ipmi_dev_kill(ipmi_device);
		if (iter->ipmi_ifnum != iface) {
			ipmi_device = iter;
			__ipmi_dev_kill(iter);
			break;
		}
	}
@@ -500,7 +497,7 @@ static void ipmi_bmc_gone(int iface)
					struct acpi_ipmi_device, head);
	mutex_unlock(&driver_data.ipmi_lock);

	if (dev_found) {
	if (ipmi_device) {
		ipmi_flush_tx_msg(ipmi_device);
		acpi_ipmi_dev_put(ipmi_device);
	}
+1 −1
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ static int apei_res_add(struct list_head *res_list,
	if (res_ins)
		list_add(&res_ins->list, res_list);
	else {
		res_ins = kmalloc(sizeof(*res), GFP_KERNEL);
		res_ins = kmalloc(sizeof(*res_ins), GFP_KERNEL);
		if (!res_ins)
			return -ENOMEM;
		res_ins->start = start;
+20 −12
Original line number Diff line number Diff line
@@ -654,7 +654,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
	unsigned int num_ent, i, cpc_rev;
	int pcc_subspace_id = -1;
	acpi_status status;
	int ret = -EFAULT;
	int ret = -ENODATA;

	if (osc_sb_cppc_not_supported)
		return -ENODEV;
@@ -679,9 +679,14 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
	cpc_obj = &out_obj->package.elements[0];
	if (cpc_obj->type == ACPI_TYPE_INTEGER)	{
		num_ent = cpc_obj->integer.value;
		if (num_ent <= 1) {
			pr_debug("Unexpected _CPC NumEntries value (%d) for CPU:%d\n",
				 num_ent, pr->id);
			goto out_free;
		}
	} else {
		pr_debug("Unexpected entry type(%d) for NumEntries\n",
				cpc_obj->type);
		pr_debug("Unexpected _CPC NumEntries entry type (%d) for CPU:%d\n",
			 cpc_obj->type, pr->id);
		goto out_free;
	}
	cpc_ptr->num_entries = num_ent;
@@ -691,8 +696,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
	if (cpc_obj->type == ACPI_TYPE_INTEGER)	{
		cpc_rev = cpc_obj->integer.value;
	} else {
		pr_debug("Unexpected entry type(%d) for Revision\n",
				cpc_obj->type);
		pr_debug("Unexpected _CPC Revision entry type (%d) for CPU:%d\n",
			 cpc_obj->type, pr->id);
		goto out_free;
	}
	cpc_ptr->version = cpc_rev;
@@ -723,7 +728,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
					if (pcc_data_alloc(pcc_subspace_id))
						goto out_free;
				} else if (pcc_subspace_id != gas_t->access_width) {
					pr_debug("Mismatched PCC ids.\n");
					pr_debug("Mismatched PCC ids in _CPC for CPU:%d\n",
						 pr->id);
					goto out_free;
				}
			} else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
@@ -742,20 +748,21 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
					 * SystemIO doesn't implement 64-bit
					 * registers.
					 */
					pr_debug("Invalid access width %d for SystemIO register\n",
					pr_debug("Invalid access width %d for SystemIO register in _CPC\n",
						 gas_t->access_width);
					goto out_free;
				}
				if (gas_t->address & OVER_16BTS_MASK) {
					/* SystemIO registers use 16-bit integer addresses */
					pr_debug("Invalid IO port %llu for SystemIO register\n",
					pr_debug("Invalid IO port %llu for SystemIO register in _CPC\n",
						 gas_t->address);
					goto out_free;
				}
			} else {
				if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
					/* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */
					pr_debug("Unsupported register type: %d\n", gas_t->space_id);
					pr_debug("Unsupported register type (%d) in _CPC\n",
						 gas_t->space_id);
					goto out_free;
				}
			}
@@ -763,7 +770,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
			cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
			memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
		} else {
			pr_debug("Err in entry:%d in CPC table of CPU:%d\n", i, pr->id);
			pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
				 i, pr->id);
			goto out_free;
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -151,8 +151,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
		{
			struct acpi_madt_local_apic_override *p =
			    (struct acpi_madt_local_apic_override *)header;
			pr_info("LAPIC_ADDR_OVR (address[%p])\n",
				(void *)(unsigned long)p->address);
			pr_info("LAPIC_ADDR_OVR (address[0x%llx])\n",
				p->address);
		}
		break;