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

Merge branches 'acpi-apei', 'acpi-misc' and 'pnp'

Merge ACPI APEI updates, a miscellaneous update related to ACPI, and a
PNP update for 6.18-rc1:

 - Remove redundant assignments in erst_dbg_{ioctl|write}() in the ACPI
   APEI driver (Thorsten Blum)

 - Allow the ACPI APEI EINJ to handle more types of addresses than just
   MMIO (Jiaqi Yan)

 - Use str_low_high() helper in two places in the ACPI code (Chelsy
   Ratnawat)

 - Use str_plural() to simplify the PNP code (Xichao Zhao)

* acpi-apei:
  ACPI: APEI: EINJ: Allow more types of addresses except MMIO
  ACPI: APEI: Remove redundant assignments in erst_dbg_{ioctl|write}()

* acpi-misc:
  ACPI: Use str_low_high() helper in two places

* pnp:
  PNP: isapnp: use str_plural() to simplify the code
Loading
Loading
Loading
Loading
+42 −9
Original line number Diff line number Diff line
@@ -656,6 +656,43 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
	return rc;
}

/* Allow almost all types of address except MMIO. */
static bool is_allowed_range(u64 base_addr, u64 size)
{
	int i;
	/*
	 * MMIO region is usually claimed with IORESOURCE_MEM + IORES_DESC_NONE.
	 * However, IORES_DESC_NONE is treated like a wildcard when we check if
	 * region intersects with known resource. So do an allow list check for
	 * IORES_DESCs that definitely or most likely not MMIO.
	 */
	int non_mmio_desc[] = {
		IORES_DESC_CRASH_KERNEL,
		IORES_DESC_ACPI_TABLES,
		IORES_DESC_ACPI_NV_STORAGE,
		IORES_DESC_PERSISTENT_MEMORY,
		IORES_DESC_PERSISTENT_MEMORY_LEGACY,
		/* Treat IORES_DESC_DEVICE_PRIVATE_MEMORY as MMIO. */
		IORES_DESC_RESERVED,
		IORES_DESC_SOFT_RESERVED,
	};

	if (region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
			      == REGION_INTERSECTS)
		return true;

	for (i = 0; i < ARRAY_SIZE(non_mmio_desc); ++i) {
		if (region_intersects(base_addr, size, IORESOURCE_MEM, non_mmio_desc[i])
				      == REGION_INTERSECTS)
			return true;
	}

	if (arch_is_platform_page(base_addr))
		return true;

	return false;
}

/* Inject the specified hardware error */
int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3,
		      u64 param4)
@@ -702,19 +739,15 @@ int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3,
	 * Disallow crazy address masks that give BIOS leeway to pick
	 * injection address almost anywhere. Insist on page or
	 * better granularity and that target address is normal RAM or
	 * NVDIMM.
	 * as long as is not MMIO.
	 */
	base_addr = param1 & param2;
	size = ~param2 + 1;

	if (((param2 & PAGE_MASK) != PAGE_MASK) ||
	    ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
				!= REGION_INTERSECTS) &&
	     (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
				!= REGION_INTERSECTS) &&
	     (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED)
				!= REGION_INTERSECTS) &&
	     !arch_is_platform_page(base_addr)))
	if ((param2 & PAGE_MASK) != PAGE_MASK)
		return -EINVAL;

	if (!is_allowed_range(base_addr, size))
		return -EINVAL;

	if (is_zero_pfn(base_addr >> PAGE_SHIFT))
+3 −5
Original line number Diff line number Diff line
@@ -60,9 +60,8 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)

	switch (cmd) {
	case APEI_ERST_CLEAR_RECORD:
		rc = copy_from_user(&record_id, (void __user *)arg,
				    sizeof(record_id));
		if (rc)
		if (copy_from_user(&record_id, (void __user *)arg,
				   sizeof(record_id)))
			return -EFAULT;
		return erst_clear(record_id);
	case APEI_ERST_GET_RECORD_COUNT:
@@ -175,8 +174,7 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf,
		erst_dbg_buf = p;
		erst_dbg_buf_len = usize;
	}
	rc = copy_from_user(erst_dbg_buf, ubuf, usize);
	if (rc) {
	if (copy_from_user(erst_dbg_buf, ubuf, usize)) {
		rc = -EFAULT;
		goto out;
	}
+2 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/acpi.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/string_choices.h>

struct acpi_prt_entry {
	struct acpi_pci_id	id;
@@ -468,7 +469,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
	dev_dbg(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
		pin_name(pin), link_desc, gsi,
		(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
		(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
		str_low_high(polarity == ACPI_ACTIVE_LOW), dev->irq);

	kfree(entry);
	return 0;
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/dmi.h>
#include <linux/string_choices.h>

#ifdef CONFIG_X86
#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
@@ -780,7 +781,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
			pr_warn("ACPI: IRQ %d override to %s%s, %s%s\n", gsi,
				t ? "level" : "edge",
				trig == triggering ? "" : "(!)",
				p ? "low" : "high",
				str_low_high(p),
				pol == polarity ? "" : "(!)");
			triggering = trig;
			polarity = pol;
+2 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/mutex.h>
#include <linux/string_choices.h>
#include <asm/io.h>

#include "../base.h"
@@ -1037,7 +1038,7 @@ static int __init isapnp_init(void)
	if (cards)
		printk(KERN_INFO
		       "isapnp: %i Plug & Play card%s detected total\n", cards,
		       cards > 1 ? "s" : "");
		       str_plural(cards));
	else
		printk(KERN_INFO "isapnp: No Plug & Play card found\n");