diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/iov_iter.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 7e43cd54c84c..94fa361be7bb 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -596,6 +596,32 @@ static unsigned long memcpy_mcsafe_to_page(struct page *page, size_t offset, | |||
| 596 | return ret; | 596 | return ret; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | /** | ||
| 600 | * _copy_to_iter_mcsafe - copy to user with source-read error exception handling | ||
| 601 | * @addr: source kernel address | ||
| 602 | * @bytes: total transfer length | ||
| 603 | * @iter: destination iterator | ||
| 604 | * | ||
| 605 | * The pmem driver arranges for filesystem-dax to use this facility via | ||
| 606 | * dax_copy_to_iter() for protecting read/write to persistent memory. | ||
| 607 | * Unless / until an architecture can guarantee identical performance | ||
| 608 | * between _copy_to_iter_mcsafe() and _copy_to_iter() it would be a | ||
| 609 | * performance regression to switch more users to the mcsafe version. | ||
| 610 | * | ||
| 611 | * Otherwise, the main differences between this and typical _copy_to_iter(). | ||
| 612 | * | ||
| 613 | * * Typical tail/residue handling after a fault retries the copy | ||
| 614 | * byte-by-byte until the fault happens again. Re-triggering machine | ||
| 615 | * checks is potentially fatal so the implementation uses source | ||
| 616 | * alignment and poison alignment assumptions to avoid re-triggering | ||
| 617 | * hardware exceptions. | ||
| 618 | * | ||
| 619 | * * ITER_KVEC, ITER_PIPE, and ITER_BVEC can return short copies. | ||
| 620 | * Compare to copy_to_iter() where only ITER_IOVEC attempts might return | ||
| 621 | * a short copy. | ||
| 622 | * | ||
| 623 | * See MCSAFE_TEST for self-test. | ||
| 624 | */ | ||
| 599 | size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i) | 625 | size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i) |
| 600 | { | 626 | { |
| 601 | const char *from = addr; | 627 | const char *from = addr; |
