[PATCH v2 3/3] livepatch: Add a sysctl livepatch_mode for atomic replace

From: Jason Baron
Date: Wed Aug 30 2017 - 17:40:32 EST


Introduce a sysctl knob such that by default livepatch is not in
'atomic replace' mode. A '0' in /proc/sys/kernel/livepatch_mode means the
current default mode, while a '1' means do atomic replace.

This patch is not meant to be applied and is for testing purposes only. The
intent is for the tool that creates the livepatch modules to set the 'replace'
field in struct klp_patch to 1, to indicate that atomic replace mode is
being requested, 0 otherwise.

Signed-off-by: Jason Baron <jbaron@xxxxxxxxxx>
Cc: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
Cc: Jessica Yu <jeyu@xxxxxxxxxx>
Cc: Jiri Kosina <jikos@xxxxxxxxxx>
Cc: Miroslav Benes <mbenes@xxxxxxx>
Cc: Petr Mladek <pmladek@xxxxxxxx>
---
include/linux/livepatch.h | 8 ++++++++
kernel/livepatch/core.c | 7 +++++++
kernel/sysctl.c | 12 ++++++++++++
3 files changed, 27 insertions(+)

diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index ee6d18b..3c4df79 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -35,6 +35,14 @@
#define KLP_UNPATCHED 0
#define KLP_PATCHED 1

+/* livepatch mode */
+
+extern int sysctl_livepatch_mode;
+enum {
+ LIVEPATCH_MODE_DEFAULT,
+ LIVEPATCH_MODE_REPLACE,
+};
+
/**
* struct klp_func - function structure for live patching
* @old_name: name of the function to be patched
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 21cecc5..cdd89a4 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -49,6 +49,8 @@ LIST_HEAD(klp_patches);

static struct kobject *klp_root_kobj;

+int sysctl_livepatch_mode;
+
static bool klp_is_module(struct klp_object *obj)
{
return obj->name;
@@ -868,6 +870,11 @@ static int klp_init_patch(struct klp_patch *patch)
patch->enabled = false;
patch->replaced = false;

+ if (sysctl_livepatch_mode == LIVEPATCH_MODE_REPLACE)
+ patch->replace = true;
+ else
+ patch->replace = false;
+
init_completion(&patch->finish);

ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4dfba1a..3a0a1f6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -67,6 +67,7 @@
#include <linux/kexec.h>
#include <linux/bpf.h>
#include <linux/mount.h>
+#include <linux/livepatch.h>

#include <linux/uaccess.h>
#include <asm/processor.h>
@@ -1203,6 +1204,17 @@ static struct ctl_table kern_table[] = {
.extra2 = &one,
},
#endif
+#ifdef CONFIG_LIVEPATCH
+ {
+ .procname = "livepatch_mode",
+ .data = &sysctl_livepatch_mode,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+#endif
{ }
};

--
2.6.1