On Wed, Apr 13, 2022 at 7:41 PM Ard Biesheuvel <ardb@xxxxxxxxxx> wrote: > > On Thu, 7 Apr 2022 at 12:51, Lorenzo Pieralisi > <lorenzo.pieralisi@xxxxxxx> wrote: > > > > Currently the sysfs interface maps the BERT error region as "memory" > > (through acpi_os_map_memory()) in order to copy the error records into > > memory buffers through memory operations (eg memory_read_from_buffer()). > > > > The OS system cannot detect whether the BERT error region is part of > > system RAM or it is "device memory" (eg BMC memory) and therefore it > > cannot detect which memory attributes the bus to memory support (and > > corresponding kernel mapping, unless firmware provides the required > > information). > > > > The acpi_os_map_memory() arch backend implementation determines the > > mapping attributes. On arm64, if the BERT error region is not present in > > the EFI memory map, the error region is mapped as device-nGnRnE; this > > triggers alignment faults since memcpy unaligned accesses are not > > allowed in device-nGnRnE regions. > > > > The ACPI sysfs code cannot therefore map by default the BERT error > > region with memory semantics but should use a safer default. > > > > Change the sysfs code to map the BERT error region as MMIO (through > > acpi_os_map_iomem()) and use the memcpy_fromio() interface to read the > > error region into the kernel buffer. > > > > Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702@xxxxxxx > > Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@xxxxxxxxxxxxxx > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx> > > Cc: Ard Biesheuvel <ardb@xxxxxxxxxx> > > Cc: Will Deacon <will@xxxxxxxxxx> > > Cc: Hanjun Guo <guohanjun@xxxxxxxxxx> > > Cc: Sudeep Holla <sudeep.holla@xxxxxxx> > > Cc: Catalin Marinas <catalin.marinas@xxxxxxx> > > Cc: "Rafael J. Wysocki" <rjw@xxxxxxxxxxxxx> > > Acked-by: Ard Biesheuvel <ardb@xxxxxxxxxx> Applied as 5.19 material, thanks! > > --- > > drivers/acpi/sysfs.c | 25 ++++++++++++++++++------- > > 1 file changed, 18 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c > > index a4b638bea6f1..cc2fe0618178 100644 > > --- a/drivers/acpi/sysfs.c > > +++ b/drivers/acpi/sysfs.c > > @@ -415,19 +415,30 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj, > > loff_t offset, size_t count) > > { > > struct acpi_data_attr *data_attr; > > - void *base; > > - ssize_t rc; > > + void __iomem *base; > > + ssize_t size; > > > > data_attr = container_of(bin_attr, struct acpi_data_attr, attr); > > + size = data_attr->attr.size; > > + > > + if (offset < 0) > > + return -EINVAL; > > + > > + if (offset >= size) > > + return 0; > > > > - base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size); > > + if (count > size - offset) > > + count = size - offset; > > + > > + base = acpi_os_map_iomem(data_attr->addr, size); > > if (!base) > > return -ENOMEM; > > - rc = memory_read_from_buffer(buf, count, &offset, base, > > - data_attr->attr.size); > > - acpi_os_unmap_memory(base, data_attr->attr.size); > > > > - return rc; > > + memcpy_fromio(buf, base + offset, count); > > + > > + acpi_os_unmap_iomem(base, size); > > + > > + return count; > > } > > > > static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr) > > -- > > 2.31.0 > >