提交 30da7434 编写于 作者: J James Morse 提交者: Baolin Wang

ACPI / APEI: Don't update struct ghes' flags in read/clear estatus

fix #28612342

commit 5cc6c68287ae4be22c40b41cf6844746cddebbcc upstream

ghes_read_estatus() sets a flag in struct ghes if the buffer of
CPER records needs to be cleared once the records have been
processed. This flag value is a problem if a struct ghes can be
processed concurrently, as happens at probe time if an NMI arrives
for the same error source. The NMI clears the flag, meaning the
interrupted handler may never do the ghes_estatus_clear() work.

The GHES_TO_CLEAR flags is only set at the same time as
buffer_paddr, which is now owned by the caller and passed to
ghes_clear_estatus(). Use this value as the flag.

A non-zero buf_paddr returned by ghes_read_estatus() means
ghes_clear_estatus() should clear this address. ghes_read_estatus()
already checks for a read of error_status_address being zero,
so CPER records cannot be written here.
Signed-off-by: NJames Morse <james.morse@arm.com>
Reviewed-by: NBorislav Petkov <bp@suse.de>
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: NBaolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: NAlex Shi <alex.shi@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
Reviewed-by: Nluanshi <zhangliguang@linux.alibaba.com>
上级 3ed68924
...@@ -329,8 +329,6 @@ static int ghes_read_estatus(struct ghes *ghes, u64 *buf_paddr) ...@@ -329,8 +329,6 @@ static int ghes_read_estatus(struct ghes *ghes, u64 *buf_paddr)
return -ENOENT; return -ENOENT;
} }
ghes->flags |= GHES_TO_CLEAR;
rc = -EIO; rc = -EIO;
len = cper_estatus_len(ghes->estatus); len = cper_estatus_len(ghes->estatus);
if (len < sizeof(*ghes->estatus)) if (len < sizeof(*ghes->estatus))
...@@ -357,15 +355,12 @@ static int ghes_read_estatus(struct ghes *ghes, u64 *buf_paddr) ...@@ -357,15 +355,12 @@ static int ghes_read_estatus(struct ghes *ghes, u64 *buf_paddr)
static void ghes_clear_estatus(struct ghes *ghes, u64 buf_paddr) static void ghes_clear_estatus(struct ghes *ghes, u64 buf_paddr)
{ {
ghes->estatus->block_status = 0; ghes->estatus->block_status = 0;
if (!(ghes->flags & GHES_TO_CLEAR))
return;
if (!buf_paddr) if (!buf_paddr)
return; return;
ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, ghes_copy_tofrom_phys(ghes->estatus, buf_paddr,
sizeof(ghes->estatus->block_status), 0); sizeof(ghes->estatus->block_status), 0);
ghes->flags &= ~GHES_TO_CLEAR;
} }
static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
* estatus: memory buffer for error status block, allocated during * estatus: memory buffer for error status block, allocated during
* HEST parsing. * HEST parsing.
*/ */
#define GHES_TO_CLEAR 0x0001
#define GHES_EXITING 0x0002 #define GHES_EXITING 0x0002
struct ghes { struct ghes {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册