Commit fafd6b47 authored by Tong Tiangen's avatar Tong Tiangen
Browse files

arm64: add machine check safe sysctl interface

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8M74H


CVE: NA

-------------------------------

Add /proc/sys/kernel/machine_check_safe_enable. Set 1(default value) to
enable machine check safe support. Set 0(default) to disable machine
check safe support.

Signed-off-by: default avatarTong Tiangen <tongtiangen@huawei.com>
parent c478eeb8
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -540,6 +540,20 @@ if leaking kernel pointer values to unprivileged users is a concern.
When ``kptr_restrict`` is set to 2, kernel pointers printed using
%pK will be replaced with 0s regardless of privileges.

machine_check_safe (arm64 only)
================================

This indicates whether the Machine Check safe memory copy feature enabled
or not,which only exists on arm64 when ARCH_HAS_COPY_MC enabled.

The value in this file determines the behaviour of the kernel when
synchronous exception from memory copy.

= ===================================================================
0 the kernel will panic immediately.
1 the kernel will recover since a memcpy-variant provided which can
  safely fail when accessing to hwpoison.
= ===================================================================

modprobe
========
+29 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/perf_event.h>
#include <linux/preempt.h>
#include <linux/hugetlb.h>
#include <linux/sysctl.h>

#include <asm/acpi.h>
#include <asm/bug.h>
@@ -43,6 +44,31 @@
#include <asm/tlbflush.h>
#include <asm/traps.h>

static int sysctl_machine_check_safe = IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC);

#ifdef CONFIG_ARCH_HAS_COPY_MC
static struct ctl_table machine_check_safe_sysctl_table[] = {
	{
		.procname       = "machine_check_safe",
		.data           = &sysctl_machine_check_safe,
		.maxlen         = sizeof(sysctl_machine_check_safe),
		.mode           = 0644,
		.proc_handler   = proc_dointvec_minmax,
		.extra1         = SYSCTL_ZERO,
		.extra2         = SYSCTL_ONE,
	},
};

static int __init machine_check_safe_sysctl_init(void)
{
	if (!register_sysctl("kernel", machine_check_safe_sysctl_table))
		return -EINVAL;
	return 0;
}

core_initcall(machine_check_safe_sysctl_init);
#endif

struct fault_info {
	int	(*fn)(unsigned long far, unsigned long esr,
		      struct pt_regs *regs);
@@ -734,6 +760,9 @@ static bool arm64_do_kernel_sea(unsigned long addr, unsigned int esr,
	if (!IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC))
		return false;

	if (!sysctl_machine_check_safe)
		return false;

	if (user_mode(regs))
		return false;