Commit fdcbb1bc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'nocache-cleanup'



This series cleans up some of the special user copy functions naming and
semantics.  In particular, get rid of the (very traditional) double
underscore names and behavior: the whole "optimize away the range check"
model has been largely excised from the other user accessors because
it's so subtle and can be unsafe, but also because it's just not a
relevant optimization any more.

To do that, a couple of drivers that misused the "user" copies as kernel
copies in order to get non-temporal stores had to be fixed up, but that
kind of code should never have been allowed anyway.

The x86-only "nocache" version was also renamed to more accurately
reflect what it actually does.

This was all done because I looked at this code due to a report by Jann
Horn, and I just couldn't stand the inconsistent naming, the horrible
semantics, and the random misuse of these functions.  This code should
probably be cleaned up further, but it's at least slightly closer to
normal semantics.

I had a more intrusive series that went even further in trying to
normalize the semantics, but that ended up hitting so many other
inconsistencies between different architectures in this area (eg
'size_t' vs 'unsigned long' vs 'int' as size arguments, and various
iovec check differences that Vasily Gorbik pointed out) that I ended up
with this more limited version that fixed the worst of the issues.

Reported-by: default avatarJann Horn <jannh@google.com>
Tested-by: default avatarWill Deacon <will@kernel.org>
Link: https://lore.kernel.org/all/CAHk-=wgg1QVWNWG-UCFo1hx0zqrPnB3qhPzUTrWNft+MtXQXig@mail.gmail.com/

* nocache-cleanup:
  x86-64/arm64/powerpc: clean up and rename __copy_from_user_flushcache
  x86: rename and clean up __copy_from_user_inatomic_nocache()
  x86-64: rename misleadingly named '__copy_user_nocache()' function
parents 028ef9c9 809b997a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ extern __must_check long strnlen_user(const char __user *str, long n);
#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE
extern unsigned long __must_check __copy_user_flushcache(void *to, const void __user *from, unsigned long n);

static inline int __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
static inline size_t copy_from_user_flushcache(void *dst, const void __user *src, size_t size)
{
	kasan_check_write(dst, size);
	return __copy_user_flushcache(dst, __uaccess_mask_ptr(src), size);
+1 −2
Original line number Diff line number Diff line
@@ -434,8 +434,7 @@ copy_mc_to_user(void __user *to, const void *from, unsigned long n)
}
#endif

extern long __copy_from_user_flushcache(void *dst, const void __user *src,
		unsigned size);
extern size_t copy_from_user_flushcache(void *dst, const void __user *src, size_t size);

static __must_check __always_inline bool __user_access_begin(const void __user *ptr, size_t len,
							     unsigned long dir)
+6 −5
Original line number Diff line number Diff line
@@ -66,15 +66,16 @@ EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
/*
 * CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
 */
long __copy_from_user_flushcache(void *dest, const void __user *src,
		unsigned size)
size_t copy_from_user_flushcache(void *dest, const void __user *src,
				 size_t size)
{
	unsigned long copied, start = (unsigned long) dest;
	unsigned long not_copied, start = (unsigned long) dest;

	copied = __copy_from_user(dest, src, size);
	src = mask_user_address(src);
	not_copied = __copy_from_user(dest, src, size);
	clean_pmem_range(start, start + size);

	return copied;
	return not_copied;
}

void memcpy_flushcache(void *dest, const void *src, size_t size)
+1 −1
Original line number Diff line number Diff line
@@ -507,7 +507,7 @@ extern struct movsl_mask {
} ____cacheline_aligned_in_smp movsl_mask;
#endif

#define ARCH_HAS_NOCACHE_UACCESS 1
#define ARCH_HAS_NONTEMPORAL_UACCESS 1

/*
 * The "unsafe" user accesses aren't really "unsafe", but the naming
+1 −7
Original line number Diff line number Diff line
@@ -26,13 +26,7 @@ raw_copy_from_user(void *to, const void __user *from, unsigned long n)
	return __copy_user_ll(to, (__force const void *)from, n);
}

static __always_inline unsigned long
__copy_from_user_inatomic_nocache(void *to, const void __user *from,
				  unsigned long n)
{
       return __copy_from_user_ll_nocache_nozero(to, from, n);
}

unsigned long __must_check copy_from_user_inatomic_nontemporal(void *, const void __user *, unsigned long n);
unsigned long __must_check clear_user(void __user *mem, unsigned long len);
unsigned long __must_check __clear_user(void __user *mem, unsigned long len);

Loading