Skip to content

Commit 77dbd72

Browse files
committed
Merge tag 'livepatching-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching
Pull livepatching updates from Petr Mladek: - Correctly handle kobjects when a livepatch init fails - Avoid CPU hogging when searching for many livepatched symbols - Add livepatch API page into documentation * tag 'livepatching-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: livepatch: Avoid CPU hogging with cond_resched livepatch: Fix missing unlock on error in klp_enable_patch() livepatch: Fix kobject refcount bug on klp_init_patch_early failure path Documentation: livepatch: Add livepatch API page
2 parents d0a231f + b2dfc3f commit 77dbd72

File tree

8 files changed

+54
-23
lines changed

8 files changed

+54
-23
lines changed

Documentation/livepatch/api.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
=================
4+
Livepatching APIs
5+
=================
6+
7+
Livepatch Enablement
8+
====================
9+
10+
.. kernel-doc:: kernel/livepatch/core.c
11+
:export:
12+
13+
14+
Shadow Variables
15+
================
16+
17+
.. kernel-doc:: kernel/livepatch/shadow.c
18+
:export:
19+
20+
System State Changes
21+
====================
22+
23+
.. kernel-doc:: kernel/livepatch/state.c
24+
:export:
25+
26+
Object Types
27+
============
28+
29+
.. kernel-doc:: include/linux/livepatch.h
30+
:identifiers: klp_patch klp_object klp_func klp_callbacks klp_state

Documentation/livepatch/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Kernel Livepatching
1414
shadow-vars
1515
system-state
1616
reliable-stacktrace
17+
api
1718

1819
.. only:: subproject and html
1920

Documentation/livepatch/shadow-vars.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ to do actions that can be done only once when a new variable is allocated.
8282
- call destructor function if defined
8383
- free shadow variable
8484

85-
* klp_shadow_free_all() - detach and free all <*, id> shadow variables
86-
- find and remove any <*, id> references from global hashtable
85+
* klp_shadow_free_all() - detach and free all <_, id> shadow variables
86+
- find and remove any <_, id> references from global hashtable
8787

8888
- if found
8989

Documentation/livepatch/system-state.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ struct klp_state:
5252

5353
The state can be manipulated using two functions:
5454

55-
- *klp_get_state(patch, id)*
55+
- klp_get_state()
5656

5757
- Get struct klp_state associated with the given livepatch
5858
and state id.
5959

60-
- *klp_get_prev_state(id)*
60+
- klp_get_prev_state()
6161

6262
- Get struct klp_state associated with the given feature id and
6363
already installed livepatches.

kernel/kallsyms.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
243243
ret = fn(data, namebuf, NULL, kallsyms_sym_address(i));
244244
if (ret != 0)
245245
return ret;
246+
cond_resched();
246247
}
247248
return 0;
248249
}

kernel/livepatch/core.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -862,14 +862,11 @@ static void klp_init_object_early(struct klp_patch *patch,
862862
list_add_tail(&obj->node, &patch->obj_list);
863863
}
864864

865-
static int klp_init_patch_early(struct klp_patch *patch)
865+
static void klp_init_patch_early(struct klp_patch *patch)
866866
{
867867
struct klp_object *obj;
868868
struct klp_func *func;
869869

870-
if (!patch->objs)
871-
return -EINVAL;
872-
873870
INIT_LIST_HEAD(&patch->list);
874871
INIT_LIST_HEAD(&patch->obj_list);
875872
kobject_init(&patch->kobj, &klp_ktype_patch);
@@ -879,20 +876,12 @@ static int klp_init_patch_early(struct klp_patch *patch)
879876
init_completion(&patch->finish);
880877

881878
klp_for_each_object_static(patch, obj) {
882-
if (!obj->funcs)
883-
return -EINVAL;
884-
885879
klp_init_object_early(patch, obj);
886880

887881
klp_for_each_func_static(obj, func) {
888882
klp_init_func_early(obj, func);
889883
}
890884
}
891-
892-
if (!try_module_get(patch->mod))
893-
return -ENODEV;
894-
895-
return 0;
896885
}
897886

898887
static int klp_init_patch(struct klp_patch *patch)
@@ -1024,10 +1013,17 @@ static int __klp_enable_patch(struct klp_patch *patch)
10241013
int klp_enable_patch(struct klp_patch *patch)
10251014
{
10261015
int ret;
1016+
struct klp_object *obj;
10271017

1028-
if (!patch || !patch->mod)
1018+
if (!patch || !patch->mod || !patch->objs)
10291019
return -EINVAL;
10301020

1021+
klp_for_each_object_static(patch, obj) {
1022+
if (!obj->funcs)
1023+
return -EINVAL;
1024+
}
1025+
1026+
10311027
if (!is_livepatch_module(patch->mod)) {
10321028
pr_err("module %s is not marked as a livepatch module\n",
10331029
patch->mod->name);
@@ -1051,12 +1047,13 @@ int klp_enable_patch(struct klp_patch *patch)
10511047
return -EINVAL;
10521048
}
10531049

1054-
ret = klp_init_patch_early(patch);
1055-
if (ret) {
1050+
if (!try_module_get(patch->mod)) {
10561051
mutex_unlock(&klp_mutex);
1057-
return ret;
1052+
return -ENODEV;
10581053
}
10591054

1055+
klp_init_patch_early(patch);
1056+
10601057
ret = klp_init_patch(patch);
10611058
if (ret)
10621059
goto err;

kernel/livepatch/shadow.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,12 @@ void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
272272
EXPORT_SYMBOL_GPL(klp_shadow_free);
273273

274274
/**
275-
* klp_shadow_free_all() - detach and free all <*, id> shadow variables
275+
* klp_shadow_free_all() - detach and free all <_, id> shadow variables
276276
* @id: data identifier
277277
* @dtor: custom callback that can be used to unregister the variable
278278
* and/or free data that the shadow variable points to (optional)
279279
*
280-
* This function releases the memory for all <*, id> shadow variable
280+
* This function releases the memory for all <_, id> shadow variable
281281
* instances, callers should stop referencing them accordingly.
282282
*/
283283
void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
@@ -288,7 +288,7 @@ void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
288288

289289
spin_lock_irqsave(&klp_shadow_lock, flags);
290290

291-
/* Delete all <*, id> from hash */
291+
/* Delete all <_, id> from hash */
292292
hash_for_each(klp_shadow_hash, i, shadow, node) {
293293
if (klp_shadow_match(shadow, shadow->obj, id))
294294
klp_shadow_free_struct(shadow, dtor);

kernel/module.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4499,6 +4499,8 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
44994499
mod, kallsyms_symbol_value(sym));
45004500
if (ret != 0)
45014501
goto out;
4502+
4503+
cond_resched();
45024504
}
45034505
}
45044506
out:

0 commit comments

Comments
 (0)