All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-07 10:51 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Pieralisi @ 2022-04-07 10:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Lorenzo Pieralisi, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, linux-acpi,
	linux-arm-kernel, Veronika kabatova, Robin Murphy,
	Aristeu Rozanski

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@arm.com
Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-07 10:51 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Pieralisi @ 2022-04-07 10:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Lorenzo Pieralisi, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, linux-acpi,
	linux-arm-kernel, Veronika kabatova, Robin Murphy,
	Aristeu Rozanski

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@arm.com
Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 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


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
  2022-04-07 10:51 ` Lorenzo Pieralisi
@ 2022-04-08 13:54   ` Veronika Kabatova
  -1 siblings, 0 replies; 10+ messages in thread
From: Veronika Kabatova @ 2022-04-08 13:54 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-kernel, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki,
	ACPI Devel Maling List, Linux ARM, Robin Murphy,
	Aristeu Rozanski

On Thu, Apr 7, 2022 at 12:51 PM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> 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.
>

Hi,

I tested this patch on top of the arm tree for-kernelci branch (a2c0b0fbe014).
I wasn't able to trigger the original problem on the same HW, and the patch
didn't introduce any new issues on these runs, nor on other randomly
chosen aarch64 machines.

Tested-by: Veronika Kabatova <vkabatov@redhat.com>


> Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> ---
>  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
>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-08 13:54   ` Veronika Kabatova
  0 siblings, 0 replies; 10+ messages in thread
From: Veronika Kabatova @ 2022-04-08 13:54 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-kernel, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki,
	ACPI Devel Maling List, Linux ARM, Robin Murphy,
	Aristeu Rozanski

On Thu, Apr 7, 2022 at 12:51 PM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> 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.
>

Hi,

I tested this patch on top of the arm tree for-kernelci branch (a2c0b0fbe014).
I wasn't able to trigger the original problem on the same HW, and the patch
didn't introduce any new issues on these runs, nor on other randomly
chosen aarch64 machines.

Tested-by: Veronika Kabatova <vkabatov@redhat.com>


> Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> ---
>  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
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
  2022-04-07 10:51 ` Lorenzo Pieralisi
@ 2022-04-08 15:52   ` Aristeu Rozanski
  -1 siblings, 0 replies; 10+ messages in thread
From: Aristeu Rozanski @ 2022-04-08 15:52 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-kernel, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, linux-acpi,
	linux-arm-kernel, Veronika kabatova, Robin Murphy

On Thu, Apr 07, 2022 at 11:51:20AM +0100, Lorenzo Pieralisi 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@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> ---
>  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)

I've tested this patch with the reproducer and I was unable to reproduce
the issue.

Tested-by: Aristeu Rozanski <aris@redhat.com>

-- 
Aristeu


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-08 15:52   ` Aristeu Rozanski
  0 siblings, 0 replies; 10+ messages in thread
From: Aristeu Rozanski @ 2022-04-08 15:52 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-kernel, Ard Biesheuvel, Will Deacon, Hanjun Guo,
	Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, linux-acpi,
	linux-arm-kernel, Veronika kabatova, Robin Murphy

On Thu, Apr 07, 2022 at 11:51:20AM +0100, Lorenzo Pieralisi 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@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> ---
>  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)

I've tested this patch with the reproducer and I was unable to reproduce
the issue.

Tested-by: Aristeu Rozanski <aris@redhat.com>

-- 
Aristeu


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
  2022-04-07 10:51 ` Lorenzo Pieralisi
@ 2022-04-13 17:40   ` Ard Biesheuvel
  -1 siblings, 0 replies; 10+ messages in thread
From: Ard Biesheuvel @ 2022-04-13 17:40 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Linux Kernel Mailing List, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Rafael J. Wysocki, ACPI Devel Maling List,
	Linux ARM, Veronika kabatova, Robin Murphy, Aristeu Rozanski

On Thu, 7 Apr 2022 at 12:51, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> 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@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>

Acked-by: Ard Biesheuvel <ardb@kernel.org>

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-13 17:40   ` Ard Biesheuvel
  0 siblings, 0 replies; 10+ messages in thread
From: Ard Biesheuvel @ 2022-04-13 17:40 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Linux Kernel Mailing List, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Rafael J. Wysocki, ACPI Devel Maling List,
	Linux ARM, Veronika kabatova, Robin Murphy, Aristeu Rozanski

On Thu, 7 Apr 2022 at 12:51, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> 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@arm.com
> Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>

Acked-by: Ard Biesheuvel <ardb@kernel.org>

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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
  2022-04-13 17:40   ` Ard Biesheuvel
@ 2022-04-13 17:59     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2022-04-13 17:59 UTC (permalink / raw)
  To: Ard Biesheuvel, Lorenzo Pieralisi
  Cc: Linux Kernel Mailing List, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Rafael J. Wysocki, ACPI Devel Maling List,
	Linux ARM, Veronika kabatova, Robin Murphy, Aristeu Rozanski

On Wed, Apr 13, 2022 at 7:41 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 7 Apr 2022 at 12:51, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> 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@arm.com
> > Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Ard Biesheuvel <ardb@kernel.org>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Hanjun Guo <guohanjun@huawei.com>
> > Cc: Sudeep Holla <sudeep.holla@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
>
> Acked-by: Ard Biesheuvel <ardb@kernel.org>

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ACPI: osl: Fix BERT error region memory mapping
@ 2022-04-13 17:59     ` Rafael J. Wysocki
  0 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2022-04-13 17:59 UTC (permalink / raw)
  To: Ard Biesheuvel, Lorenzo Pieralisi
  Cc: Linux Kernel Mailing List, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Rafael J. Wysocki, ACPI Devel Maling List,
	Linux ARM, Veronika kabatova, Robin Murphy, Aristeu Rozanski

On Wed, Apr 13, 2022 at 7:41 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 7 Apr 2022 at 12:51, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> 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@arm.com
> > Link: https://lore.kernel.org/linux-acpi/CAJZ5v0g+OVbhuUUDrLUCfX_mVqY_e8ubgLTU98=jfjTeb4t+Pw@mail.gmail.com
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Ard Biesheuvel <ardb@kernel.org>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Hanjun Guo <guohanjun@huawei.com>
> > Cc: Sudeep Holla <sudeep.holla@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
>
> Acked-by: Ard Biesheuvel <ardb@kernel.org>

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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-04-13 18:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-07 10:51 [PATCH] ACPI: osl: Fix BERT error region memory mapping Lorenzo Pieralisi
2022-04-07 10:51 ` Lorenzo Pieralisi
2022-04-08 13:54 ` Veronika Kabatova
2022-04-08 13:54   ` Veronika Kabatova
2022-04-08 15:52 ` Aristeu Rozanski
2022-04-08 15:52   ` Aristeu Rozanski
2022-04-13 17:40 ` Ard Biesheuvel
2022-04-13 17:40   ` Ard Biesheuvel
2022-04-13 17:59   ` Rafael J. Wysocki
2022-04-13 17:59     ` Rafael J. Wysocki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.