Commit 3dae09de authored by Wardenjohn's avatar Wardenjohn Committed by Petr Mladek
Browse files

livepatch: Add stack_order sysfs attribute



Add "stack_order" sysfs attribute which holds the order in which a live
patch module was loaded into the system. A user can then determine an
active live patched version of a function.

cat /sys/kernel/livepatch/livepatch_1/stack_order -> 1

means that livepatch_1 is the first live patch applied

cat /sys/kernel/livepatch/livepatch_module/stack_order -> N

means that livepatch_module is the Nth live patch applied

Suggested-by: default avatarPetr Mladek <pmladek@suse.com>
Suggested-by: default avatarMiroslav Benes <mbenes@suse.cz>
Suggested-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: default avatarWardenjohn <zhangwarden@gmail.com>
Acked-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Tested-by: default avatarPetr Mladek <pmladek@suse.com>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Link: https://lore.kernel.org/r/20241008014856.3729-2-zhangwarden@gmail.com


[pmladek@suse.com: Updated kernel version and date in the ABI documentation.]
Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
parent aa44f414
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -55,6 +55,15 @@ Description:
		An attribute which indicates whether the patch supports
		atomic-replace.

What:		/sys/kernel/livepatch/<patch>/stack_order
Date:		Jan 2025
KernelVersion:	6.14.0
Description:
		This attribute specifies the sequence in which live patch modules
		are applied to the system. If multiple live patches modify the same
		function, the implementation with the biggest 'stack_order' number
		is used, unless a transition is currently in progress.

What:		/sys/kernel/livepatch/<patch>/<object>
Date:		Nov 2014
KernelVersion:	3.19.0
+24 −0
Original line number Diff line number Diff line
@@ -347,6 +347,7 @@ int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
 * /sys/kernel/livepatch/<patch>/transition
 * /sys/kernel/livepatch/<patch>/force
 * /sys/kernel/livepatch/<patch>/replace
 * /sys/kernel/livepatch/<patch>/stack_order
 * /sys/kernel/livepatch/<patch>/<object>
 * /sys/kernel/livepatch/<patch>/<object>/patched
 * /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
@@ -452,15 +453,38 @@ static ssize_t replace_show(struct kobject *kobj,
	return sysfs_emit(buf, "%d\n", patch->replace);
}

static ssize_t stack_order_show(struct kobject *kobj,
				struct kobj_attribute *attr, char *buf)
{
	struct klp_patch *patch, *this_patch;
	int stack_order = 0;

	this_patch = container_of(kobj, struct klp_patch, kobj);

	mutex_lock(&klp_mutex);

	klp_for_each_patch(patch) {
		stack_order++;
		if (patch == this_patch)
			break;
	}

	mutex_unlock(&klp_mutex);

	return sysfs_emit(buf, "%d\n", stack_order);
}

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 kobj_attribute stack_order_kobj_attr = __ATTR_RO(stack_order);
static struct attribute *klp_patch_attrs[] = {
	&enabled_kobj_attr.attr,
	&transition_kobj_attr.attr,
	&force_kobj_attr.attr,
	&replace_kobj_attr.attr,
	&stack_order_kobj_attr.attr,
	NULL
};
ATTRIBUTE_GROUPS(klp_patch);