When building a livepatch, a user can set it to be either an atomic-replace
livepatch or a non-atomic-replace livepatch. However, it is not easy to
identify whether a livepatch is atomic-replace or not until it actually
replaces some old livepatches. This can lead to mistakes in a mixed
atomic-replace and non-atomic-replace environment, especially when
transitioning all livepatches from non-atomic-replace to atomic-replace in
a large fleet of servers.

To address this issue, a new sysfs interface called 'replace' is introduced
in this patch. The result after this change is as follows:

  $ cat /sys/kernel/livepatch/livepatch-non_replace/replace
  0

  $ cat /sys/kernel/livepatch/livepatch-replace/replace
  1

Signed-off-by: Yafang Shao <[email protected]>
---
 Documentation/ABI/testing/sysfs-kernel-livepatch |  8 ++++++++
 kernel/livepatch/core.c                          | 12 ++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-kernel-livepatch 
b/Documentation/ABI/testing/sysfs-kernel-livepatch
index a5df9b4910dc..3735d868013d 100644
--- a/Documentation/ABI/testing/sysfs-kernel-livepatch
+++ b/Documentation/ABI/testing/sysfs-kernel-livepatch
@@ -47,6 +47,14 @@ Description:
                disabled when the feature is used. See
                Documentation/livepatch/livepatch.rst for more information.
 
+What:          /sys/kernel/livepatch/<patch>/replace
+Date:          Jun 2024
+KernelVersion: 6.11.0
+Contact:       [email protected]
+Description:
+               An attribute which indicates whether the patch supports
+               atomic-replace.
+
 What:          /sys/kernel/livepatch/<patch>/<object>
 Date:          Nov 2014
 KernelVersion: 3.19.0
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 52426665eecc..0e9832f146f1 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -346,6 +346,7 @@ int klp_apply_section_relocs(struct module *pmod, Elf_Shdr 
*sechdrs,
  * /sys/kernel/livepatch/<patch>/enabled
  * /sys/kernel/livepatch/<patch>/transition
  * /sys/kernel/livepatch/<patch>/force
+ * /sys/kernel/livepatch/<patch>/replace
  * /sys/kernel/livepatch/<patch>/<object>
  * /sys/kernel/livepatch/<patch>/<object>/patched
  * /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
@@ -443,13 +444,24 @@ static ssize_t force_store(struct kobject *kobj, struct 
kobj_attribute *attr,
        return count;
 }
 
+static ssize_t replace_show(struct kobject *kobj,
+                           struct kobj_attribute *attr, char *buf)
+{
+       struct klp_patch *patch;
+
+       patch = container_of(kobj, struct klp_patch, kobj);
+       return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->replace);
+}
+
 static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled);
 static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition);
 static struct kobj_attribute force_kobj_attr = __ATTR_WO(force);
+static struct kobj_attribute replace_kobj_attr = __ATTR_RO(replace);
 static struct attribute *klp_patch_attrs[] = {
        &enabled_kobj_attr.attr,
        &transition_kobj_attr.attr,
        &force_kobj_attr.attr,
+       &replace_kobj_attr.attr,
        NULL
 };
 ATTRIBUTE_GROUPS(klp_patch);
-- 
2.39.1


Reply via email to