diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-21 19:52:08 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-21 19:52:08 -0400 |
| commit | ea75a2c715a4bf682c756d4754665fb3595f3531 (patch) | |
| tree | ee2b4979e9c3b7b35dae23578264c1dfa2a55c72 | |
| parent | ffb48e7924768d760bcd63212c8530c010059215 (diff) | |
| parent | 092b31aa2048cf7561a39697974adcd147fbb27b (diff) | |
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core kernel fixes from Ingo Molnar:
"This is mostly the copy_to_user_mcsafe() related fixes from Dan
Williams, and an ORC fix for Clang"
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/asm/memcpy_mcsafe: Fix copy_to_user_mcsafe() exception handling
lib/iov_iter: Fix pipe handling in _copy_to_iter_mcsafe()
lib/iov_iter: Document _copy_to_iter_flushcache()
lib/iov_iter: Document _copy_to_iter_mcsafe()
objtool: Use '.strtab' if '.shstrtab' doesn't exist, to support ORC tables on Clang
| -rw-r--r-- | arch/x86/Kconfig | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/uaccess_64.h | 7 | ||||
| -rw-r--r-- | lib/iov_iter.c | 77 | ||||
| -rw-r--r-- | tools/objtool/elf.c | 6 |
4 files changed, 84 insertions, 8 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f1dbb4ee19d7..887d3a7bb646 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -63,7 +63,7 @@ config X86 | |||
| 63 | select ARCH_HAS_PTE_SPECIAL | 63 | select ARCH_HAS_PTE_SPECIAL |
| 64 | select ARCH_HAS_REFCOUNT | 64 | select ARCH_HAS_REFCOUNT |
| 65 | select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 | 65 | select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 |
| 66 | select ARCH_HAS_UACCESS_MCSAFE if X86_64 | 66 | select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE |
| 67 | select ARCH_HAS_SET_MEMORY | 67 | select ARCH_HAS_SET_MEMORY |
| 68 | select ARCH_HAS_SG_CHAIN | 68 | select ARCH_HAS_SG_CHAIN |
| 69 | select ARCH_HAS_STRICT_KERNEL_RWX | 69 | select ARCH_HAS_STRICT_KERNEL_RWX |
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 62acb613114b..a9d637bc301d 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h | |||
| @@ -52,7 +52,12 @@ copy_to_user_mcsafe(void *to, const void *from, unsigned len) | |||
| 52 | unsigned long ret; | 52 | unsigned long ret; |
| 53 | 53 | ||
| 54 | __uaccess_begin(); | 54 | __uaccess_begin(); |
| 55 | ret = memcpy_mcsafe(to, from, len); | 55 | /* |
| 56 | * Note, __memcpy_mcsafe() is explicitly used since it can | ||
| 57 | * handle exceptions / faults. memcpy_mcsafe() may fall back to | ||
| 58 | * memcpy() which lacks this handling. | ||
| 59 | */ | ||
| 60 | ret = __memcpy_mcsafe(to, from, len); | ||
| 56 | __uaccess_end(); | 61 | __uaccess_end(); |
| 57 | return ret; | 62 | return ret; |
| 58 | } | 63 | } |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 7e43cd54c84c..8be175df3075 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -596,15 +596,70 @@ static unsigned long memcpy_mcsafe_to_page(struct page *page, size_t offset, | |||
| 596 | return ret; | 596 | return ret; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | static size_t copy_pipe_to_iter_mcsafe(const void *addr, size_t bytes, | ||
| 600 | struct iov_iter *i) | ||
| 601 | { | ||
| 602 | struct pipe_inode_info *pipe = i->pipe; | ||
| 603 | size_t n, off, xfer = 0; | ||
| 604 | int idx; | ||
| 605 | |||
| 606 | if (!sanity(i)) | ||
| 607 | return 0; | ||
| 608 | |||
| 609 | bytes = n = push_pipe(i, bytes, &idx, &off); | ||
| 610 | if (unlikely(!n)) | ||
| 611 | return 0; | ||
| 612 | for ( ; n; idx = next_idx(idx, pipe), off = 0) { | ||
| 613 | size_t chunk = min_t(size_t, n, PAGE_SIZE - off); | ||
| 614 | unsigned long rem; | ||
| 615 | |||
| 616 | rem = memcpy_mcsafe_to_page(pipe->bufs[idx].page, off, addr, | ||
| 617 | chunk); | ||
| 618 | i->idx = idx; | ||
| 619 | i->iov_offset = off + chunk - rem; | ||
| 620 | xfer += chunk - rem; | ||
| 621 | if (rem) | ||
| 622 | break; | ||
| 623 | n -= chunk; | ||
| 624 | addr += chunk; | ||
| 625 | } | ||
| 626 | i->count -= xfer; | ||
| 627 | return xfer; | ||
| 628 | } | ||
| 629 | |||
| 630 | /** | ||
| 631 | * _copy_to_iter_mcsafe - copy to user with source-read error exception handling | ||
| 632 | * @addr: source kernel address | ||
| 633 | * @bytes: total transfer length | ||
| 634 | * @iter: destination iterator | ||
| 635 | * | ||
| 636 | * The pmem driver arranges for filesystem-dax to use this facility via | ||
| 637 | * dax_copy_to_iter() for protecting read/write to persistent memory. | ||
| 638 | * Unless / until an architecture can guarantee identical performance | ||
| 639 | * between _copy_to_iter_mcsafe() and _copy_to_iter() it would be a | ||
| 640 | * performance regression to switch more users to the mcsafe version. | ||
| 641 | * | ||
| 642 | * Otherwise, the main differences between this and typical _copy_to_iter(). | ||
| 643 | * | ||
| 644 | * * Typical tail/residue handling after a fault retries the copy | ||
| 645 | * byte-by-byte until the fault happens again. Re-triggering machine | ||
| 646 | * checks is potentially fatal so the implementation uses source | ||
| 647 | * alignment and poison alignment assumptions to avoid re-triggering | ||
| 648 | * hardware exceptions. | ||
| 649 | * | ||
| 650 | * * ITER_KVEC, ITER_PIPE, and ITER_BVEC can return short copies. | ||
| 651 | * Compare to copy_to_iter() where only ITER_IOVEC attempts might return | ||
| 652 | * a short copy. | ||
| 653 | * | ||
| 654 | * See MCSAFE_TEST for self-test. | ||
| 655 | */ | ||
| 599 | size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i) | 656 | size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i) |
| 600 | { | 657 | { |
| 601 | const char *from = addr; | 658 | const char *from = addr; |
| 602 | unsigned long rem, curr_addr, s_addr = (unsigned long) addr; | 659 | unsigned long rem, curr_addr, s_addr = (unsigned long) addr; |
| 603 | 660 | ||
| 604 | if (unlikely(i->type & ITER_PIPE)) { | 661 | if (unlikely(i->type & ITER_PIPE)) |
| 605 | WARN_ON(1); | 662 | return copy_pipe_to_iter_mcsafe(addr, bytes, i); |
| 606 | return 0; | ||
| 607 | } | ||
| 608 | if (iter_is_iovec(i)) | 663 | if (iter_is_iovec(i)) |
| 609 | might_fault(); | 664 | might_fault(); |
| 610 | iterate_and_advance(i, bytes, v, | 665 | iterate_and_advance(i, bytes, v, |
| @@ -701,6 +756,20 @@ size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i) | |||
| 701 | EXPORT_SYMBOL(_copy_from_iter_nocache); | 756 | EXPORT_SYMBOL(_copy_from_iter_nocache); |
| 702 | 757 | ||
| 703 | #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE | 758 | #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE |
| 759 | /** | ||
| 760 | * _copy_from_iter_flushcache - write destination through cpu cache | ||
| 761 | * @addr: destination kernel address | ||
| 762 | * @bytes: total transfer length | ||
| 763 | * @iter: source iterator | ||
| 764 | * | ||
| 765 | * The pmem driver arranges for filesystem-dax to use this facility via | ||
| 766 | * dax_copy_from_iter() for ensuring that writes to persistent memory | ||
| 767 | * are flushed through the CPU cache. It is differentiated from | ||
| 768 | * _copy_from_iter_nocache() in that guarantees all data is flushed for | ||
| 769 | * all iterator types. The _copy_from_iter_nocache() only attempts to | ||
| 770 | * bypass the cache for the ITER_IOVEC case, and on some archs may use | ||
| 771 | * instructions that strand dirty-data in the cache. | ||
| 772 | */ | ||
| 704 | size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i) | 773 | size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i) |
| 705 | { | 774 | { |
| 706 | char *to = addr; | 775 | char *to = addr; |
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 0d1acb704f64..7ec85d567598 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c | |||
| @@ -519,10 +519,12 @@ struct section *elf_create_section(struct elf *elf, const char *name, | |||
| 519 | sec->sh.sh_flags = SHF_ALLOC; | 519 | sec->sh.sh_flags = SHF_ALLOC; |
| 520 | 520 | ||
| 521 | 521 | ||
| 522 | /* Add section name to .shstrtab */ | 522 | /* Add section name to .shstrtab (or .strtab for Clang) */ |
| 523 | shstrtab = find_section_by_name(elf, ".shstrtab"); | 523 | shstrtab = find_section_by_name(elf, ".shstrtab"); |
| 524 | if (!shstrtab) | ||
| 525 | shstrtab = find_section_by_name(elf, ".strtab"); | ||
| 524 | if (!shstrtab) { | 526 | if (!shstrtab) { |
| 525 | WARN("can't find .shstrtab section"); | 527 | WARN("can't find .shstrtab or .strtab section"); |
| 526 | return NULL; | 528 | return NULL; |
| 527 | } | 529 | } |
| 528 | 530 | ||
