livepatch: Convert error about unsupported reliable stacktrace into a warning
[sfrench/cifs-2.6.git] / kernel / livepatch / core.c
index 113645ee86b611ace522ac64904bfa3c06570d80..14f33ab6c583ced8362e94b008893fdc7d075794 100644 (file)
@@ -313,7 +313,6 @@ static int klp_write_object_relocations(struct module *pmod,
  * /sys/kernel/livepatch/<patch>
  * /sys/kernel/livepatch/<patch>/enabled
  * /sys/kernel/livepatch/<patch>/transition
- * /sys/kernel/livepatch/<patch>/signal
  * /sys/kernel/livepatch/<patch>/force
  * /sys/kernel/livepatch/<patch>/<object>
  * /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
@@ -382,35 +381,6 @@ static ssize_t transition_show(struct kobject *kobj,
                        patch == klp_transition_patch);
 }
 
-static ssize_t signal_store(struct kobject *kobj, struct kobj_attribute *attr,
-                           const char *buf, size_t count)
-{
-       struct klp_patch *patch;
-       int ret;
-       bool val;
-
-       ret = kstrtobool(buf, &val);
-       if (ret)
-               return ret;
-
-       if (!val)
-               return count;
-
-       mutex_lock(&klp_mutex);
-
-       patch = container_of(kobj, struct klp_patch, kobj);
-       if (patch != klp_transition_patch) {
-               mutex_unlock(&klp_mutex);
-               return -EINVAL;
-       }
-
-       klp_send_signals();
-
-       mutex_unlock(&klp_mutex);
-
-       return count;
-}
-
 static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr,
                           const char *buf, size_t count)
 {
@@ -442,12 +412,10 @@ static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr,
 
 static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled);
 static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition);
-static struct kobj_attribute signal_kobj_attr = __ATTR_WO(signal);
 static struct kobj_attribute force_kobj_attr = __ATTR_WO(force);
 static struct attribute *klp_patch_attrs[] = {
        &enabled_kobj_attr.attr,
        &transition_kobj_attr.attr,
-       &signal_kobj_attr.attr,
        &force_kobj_attr.attr,
        NULL
 };
@@ -554,7 +522,7 @@ static int klp_add_nops(struct klp_patch *patch)
        struct klp_patch *old_patch;
        struct klp_object *old_obj;
 
-       list_for_each_entry(old_patch, &klp_patches, list) {
+       klp_for_each_patch(old_patch) {
                klp_for_each_object(old_patch, old_obj) {
                        int err;
 
@@ -925,10 +893,6 @@ static int __klp_disable_patch(struct klp_patch *patch)
        if (klp_transition_patch)
                return -EBUSY;
 
-       /* enforce stacking: only the last enabled patch can be disabled */
-       if (!list_is_last(&patch->list, &klp_patches))
-               return -EBUSY;
-
        klp_init_transition(patch, KLP_UNPATCHED);
 
        klp_for_each_object(patch, obj)
@@ -1039,11 +1003,10 @@ int klp_enable_patch(struct klp_patch *patch)
                return -ENODEV;
 
        if (!klp_have_reliable_stack()) {
-               pr_err("This architecture doesn't have support for the livepatch consistency model.\n");
-               return -ENOSYS;
+               pr_warn("This architecture doesn't have support for the livepatch consistency model.\n");
+               pr_warn("The livepatch transition may never complete.\n");
        }
 
-
        mutex_lock(&klp_mutex);
 
        ret = klp_init_patch_early(patch);
@@ -1093,7 +1056,7 @@ void klp_discard_replaced_patches(struct klp_patch *new_patch)
 {
        struct klp_patch *old_patch, *tmp_patch;
 
-       list_for_each_entry_safe(old_patch, tmp_patch, &klp_patches, list) {
+       klp_for_each_patch_safe(old_patch, tmp_patch) {
                if (old_patch == new_patch)
                        return;
 
@@ -1137,7 +1100,7 @@ static void klp_cleanup_module_patches_limited(struct module *mod,
        struct klp_patch *patch;
        struct klp_object *obj;
 
-       list_for_each_entry(patch, &klp_patches, list) {
+       klp_for_each_patch(patch) {
                if (patch == limit)
                        break;
 
@@ -1145,21 +1108,14 @@ static void klp_cleanup_module_patches_limited(struct module *mod,
                        if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
                                continue;
 
-                       /*
-                        * Only unpatch the module if the patch is enabled or
-                        * is in transition.
-                        */
-                       if (patch->enabled || patch == klp_transition_patch) {
-
-                               if (patch != klp_transition_patch)
-                                       klp_pre_unpatch_callback(obj);
+                       if (patch != klp_transition_patch)
+                               klp_pre_unpatch_callback(obj);
 
-                               pr_notice("reverting patch '%s' on unloading module '%s'\n",
-                                         patch->mod->name, obj->mod->name);
-                               klp_unpatch_object(obj);
+                       pr_notice("reverting patch '%s' on unloading module '%s'\n",
+                                 patch->mod->name, obj->mod->name);
+                       klp_unpatch_object(obj);
 
-                               klp_post_unpatch_callback(obj);
-                       }
+                       klp_post_unpatch_callback(obj);
 
                        klp_free_object_loaded(obj);
                        break;
@@ -1184,7 +1140,7 @@ int klp_module_coming(struct module *mod)
         */
        mod->klp_alive = true;
 
-       list_for_each_entry(patch, &klp_patches, list) {
+       klp_for_each_patch(patch) {
                klp_for_each_object(patch, obj) {
                        if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
                                continue;
@@ -1198,13 +1154,6 @@ int klp_module_coming(struct module *mod)
                                goto err;
                        }
 
-                       /*
-                        * Only patch the module if the patch is enabled or is
-                        * in transition.
-                        */
-                       if (!patch->enabled && patch != klp_transition_patch)
-                               break;
-
                        pr_notice("applying patch '%s' to loading module '%s'\n",
                                  patch->mod->name, obj->mod->name);