Commit 930218af authored by Dan Williams's avatar Dan Williams
Browse files

Merge branch 'for-4.18/mcsafe' into libnvdimm-for-next

parents b5684579 5d8beee2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ config X86
	select ARCH_HAS_PMEM_API		if X86_64
	select ARCH_HAS_REFCOUNT
	select ARCH_HAS_UACCESS_FLUSHCACHE	if X86_64
	select ARCH_HAS_UACCESS_MCSAFE		if X86_64
	select ARCH_HAS_SET_MEMORY
	select ARCH_HAS_SG_CHAIN
	select ARCH_HAS_STRICT_KERNEL_RWX
+3 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ config EARLY_PRINTK_USB_XDBC
	  You should normally say N here, unless you want to debug early
	  crashes or need a very simple printk logging facility.

config MCSAFE_TEST
	def_bool n

config X86_PTDUMP_CORE
	def_bool n

+75 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _MCSAFE_TEST_H_
#define _MCSAFE_TEST_H_

#ifndef __ASSEMBLY__
#ifdef CONFIG_MCSAFE_TEST
extern unsigned long mcsafe_test_src;
extern unsigned long mcsafe_test_dst;

static inline void mcsafe_inject_src(void *addr)
{
	if (addr)
		mcsafe_test_src = (unsigned long) addr;
	else
		mcsafe_test_src = ~0UL;
}

static inline void mcsafe_inject_dst(void *addr)
{
	if (addr)
		mcsafe_test_dst = (unsigned long) addr;
	else
		mcsafe_test_dst = ~0UL;
}
#else /* CONFIG_MCSAFE_TEST */
static inline void mcsafe_inject_src(void *addr)
{
}

static inline void mcsafe_inject_dst(void *addr)
{
}
#endif /* CONFIG_MCSAFE_TEST */

#else /* __ASSEMBLY__ */
#include <asm/export.h>

#ifdef CONFIG_MCSAFE_TEST
.macro MCSAFE_TEST_CTL
	.pushsection .data
	.align 8
	.globl mcsafe_test_src
	mcsafe_test_src:
		.quad 0
	EXPORT_SYMBOL_GPL(mcsafe_test_src)
	.globl mcsafe_test_dst
	mcsafe_test_dst:
		.quad 0
	EXPORT_SYMBOL_GPL(mcsafe_test_dst)
	.popsection
.endm

.macro MCSAFE_TEST_SRC reg count target
	leaq \count(\reg), %r9
	cmp mcsafe_test_src, %r9
	ja \target
.endm

.macro MCSAFE_TEST_DST reg count target
	leaq \count(\reg), %r9
	cmp mcsafe_test_dst, %r9
	ja \target
.endm
#else
.macro MCSAFE_TEST_CTL
.endm

.macro MCSAFE_TEST_SRC reg count target
.endm

.macro MCSAFE_TEST_DST reg count target
.endm
#endif /* CONFIG_MCSAFE_TEST */
#endif /* __ASSEMBLY__ */
#endif /* _MCSAFE_TEST_H_ */
+6 −4
Original line number Diff line number Diff line
@@ -116,7 +116,8 @@ int strcmp(const char *cs, const char *ct);
#endif

#define __HAVE_ARCH_MEMCPY_MCSAFE 1
__must_check int memcpy_mcsafe_unrolled(void *dst, const void *src, size_t cnt);
__must_check unsigned long __memcpy_mcsafe(void *dst, const void *src,
		size_t cnt);
DECLARE_STATIC_KEY_FALSE(mcsafe_key);

/**
@@ -131,14 +132,15 @@ DECLARE_STATIC_KEY_FALSE(mcsafe_key);
 * actually do machine check recovery. Everyone else can just
 * use memcpy().
 *
 * Return 0 for success, -EFAULT for fail
 * Return 0 for success, or number of bytes not copied if there was an
 * exception.
 */
static __always_inline __must_check int
static __always_inline __must_check unsigned long
memcpy_mcsafe(void *dst, const void *src, size_t cnt)
{
#ifdef CONFIG_X86_MCE
	if (static_branch_unlikely(&mcsafe_key))
		return memcpy_mcsafe_unrolled(dst, src, cnt);
		return __memcpy_mcsafe(dst, src, cnt);
	else
#endif
		memcpy(dst, src, cnt);
+14 −0
Original line number Diff line number Diff line
@@ -46,6 +46,17 @@ copy_user_generic(void *to, const void *from, unsigned len)
	return ret;
}

static __always_inline __must_check unsigned long
copy_to_user_mcsafe(void *to, const void *from, unsigned len)
{
	unsigned long ret;

	__uaccess_begin();
	ret = memcpy_mcsafe(to, from, len);
	__uaccess_end();
	return ret;
}

static __always_inline __must_check unsigned long
raw_copy_from_user(void *dst, const void __user *src, unsigned long size)
{
@@ -194,4 +205,7 @@ __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
unsigned long
copy_user_handle_tail(char *to, char *from, unsigned len);

unsigned long
mcsafe_handle_tail(char *to, char *from, unsigned len);

#endif /* _ASM_X86_UACCESS_64_H */
Loading