|
@@ -454,6 +454,7 @@ EXPORT_SYMBOL_GPL(klp_enable_patch);
|
|
|
* /sys/kernel/livepatch/<patch>
|
|
|
* /sys/kernel/livepatch/<patch>/enabled
|
|
|
* /sys/kernel/livepatch/<patch>/transition
|
|
|
+ * /sys/kernel/livepatch/<patch>/signal
|
|
|
* /sys/kernel/livepatch/<patch>/<object>
|
|
|
* /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
|
|
|
*/
|
|
@@ -528,11 +529,40 @@ 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;
|
|
|
+
|
|
|
+ patch = container_of(kobj, struct klp_patch, kobj);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * klp_mutex lock is not grabbed here intentionally. It is not really
|
|
|
+ * needed. The race window is harmless and grabbing the lock would only
|
|
|
+ * hold the action back.
|
|
|
+ */
|
|
|
+ if (patch != klp_transition_patch)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ret = kstrtobool(buf, &val);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (val)
|
|
|
+ klp_send_signals();
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
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 attribute *klp_patch_attrs[] = {
|
|
|
&enabled_kobj_attr.attr,
|
|
|
&transition_kobj_attr.attr,
|
|
|
+ &signal_kobj_attr.attr,
|
|
|
NULL
|
|
|
};
|
|
|
|