Skip to content

Commit 0e33ac9

Browse files
AlisonSchofielddjbw
authored andcommitted
cxl/memdev: Hold region_rwsem during inject and clear poison ops
Poison inject and clear are supported via debugfs where a privileged user can inject and clear poison to a device physical address. Commit 458ba81 ("cxl: Add cxl_decoders_committed() helper") added a lockdep assert that highlighted a gap in poison inject and clear functions where holding the dpa_rwsem does not assure that a a DPA is not added to a region. The impact for inject and clear is that if the DPA address being injected or cleared has been attached to a region, but not yet committed, the dev_dbg() message intended to alert the debug user that they are acting on a mapped address is not emitted. Also, the cxl_poison trace event that serves as a log of the inject and clear activity will not include region info. Close this gap by snapshotting an unchangeable region state during poison inject and clear operations. That means holding both the region_rwsem and the dpa_rwsem during the inject and clear ops. Fixes: d2fbc48 ("cxl/memdev: Add support for the Inject Poison mailbox command") Fixes: 9690b07 ("cxl/memdev: Add support for the Clear Poison mailbox command") Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/08721dc1df0a51e4e38fecd02425c3475912dfd5.1701041440.git.alison.schofield@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 5558b92 commit 0e33ac9

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

drivers/cxl/core/memdev.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,16 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
331331
if (!IS_ENABLED(CONFIG_DEBUG_FS))
332332
return 0;
333333

334-
rc = down_read_interruptible(&cxl_dpa_rwsem);
334+
rc = down_read_interruptible(&cxl_region_rwsem);
335335
if (rc)
336336
return rc;
337337

338+
rc = down_read_interruptible(&cxl_dpa_rwsem);
339+
if (rc) {
340+
up_read(&cxl_region_rwsem);
341+
return rc;
342+
}
343+
338344
rc = cxl_validate_poison_dpa(cxlmd, dpa);
339345
if (rc)
340346
goto out;
@@ -362,6 +368,7 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
362368
trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT);
363369
out:
364370
up_read(&cxl_dpa_rwsem);
371+
up_read(&cxl_region_rwsem);
365372

366373
return rc;
367374
}
@@ -379,10 +386,16 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
379386
if (!IS_ENABLED(CONFIG_DEBUG_FS))
380387
return 0;
381388

382-
rc = down_read_interruptible(&cxl_dpa_rwsem);
389+
rc = down_read_interruptible(&cxl_region_rwsem);
383390
if (rc)
384391
return rc;
385392

393+
rc = down_read_interruptible(&cxl_dpa_rwsem);
394+
if (rc) {
395+
up_read(&cxl_region_rwsem);
396+
return rc;
397+
}
398+
386399
rc = cxl_validate_poison_dpa(cxlmd, dpa);
387400
if (rc)
388401
goto out;
@@ -419,6 +432,7 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
419432
trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR);
420433
out:
421434
up_read(&cxl_dpa_rwsem);
435+
up_read(&cxl_region_rwsem);
422436

423437
return rc;
424438
}

0 commit comments

Comments
 (0)