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
pull/1354/merge
Rafael J. Wysocki 2025-09-29 15:28:51 +02:00
commit c87072064b
5 changed files with 51 additions and 17 deletions

View File

@ -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))

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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");