Skip to content

Commit fc0c202

Browse files
committed
x86, pmem: use memcpy_mcsafe() for memcpy_from_pmem()
Update the definition of memcpy_from_pmem() to return 0 or a negative error code. Implement x86/arch_memcpy_from_pmem() with memcpy_mcsafe(). Cc: Borislav Petkov <bp@alien8.de> Cc: Tony Luck <tony.luck@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Acked-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent f55532a commit fc0c202

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

arch/x86/include/asm/pmem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
4747
BUG();
4848
}
4949

50+
static inline int arch_memcpy_from_pmem(void *dst, const void __pmem *src,
51+
size_t n)
52+
{
53+
if (static_cpu_has(X86_FEATURE_MCE_RECOVERY))
54+
return memcpy_mcsafe(dst, (void __force *) src, n);
55+
memcpy(dst, (void __force *) src, n);
56+
return 0;
57+
}
58+
5059
/**
5160
* arch_wmb_pmem - synchronize writes to persistent memory
5261
*

drivers/nvdimm/pmem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
9999
if (unlikely(bad_pmem))
100100
rc = -EIO;
101101
else {
102-
memcpy_from_pmem(mem + off, pmem_addr, len);
102+
rc = memcpy_from_pmem(mem + off, pmem_addr, len);
103103
flush_dcache_page(page);
104104
}
105105
} else {
@@ -295,7 +295,7 @@ static int pmem_rw_bytes(struct nd_namespace_common *ndns,
295295

296296
if (unlikely(is_bad_pmem(&pmem->bb, offset / 512, sz_align)))
297297
return -EIO;
298-
memcpy_from_pmem(buf, pmem->virt_addr + offset, size);
298+
return memcpy_from_pmem(buf, pmem->virt_addr + offset, size);
299299
} else {
300300
memcpy_to_pmem(pmem->virt_addr + offset, buf, size);
301301
wmb_pmem();

include/linux/pmem.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
4242
BUG();
4343
}
4444

45+
static inline int arch_memcpy_from_pmem(void *dst, const void __pmem *src,
46+
size_t n)
47+
{
48+
BUG();
49+
return -EFAULT;
50+
}
51+
4552
static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
4653
struct iov_iter *i)
4754
{
@@ -66,14 +73,17 @@ static inline void arch_invalidate_pmem(void __pmem *addr, size_t size)
6673
#endif
6774

6875
/*
69-
* Architectures that define ARCH_HAS_PMEM_API must provide
70-
* implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(),
71-
* arch_copy_from_iter_pmem(), arch_clear_pmem(), arch_wb_cache_pmem()
72-
* and arch_has_wmb_pmem().
76+
* memcpy_from_pmem - read from persistent memory with error handling
77+
* @dst: destination buffer
78+
* @src: source buffer
79+
* @size: transfer length
80+
*
81+
* Returns 0 on success negative error code on failure.
7382
*/
74-
static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
83+
static inline int memcpy_from_pmem(void *dst, void __pmem const *src,
84+
size_t size)
7585
{
76-
memcpy(dst, (void __force const *) src, size);
86+
return arch_memcpy_from_pmem(dst, src, size);
7787
}
7888

7989
static inline bool arch_has_pmem_api(void)

0 commit comments

Comments
 (0)