summaryrefslogtreecommitdiffstats
path: root/kernel/livepatch
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-08-12 14:36:27 +0200
committerThomas Gleixner <tglx@linutronix.de>2019-08-12 14:36:27 +0200
commitcbd32a1c56e36fedaa93a727699188bd3e6e6f67 (patch)
tree199e302eb5a66725a9d1774e47367a87098ba397 /kernel/livepatch
parent48c7d73b2362ce61503551ad70052617b3e8857d (diff)
parentb61fbc887af7a13a1c90c84c1feaeb4c9780e1e2 (diff)
downloadcachepc-linux-cbd32a1c56e36fedaa93a727699188bd3e6e6f67.tar.gz
cachepc-linux-cbd32a1c56e36fedaa93a727699188bd3e6e6f67.zip
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into efi/urgent
Pull a single EFI fix for v5.3 from Ard: - Fix mixed mode breakage in EFI config table handling for TPM.
Diffstat (limited to 'kernel/livepatch')
-rw-r--r--kernel/livepatch/core.c6
-rw-r--r--kernel/livepatch/transition.c11
2 files changed, 14 insertions, 3 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 2398832947c6..c4ce08f43bd6 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -18,6 +18,7 @@
#include <linux/elf.h>
#include <linux/moduleloader.h>
#include <linux/completion.h>
+#include <linux/memory.h>
#include <asm/cacheflush.h>
#include "core.h"
#include "patch.h"
@@ -718,16 +719,21 @@ static int klp_init_object_loaded(struct klp_patch *patch,
struct klp_func *func;
int ret;
+ mutex_lock(&text_mutex);
+
module_disable_ro(patch->mod);
ret = klp_write_object_relocations(patch->mod, obj);
if (ret) {
module_enable_ro(patch->mod, true);
+ mutex_unlock(&text_mutex);
return ret;
}
arch_klp_init_object_loaded(patch, obj);
module_enable_ro(patch->mod, true);
+ mutex_unlock(&text_mutex);
+
klp_for_each_func(obj, func) {
ret = klp_find_object_symbol(obj->name, func->old_name,
func->old_sympos,
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index abb2a4a2cbb2..cdf318d86dd6 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -247,7 +247,6 @@ static int klp_check_stack(struct task_struct *task, char *err_buf)
int ret, nr_entries;
ret = stack_trace_save_tsk_reliable(task, entries, ARRAY_SIZE(entries));
- WARN_ON_ONCE(ret == -ENOSYS);
if (ret < 0) {
snprintf(err_buf, STACK_ERR_BUF_SIZE,
"%s: %s:%d has an unreliable stack\n",
@@ -281,11 +280,11 @@ static int klp_check_stack(struct task_struct *task, char *err_buf)
*/
static bool klp_try_switch_task(struct task_struct *task)
{
+ static char err_buf[STACK_ERR_BUF_SIZE];
struct rq *rq;
struct rq_flags flags;
int ret;
bool success = false;
- char err_buf[STACK_ERR_BUF_SIZE];
err_buf[0] = '\0';
@@ -294,6 +293,13 @@ static bool klp_try_switch_task(struct task_struct *task)
return true;
/*
+ * For arches which don't have reliable stack traces, we have to rely
+ * on other methods (e.g., switching tasks at kernel exit).
+ */
+ if (!klp_have_reliable_stack())
+ return false;
+
+ /*
* Now try to check the stack for any to-be-patched or to-be-unpatched
* functions. If all goes well, switch the task to the target patch
* state.
@@ -328,7 +334,6 @@ done:
pr_debug("%s", err_buf);
return success;
-
}
/*