aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/livepatch/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r--kernel/livepatch/core.c36
1 files changed, 11 insertions, 25 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index fe1993399823..eb0ee10a1981 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -522,7 +522,7 @@ static int klp_add_nops(struct klp_patch *patch)
522 struct klp_patch *old_patch; 522 struct klp_patch *old_patch;
523 struct klp_object *old_obj; 523 struct klp_object *old_obj;
524 524
525 list_for_each_entry(old_patch, &klp_patches, list) { 525 klp_for_each_patch(old_patch) {
526 klp_for_each_object(old_patch, old_obj) { 526 klp_for_each_object(old_patch, old_obj) {
527 int err; 527 int err;
528 528
@@ -1004,7 +1004,7 @@ int klp_enable_patch(struct klp_patch *patch)
1004 1004
1005 if (!klp_have_reliable_stack()) { 1005 if (!klp_have_reliable_stack()) {
1006 pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); 1006 pr_err("This architecture doesn't have support for the livepatch consistency model.\n");
1007 return -ENOSYS; 1007 return -EOPNOTSUPP;
1008 } 1008 }
1009 1009
1010 1010
@@ -1057,7 +1057,7 @@ void klp_discard_replaced_patches(struct klp_patch *new_patch)
1057{ 1057{
1058 struct klp_patch *old_patch, *tmp_patch; 1058 struct klp_patch *old_patch, *tmp_patch;
1059 1059
1060 list_for_each_entry_safe(old_patch, tmp_patch, &klp_patches, list) { 1060 klp_for_each_patch_safe(old_patch, tmp_patch) {
1061 if (old_patch == new_patch) 1061 if (old_patch == new_patch)
1062 return; 1062 return;
1063 1063
@@ -1101,7 +1101,7 @@ static void klp_cleanup_module_patches_limited(struct module *mod,
1101 struct klp_patch *patch; 1101 struct klp_patch *patch;
1102 struct klp_object *obj; 1102 struct klp_object *obj;
1103 1103
1104 list_for_each_entry(patch, &klp_patches, list) { 1104 klp_for_each_patch(patch) {
1105 if (patch == limit) 1105 if (patch == limit)
1106 break; 1106 break;
1107 1107
@@ -1109,21 +1109,14 @@ static void klp_cleanup_module_patches_limited(struct module *mod,
1109 if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 1109 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
1110 continue; 1110 continue;
1111 1111
1112 /* 1112 if (patch != klp_transition_patch)
1113 * Only unpatch the module if the patch is enabled or 1113 klp_pre_unpatch_callback(obj);
1114 * is in transition.
1115 */
1116 if (patch->enabled || patch == klp_transition_patch) {
1117
1118 if (patch != klp_transition_patch)
1119 klp_pre_unpatch_callback(obj);
1120 1114
1121 pr_notice("reverting patch '%s' on unloading module '%s'\n", 1115 pr_notice("reverting patch '%s' on unloading module '%s'\n",
1122 patch->mod->name, obj->mod->name); 1116 patch->mod->name, obj->mod->name);
1123 klp_unpatch_object(obj); 1117 klp_unpatch_object(obj);
1124 1118
1125 klp_post_unpatch_callback(obj); 1119 klp_post_unpatch_callback(obj);
1126 }
1127 1120
1128 klp_free_object_loaded(obj); 1121 klp_free_object_loaded(obj);
1129 break; 1122 break;
@@ -1148,7 +1141,7 @@ int klp_module_coming(struct module *mod)
1148 */ 1141 */
1149 mod->klp_alive = true; 1142 mod->klp_alive = true;
1150 1143
1151 list_for_each_entry(patch, &klp_patches, list) { 1144 klp_for_each_patch(patch) {
1152 klp_for_each_object(patch, obj) { 1145 klp_for_each_object(patch, obj) {
1153 if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 1146 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
1154 continue; 1147 continue;
@@ -1162,13 +1155,6 @@ int klp_module_coming(struct module *mod)
1162 goto err; 1155 goto err;
1163 } 1156 }
1164 1157
1165 /*
1166 * Only patch the module if the patch is enabled or is
1167 * in transition.
1168 */
1169 if (!patch->enabled && patch != klp_transition_patch)
1170 break;
1171
1172 pr_notice("applying patch '%s' to loading module '%s'\n", 1158 pr_notice("applying patch '%s' to loading module '%s'\n",
1173 patch->mod->name, obj->mod->name); 1159 patch->mod->name, obj->mod->name);
1174 1160