@@ -1324,7 +1324,7 @@ static void cxl_mem_report_poison(struct cxl_memdev *cxlmd,
}
int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
- struct cxl_region *cxlr)
+ struct cxl_region *cxlr, bool report)
{
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
struct cxl_mbox_poison_out *po;
@@ -1355,10 +1355,13 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
if (rc)
break;
- for (int i = 0; i < le16_to_cpu(po->count); i++)
+ for (int i = 0; i < le16_to_cpu(po->count); i++) {
trace_cxl_poison(cxlmd, cxlr, &po->record[i],
po->flags, po->overflow_ts,
CXL_POISON_TRACE_LIST);
+ if (report)
+ cxl_mem_report_poison(cxlmd, &po->record[i]);
+ }
/* Protect against an uncleared _FLAG_MORE */
nr_records = nr_records + le16_to_cpu(po->count);
@@ -200,14 +200,14 @@ static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
if (resource_size(&cxlds->pmem_res)) {
offset = cxlds->pmem_res.start;
length = resource_size(&cxlds->pmem_res);
- rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ rc = cxl_mem_get_poison(cxlmd, offset, length, NULL, false);
if (rc)
return rc;
}
if (resource_size(&cxlds->ram_res)) {
offset = cxlds->ram_res.start;
length = resource_size(&cxlds->ram_res);
- rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ rc = cxl_mem_get_poison(cxlmd, offset, length, NULL, false);
/*
* Invalid Physical Address is not an error for
* volatile addresses. Device support is optional.
@@ -2386,7 +2386,7 @@ static int cxl_get_poison_unmapped(struct cxl_memdev *cxlmd,
if (ctx->mode == CXL_DECODER_RAM) {
offset = ctx->offset;
length = resource_size(&cxlds->ram_res) - offset;
- rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ rc = cxl_mem_get_poison(cxlmd, offset, length, NULL, false);
if (rc == -EFAULT)
rc = 0;
if (rc)
@@ -2404,7 +2404,7 @@ static int cxl_get_poison_unmapped(struct cxl_memdev *cxlmd,
return 0;
}
- return cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ return cxl_mem_get_poison(cxlmd, offset, length, NULL, false);
}
static int poison_by_decoder(struct device *dev, void *arg)
@@ -2438,7 +2438,7 @@ static int poison_by_decoder(struct device *dev, void *arg)
if (cxled->skip) {
offset = cxled->dpa_res->start - cxled->skip;
length = cxled->skip;
- rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ rc = cxl_mem_get_poison(cxlmd, offset, length, NULL, false);
if (rc == -EFAULT && cxled->mode == CXL_DECODER_RAM)
rc = 0;
if (rc)
@@ -2447,7 +2447,7 @@ static int poison_by_decoder(struct device *dev, void *arg)
offset = cxled->dpa_res->start;
length = cxled->dpa_res->end - offset + 1;
- rc = cxl_mem_get_poison(cxlmd, offset, length, cxled->cxld.region);
+ rc = cxl_mem_get_poison(cxlmd, offset, length, cxled->cxld.region, false);
if (rc == -EFAULT && cxled->mode == CXL_DECODER_RAM)
rc = 0;
if (rc)
@@ -831,7 +831,7 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
int cxl_set_timestamp(struct cxl_memdev_state *mds);
int cxl_poison_state_init(struct cxl_memdev_state *mds);
int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
- struct cxl_region *cxlr);
+ struct cxl_region *cxlr, bool report);
int cxl_trigger_poison_list(struct cxl_memdev *cxlmd);
phys_addr_t cxl_memdev_dpa_to_hpa(struct cxl_memdev *cxlmd, u64 dpa);
int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa);
When a poison event is received, driver uses GET_POISON_LIST command to get the poison list. Now driver has cxl_mem_get_poison(), so reuse it and add a parameter 'bool report', report poison record to MCE if set true. Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com> --- drivers/cxl/core/mbox.c | 7 +++++-- drivers/cxl/core/memdev.c | 4 ++-- drivers/cxl/core/region.c | 8 ++++---- drivers/cxl/cxlmem.h | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-)