diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 2614247a9781..89df578af8c3 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -106,9 +106,11 @@ struct klp_callbacks {
  * struct klp_object - kernel object structure for live patching
  * @name:	module name (or NULL for vmlinux)
  * @funcs:	function entries for functions to be patched in the object
+ * @funcs_stack:	function entries for functions to be stack checked
  * @callbacks:	functions to be executed pre/post (un)patching
  * @kobj:	kobject for sysfs resources
  * @func_list:	dynamic list of the function entries
+ * @func_stack_list:	dynamic list of the function entries for stack checking
  * @node:	list node for klp_patch obj_list
  * @mod:	kernel module associated with the patched object
  *		(NULL for vmlinux)
@@ -119,11 +121,13 @@ struct klp_object {
 	/* external */
 	const char *name;
 	struct klp_func *funcs;
+	struct klp_func *funcs_stack;
 	struct klp_callbacks callbacks;
 
 	/* internal */
 	struct kobject kobj;
 	struct list_head func_list;
+	struct list_head func_stack_list;
 	struct list_head node;
 	struct module *mod;
 	bool dynamic;
@@ -187,12 +191,19 @@ struct klp_patch {
 	     func->old_name || func->new_func || func->old_sympos; \
 	     func++)
 
+#define klp_for_each_func_stack_static(obj, func) \
+	for (func = obj->funcs_stack; \
+	     func && (func->old_name || func->old_sympos); func++)
+
 #define klp_for_each_func_safe(obj, func, tmp_func)			\
 	list_for_each_entry_safe(func, tmp_func, &obj->func_list, node)
 
 #define klp_for_each_func(obj, func)	\
 	list_for_each_entry(func, &obj->func_list, node)
 
+#define klp_for_each_func_stack(obj, func)	\
+	list_for_each_entry(func, &obj->func_stack_list, node)
+
 int klp_enable_patch(struct klp_patch *);
 
 /* Called from the module loader during module coming/going states */
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 3d8e3caf9f92..86fc73a06844 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -825,6 +825,12 @@ static int klp_init_object_loaded(struct klp_patch *patch,
 		}
 	}
 
+	klp_for_each_func_stack(obj, func) {
+		ret = klp_init_old_func(obj, func);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -853,6 +859,11 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
 			return ret;
 	}
 
+	klp_for_each_func_stack(obj, func) {
+		if (strlen(func->old_name) >= KSYM_NAME_LEN)
+			return -EINVAL;
+	}
+
 	if (klp_is_object_loaded(obj))
 		ret = klp_init_object_loaded(patch, obj);
 
@@ -870,6 +881,7 @@ static void klp_init_object_early(struct klp_patch *patch,
 				  struct klp_object *obj)
 {
 	INIT_LIST_HEAD(&obj->func_list);
+	INIT_LIST_HEAD(&obj->func_stack_list);
 	kobject_init(&obj->kobj, &klp_ktype_object);
 	list_add_tail(&obj->node, &patch->obj_list);
 }
@@ -899,6 +911,10 @@ static int klp_init_patch_early(struct klp_patch *patch)
 		klp_for_each_func_static(obj, func) {
 			klp_init_func_early(obj, func);
 		}
+
+		klp_for_each_func_stack_static(obj, func) {
+			list_add_tail(&func->node, &obj->func_stack_list);
+		}
 	}
 
 	if (!try_module_get(patch->mod))
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 5683ac0d2566..be7afc5dc275 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -200,7 +200,10 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries,
 	for (i = 0; i < nr_entries; i++) {
 		address = entries[i];
 
-		if (klp_target_state == KLP_UNPATCHED) {
+		if (!func->new_func) {
+			func_addr = (unsigned long)func->old_func;
+			func_size = func->old_size;
+		} else if (klp_target_state == KLP_UNPATCHED) {
 			 /*
 			  * Check for the to-be-unpatched function
 			  * (the func itself).
@@ -256,14 +259,22 @@ static int klp_check_stack(struct task_struct *task, const char **oldname)
 			continue;
 		klp_for_each_func(obj, func) {
 			ret = klp_check_stack_func(func, entries, nr_entries);
-			if (ret) {
-				*oldname = func->old_name;
-				return -EADDRINUSE;
-			}
+			if (ret)
+				goto err;
+		}
+
+		klp_for_each_func_stack(obj, func) {
+			ret = klp_check_stack_func(func, entries, nr_entries);
+			if (ret)
+				goto err;
 		}
 	}
 
 	return 0;
+
+err:
+	*oldname = func->old_name;
+	return -EADDRINUSE;
 }
 
 static int klp_check_and_switch_task(struct task_struct *task, void *arg)
