Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching

Pull livepatching updates from Jiri Kosina:

 - support for something we call 'atomic replace', and allows for much
   better handling of cumulative patches (which is something very useful
   for distros), from Jason Baron with help of Petr Mladek and Joe
   Lawrence

 - improvement of handling of tasks blocking finalization, from Miroslav
   Benes

 - update of MAINTAINERS file to reflect move towards group
   maintainership

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: (22 commits)
  livepatch/selftests: use "$@" to preserve argument list
  livepatch: Module coming and going callbacks can proceed with all listed patches
  livepatch: Proper error handling in the shadow variables selftest
  livepatch: return -ENOMEM on ptr_id() allocation failure
  livepatch: Introduce klp_for_each_patch macro
  livepatch: core: Return EOPNOTSUPP instead of ENOSYS
  selftests/livepatch: add DYNAMIC_DEBUG config dependency
  livepatch: samples: non static warnings fix
  livepatch: update MAINTAINERS
  livepatch: Remove signal sysfs attribute
  livepatch: Send a fake signal periodically
  selftests/livepatch: introduce tests
  livepatch: Remove ordering (stacking) of the livepatches
  livepatch: Atomic replace and cumulative patches documentation
  livepatch: Remove Nop structures when unused
  livepatch: Add atomic replace
  livepatch: Use lists to manage patches, objects and functions
  livepatch: Simplify API by removing registration step
  livepatch: Don't block the removal of patches loaded after a forced transition
  livepatch: Consolidate klp_free functions
  ...
This commit is contained in:
Linus Torvalds
2019-03-08 08:58:25 -08:00
35 changed files with 2856 additions and 1278 deletions

View File

@@ -195,22 +195,11 @@ static struct klp_patch patch = {
static int livepatch_callbacks_demo_init(void)
{
int ret;
ret = klp_register_patch(&patch);
if (ret)
return ret;
ret = klp_enable_patch(&patch);
if (ret) {
WARN_ON(klp_unregister_patch(&patch));
return ret;
}
return 0;
return klp_enable_patch(&patch);
}
static void livepatch_callbacks_demo_exit(void)
{
WARN_ON(klp_unregister_patch(&patch));
}
module_init(livepatch_callbacks_demo_init);

View File

@@ -69,22 +69,11 @@ static struct klp_patch patch = {
static int livepatch_init(void)
{
int ret;
ret = klp_register_patch(&patch);
if (ret)
return ret;
ret = klp_enable_patch(&patch);
if (ret) {
WARN_ON(klp_unregister_patch(&patch));
return ret;
}
return 0;
return klp_enable_patch(&patch);
}
static void livepatch_exit(void)
{
WARN_ON(klp_unregister_patch(&patch));
}
module_init(livepatch_init);

View File

@@ -71,7 +71,7 @@ static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
return 0;
}
struct dummy *livepatch_fix1_dummy_alloc(void)
static struct dummy *livepatch_fix1_dummy_alloc(void)
{
struct dummy *d;
void *leak;
@@ -113,7 +113,7 @@ static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
__func__, d, *shadow_leak);
}
void livepatch_fix1_dummy_free(struct dummy *d)
static void livepatch_fix1_dummy_free(struct dummy *d)
{
void **shadow_leak;
@@ -157,25 +157,13 @@ static struct klp_patch patch = {
static int livepatch_shadow_fix1_init(void)
{
int ret;
ret = klp_register_patch(&patch);
if (ret)
return ret;
ret = klp_enable_patch(&patch);
if (ret) {
WARN_ON(klp_unregister_patch(&patch));
return ret;
}
return 0;
return klp_enable_patch(&patch);
}
static void livepatch_shadow_fix1_exit(void)
{
/* Cleanup any existing SV_LEAK shadow variables */
klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
WARN_ON(klp_unregister_patch(&patch));
}
module_init(livepatch_shadow_fix1_init);

View File

@@ -50,7 +50,7 @@ struct dummy {
unsigned long jiffies_expire;
};
bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
static bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
{
int *shadow_count;
@@ -78,7 +78,7 @@ static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
__func__, d, *shadow_leak);
}
void livepatch_fix2_dummy_free(struct dummy *d)
static void livepatch_fix2_dummy_free(struct dummy *d)
{
void **shadow_leak;
int *shadow_count;
@@ -129,25 +129,13 @@ static struct klp_patch patch = {
static int livepatch_shadow_fix2_init(void)
{
int ret;
ret = klp_register_patch(&patch);
if (ret)
return ret;
ret = klp_enable_patch(&patch);
if (ret) {
WARN_ON(klp_unregister_patch(&patch));
return ret;
}
return 0;
return klp_enable_patch(&patch);
}
static void livepatch_shadow_fix2_exit(void)
{
/* Cleanup any existing SV_COUNTER shadow variables */
klp_shadow_free_all(SV_COUNTER, NULL);
WARN_ON(klp_unregister_patch(&patch));
}
module_init(livepatch_shadow_fix2_init);

View File

@@ -96,15 +96,15 @@ MODULE_DESCRIPTION("Buggy module for shadow variable demo");
* Keep a list of all the dummies so we can clean up any residual ones
* on module exit
*/
LIST_HEAD(dummy_list);
DEFINE_MUTEX(dummy_list_mutex);
static LIST_HEAD(dummy_list);
static DEFINE_MUTEX(dummy_list_mutex);
struct dummy {
struct list_head list;
unsigned long jiffies_expire;
};
noinline struct dummy *dummy_alloc(void)
static __used noinline struct dummy *dummy_alloc(void)
{
struct dummy *d;
void *leak;
@@ -129,7 +129,7 @@ noinline struct dummy *dummy_alloc(void)
return d;
}
noinline void dummy_free(struct dummy *d)
static __used noinline void dummy_free(struct dummy *d)
{
pr_info("%s: dummy @ %p, expired = %lx\n",
__func__, d, d->jiffies_expire);
@@ -137,7 +137,8 @@ noinline void dummy_free(struct dummy *d)
kfree(d);
}
noinline bool dummy_check(struct dummy *d, unsigned long jiffies)
static __used noinline bool dummy_check(struct dummy *d,
unsigned long jiffies)
{
return time_after(jiffies, d->jiffies_expire);
}