Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Miroslav Benes
On Fri, 23 Feb 2018, Joe Lawrence wrote:

> On 02/23/2018 05:41 AM, Miroslav Benes wrote:
> > On Wed, 21 Feb 2018, Petr Mladek wrote:
> > 
> >> User documentation for the atomic replace feature. It makes it easier
> >> to maintain livepatches using so-called cumulative patches.
> >>
> >> Signed-off-by: Petr Mladek 
> > 
> > Acked-by: Miroslav Benes 
> > 
> > Joe, are you planning to extend shadow vars documentation you mentioned 
> > before (v7), or do you want Petr to do it?
> 
> I created a sample cumulative patch for testing (I can post later),
> but I had a quick question regarding the callbacks...
> 
> >From v8 of the patch:
> 
>   + Only the (un)patching callbacks from the _new_ cumulative livepatch are
> executed. Any callbacks from the replaced patches are ignored.
> 
> maybe I'm not testing this as intended, but I'm not seeing this
> behavior with the latest version of the patch.  See below.

No, you found a bug, I think. I didn't test callbacks and missed this 
during the review. 
 
> Test 2
> ==
> 
> Make the second livepatch a cumulative one:
> 
> diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
> --- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
> 09:42:10.370223095 -0500
> +++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
> 11:16:20.557557153 -0500
> @@ -191,6 +191,7 @@ static struct klp_object objs[] = {
>  static struct klp_patch patch = {
> .mod = THIS_MODULE,
> .objs = objs,
> +   .replace = true,
>  };

The problem is that there are no new/patch functions defined for vmlinux 
and livepatch-callbacks-mod objects. There are only callbacks. Only 
livepatch-callbacks-busymod module has a replacement function. I'll focus 
on vmlinux only. 

No nop functions are added by klp_add_nops(). vmlinux object is empty. 
Then it is destroyed in 
klp_complete_transition()->klp_free_objects(klp_transition_patch, 
KLP_FUNC_NOP). In the end only livepatch-callbacks-busymod is preserved 
regardless the callbacks.

Had you load livepatch-callbacks-busymod module, its callback would be 
called.

Petr, we cannot free the "nop-only" objects if there is a callback defined 
there (an unpatch callback).
  
>  static int livepatch_callbacks_demo_init(void)
> 
> Load the two modules, disable and unload:
> 
>   % dmesg -C
>   % insmod samples/livepatch/livepatch-callbacks-demo.ko
>   % insmod samples/livepatch/livepatch-callbacks-demo2.ko
>   % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
>   % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
>   % rmmod samples/livepatch/livepatch-callbacks-demo.ko
> 
> Pre and post patch callbacks are called for both modules (expected), but
> *no* unpatch callbacks are executed:
> 
>   % dmesg
>   [ 5442.244332] livepatch: enabling patch 'livepatch_callbacks_demo'
>   [ 5442.244334] livepatch: 'livepatch_callbacks_demo': initializing patching 
> transition
> > [ 5442.244372] livepatch_callbacks_demo: pre_patch_callback: vmlinux
>   [ 5442.244372] livepatch: 'livepatch_callbacks_demo': starting patching 
> transition
>   [ 5444.704089] livepatch: 'livepatch_callbacks_demo': completing patching 
> transition
> > [ 5444.704183] livepatch_callbacks_demo: post_patch_callback: vmlinux
>   [ 5444.704184] livepatch: 'livepatch_callbacks_demo': patching complete
>   [ 5448.567820] livepatch: enabling patch 'livepatch_callbacks_demo2'
>   [ 5448.567823] livepatch: 'livepatch_callbacks_demo2': initializing 
> patching transition
> > [ 5448.567860] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
>   [ 5448.567861] livepatch: 'livepatch_callbacks_demo2': starting patching 
> transition
>   [ 5451.744131] livepatch: 'livepatch_callbacks_demo2': completing patching 
> transition
> > [ 5451.744212] livepatch_callbacks_demo2: post_patch_callback: vmlinux
>   [ 5451.744213] livepatch: 'livepatch_callbacks_demo2': patching complete
>   [ 5455.002339] livepatch: 'livepatch_callbacks_demo2': initializing 
> unpatching transition
>   [ 5455.002378] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
> transition
>   [ 5456.736068] livepatch: 'livepatch_callbacks_demo2': completing 
> unpatching transition
>   [ 5456.736132] livepatch: 'livepatch_callbacks_demo2': unpatching complete
> 
> 
> BTW, should we just add this test-case to the doc / samples?

Why not. I think we need to transform the samples into a testsuite or 
selftests, because their role has changed.

Thanks for the report. The atomic replace patch set has become a nightmare 
for me :). So many tiny corner cases everywhere and I'm not capable to 
hold every detail in my brain during the review.

Miroslav


Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Miroslav Benes
On Fri, 23 Feb 2018, Joe Lawrence wrote:

> On 02/23/2018 05:41 AM, Miroslav Benes wrote:
> > On Wed, 21 Feb 2018, Petr Mladek wrote:
> > 
> >> User documentation for the atomic replace feature. It makes it easier
> >> to maintain livepatches using so-called cumulative patches.
> >>
> >> Signed-off-by: Petr Mladek 
> > 
> > Acked-by: Miroslav Benes 
> > 
> > Joe, are you planning to extend shadow vars documentation you mentioned 
> > before (v7), or do you want Petr to do it?
> 
> I created a sample cumulative patch for testing (I can post later),
> but I had a quick question regarding the callbacks...
> 
> >From v8 of the patch:
> 
>   + Only the (un)patching callbacks from the _new_ cumulative livepatch are
> executed. Any callbacks from the replaced patches are ignored.
> 
> maybe I'm not testing this as intended, but I'm not seeing this
> behavior with the latest version of the patch.  See below.

No, you found a bug, I think. I didn't test callbacks and missed this 
during the review. 
 
> Test 2
> ==
> 
> Make the second livepatch a cumulative one:
> 
> diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
> --- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
> 09:42:10.370223095 -0500
> +++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
> 11:16:20.557557153 -0500
> @@ -191,6 +191,7 @@ static struct klp_object objs[] = {
>  static struct klp_patch patch = {
> .mod = THIS_MODULE,
> .objs = objs,
> +   .replace = true,
>  };

The problem is that there are no new/patch functions defined for vmlinux 
and livepatch-callbacks-mod objects. There are only callbacks. Only 
livepatch-callbacks-busymod module has a replacement function. I'll focus 
on vmlinux only. 

No nop functions are added by klp_add_nops(). vmlinux object is empty. 
Then it is destroyed in 
klp_complete_transition()->klp_free_objects(klp_transition_patch, 
KLP_FUNC_NOP). In the end only livepatch-callbacks-busymod is preserved 
regardless the callbacks.

Had you load livepatch-callbacks-busymod module, its callback would be 
called.

Petr, we cannot free the "nop-only" objects if there is a callback defined 
there (an unpatch callback).
  
>  static int livepatch_callbacks_demo_init(void)
> 
> Load the two modules, disable and unload:
> 
>   % dmesg -C
>   % insmod samples/livepatch/livepatch-callbacks-demo.ko
>   % insmod samples/livepatch/livepatch-callbacks-demo2.ko
>   % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
>   % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
>   % rmmod samples/livepatch/livepatch-callbacks-demo.ko
> 
> Pre and post patch callbacks are called for both modules (expected), but
> *no* unpatch callbacks are executed:
> 
>   % dmesg
>   [ 5442.244332] livepatch: enabling patch 'livepatch_callbacks_demo'
>   [ 5442.244334] livepatch: 'livepatch_callbacks_demo': initializing patching 
> transition
> > [ 5442.244372] livepatch_callbacks_demo: pre_patch_callback: vmlinux
>   [ 5442.244372] livepatch: 'livepatch_callbacks_demo': starting patching 
> transition
>   [ 5444.704089] livepatch: 'livepatch_callbacks_demo': completing patching 
> transition
> > [ 5444.704183] livepatch_callbacks_demo: post_patch_callback: vmlinux
>   [ 5444.704184] livepatch: 'livepatch_callbacks_demo': patching complete
>   [ 5448.567820] livepatch: enabling patch 'livepatch_callbacks_demo2'
>   [ 5448.567823] livepatch: 'livepatch_callbacks_demo2': initializing 
> patching transition
> > [ 5448.567860] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
>   [ 5448.567861] livepatch: 'livepatch_callbacks_demo2': starting patching 
> transition
>   [ 5451.744131] livepatch: 'livepatch_callbacks_demo2': completing patching 
> transition
> > [ 5451.744212] livepatch_callbacks_demo2: post_patch_callback: vmlinux
>   [ 5451.744213] livepatch: 'livepatch_callbacks_demo2': patching complete
>   [ 5455.002339] livepatch: 'livepatch_callbacks_demo2': initializing 
> unpatching transition
>   [ 5455.002378] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
> transition
>   [ 5456.736068] livepatch: 'livepatch_callbacks_demo2': completing 
> unpatching transition
>   [ 5456.736132] livepatch: 'livepatch_callbacks_demo2': unpatching complete
> 
> 
> BTW, should we just add this test-case to the doc / samples?

Why not. I think we need to transform the samples into a testsuite or 
selftests, because their role has changed.

Thanks for the report. The atomic replace patch set has become a nightmare 
for me :). So many tiny corner cases everywhere and I'm not capable to 
hold every detail in my brain during the review.

Miroslav


Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Joe Lawrence
On 02/23/2018 05:41 AM, Miroslav Benes wrote:
> On Wed, 21 Feb 2018, Petr Mladek wrote:
> 
>> User documentation for the atomic replace feature. It makes it easier
>> to maintain livepatches using so-called cumulative patches.
>>
>> Signed-off-by: Petr Mladek 
> 
> Acked-by: Miroslav Benes 
> 
> Joe, are you planning to extend shadow vars documentation you mentioned 
> before (v7), or do you want Petr to do it?

I created a sample cumulative patch for testing (I can post later),
but I had a quick question regarding the callbacks...

>From v8 of the patch:

  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
executed. Any callbacks from the replaced patches are ignored.

maybe I'm not testing this as intended, but I'm not seeing this
behavior with the latest version of the patch.  See below.


Init


Setup dynamic debug messages:

  % echo "file kernel/livepatch/* +p" > /sys/kernel/debug/dynamic_debug/control
  % echo "func klp_try_switch_task -p" >> 
/sys/kernel/debug/dynamic_debug/control


Test 1
==

Copy the original callbacks demo, leave the atomic .replace feature off:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:38:08.372557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = false,
 };
 
 static int livepatch_callbacks_demo_init(void)


Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo.ko

All callbacks are called for both livepatch modules (expected):

  % dmesg
  [ 5755.608999] livepatch: enabling patch 'livepatch_callbacks_demo'
  [ 5755.609014] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
> [ 5755.609054] livepatch_callbacks_demo: pre_patch_callback: vmlinux
  [ 5755.609055] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
  [ 5756.704163] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
> [ 5756.704259] livepatch_callbacks_demo: post_patch_callback: vmlinux
  [ 5756.704260] livepatch: 'livepatch_callbacks_demo': patching complete
  [ 5760.231035] livepatch: enabling patch 'livepatch_callbacks_demo2'
  [ 5760.231038] livepatch: 'livepatch_callbacks_demo2': initializing patching 
transition
> [ 5760.231077] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
  [ 5760.231078] livepatch: 'livepatch_callbacks_demo2': starting patching 
transition
  [ 5761.696067] livepatch: 'livepatch_callbacks_demo2': completing patching 
transition
> [ 5761.696166] livepatch_callbacks_demo2: post_patch_callback: vmlinux
  [ 5761.696166] livepatch: 'livepatch_callbacks_demo2': patching complete
  [ 5765.738278] livepatch: 'livepatch_callbacks_demo2': initializing 
unpatching transition
> [ 5765.738319] livepatch_callbacks_demo2: pre_unpatch_callback: vmlinux
  [ 5765.738319] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
  [ 5767.712143] livepatch: 'livepatch_callbacks_demo2': completing unpatching 
transition
> [ 5767.712502] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
  [ 5767.712503] livepatch: 'livepatch_callbacks_demo2': unpatching complete
  [ 5770.909701] livepatch: 'livepatch_callbacks_demo': initializing unpatching 
transition
> [ 5770.909743] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [ 5770.909743] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [ 5772.704108] livepatch: 'livepatch_callbacks_demo': completing unpatching 
transition
> [ 5772.704215] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [ 5772.704216] livepatch: 'livepatch_callbacks_demo': unpatching complete


Test 2
==

Make the second livepatch a cumulative one:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:16:20.557557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = true,
 };
 
 static int livepatch_callbacks_demo_init(void)

Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > 

Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Joe Lawrence
On 02/23/2018 05:41 AM, Miroslav Benes wrote:
> On Wed, 21 Feb 2018, Petr Mladek wrote:
> 
>> User documentation for the atomic replace feature. It makes it easier
>> to maintain livepatches using so-called cumulative patches.
>>
>> Signed-off-by: Petr Mladek 
> 
> Acked-by: Miroslav Benes 
> 
> Joe, are you planning to extend shadow vars documentation you mentioned 
> before (v7), or do you want Petr to do it?

I created a sample cumulative patch for testing (I can post later),
but I had a quick question regarding the callbacks...

>From v8 of the patch:

  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
executed. Any callbacks from the replaced patches are ignored.

maybe I'm not testing this as intended, but I'm not seeing this
behavior with the latest version of the patch.  See below.


Init


Setup dynamic debug messages:

  % echo "file kernel/livepatch/* +p" > /sys/kernel/debug/dynamic_debug/control
  % echo "func klp_try_switch_task -p" >> 
/sys/kernel/debug/dynamic_debug/control


Test 1
==

Copy the original callbacks demo, leave the atomic .replace feature off:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:38:08.372557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = false,
 };
 
 static int livepatch_callbacks_demo_init(void)


Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo.ko

All callbacks are called for both livepatch modules (expected):

  % dmesg
  [ 5755.608999] livepatch: enabling patch 'livepatch_callbacks_demo'
  [ 5755.609014] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
> [ 5755.609054] livepatch_callbacks_demo: pre_patch_callback: vmlinux
  [ 5755.609055] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
  [ 5756.704163] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
> [ 5756.704259] livepatch_callbacks_demo: post_patch_callback: vmlinux
  [ 5756.704260] livepatch: 'livepatch_callbacks_demo': patching complete
  [ 5760.231035] livepatch: enabling patch 'livepatch_callbacks_demo2'
  [ 5760.231038] livepatch: 'livepatch_callbacks_demo2': initializing patching 
transition
> [ 5760.231077] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
  [ 5760.231078] livepatch: 'livepatch_callbacks_demo2': starting patching 
transition
  [ 5761.696067] livepatch: 'livepatch_callbacks_demo2': completing patching 
transition
> [ 5761.696166] livepatch_callbacks_demo2: post_patch_callback: vmlinux
  [ 5761.696166] livepatch: 'livepatch_callbacks_demo2': patching complete
  [ 5765.738278] livepatch: 'livepatch_callbacks_demo2': initializing 
unpatching transition
> [ 5765.738319] livepatch_callbacks_demo2: pre_unpatch_callback: vmlinux
  [ 5765.738319] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
  [ 5767.712143] livepatch: 'livepatch_callbacks_demo2': completing unpatching 
transition
> [ 5767.712502] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
  [ 5767.712503] livepatch: 'livepatch_callbacks_demo2': unpatching complete
  [ 5770.909701] livepatch: 'livepatch_callbacks_demo': initializing unpatching 
transition
> [ 5770.909743] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [ 5770.909743] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [ 5772.704108] livepatch: 'livepatch_callbacks_demo': completing unpatching 
transition
> [ 5772.704215] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [ 5772.704216] livepatch: 'livepatch_callbacks_demo': unpatching complete


Test 2
==

Make the second livepatch a cumulative one:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:16:20.557557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = true,
 };
 
 static int livepatch_callbacks_demo_init(void)

Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  % rmmod 

Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Miroslav Benes
On Wed, 21 Feb 2018, Petr Mladek wrote:

> User documentation for the atomic replace feature. It makes it easier
> to maintain livepatches using so-called cumulative patches.
> 
> Signed-off-by: Petr Mladek 

Acked-by: Miroslav Benes 

Joe, are you planning to extend shadow vars documentation you mentioned 
before (v7), or do you want Petr to do it?

Thanks,
Miroslav


Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Miroslav Benes
On Wed, 21 Feb 2018, Petr Mladek wrote:

> User documentation for the atomic replace feature. It makes it easier
> to maintain livepatches using so-called cumulative patches.
> 
> Signed-off-by: Petr Mladek 

Acked-by: Miroslav Benes 

Joe, are you planning to extend shadow vars documentation you mentioned 
before (v7), or do you want Petr to do it?

Thanks,
Miroslav


[PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-21 Thread Petr Mladek
User documentation for the atomic replace feature. It makes it easier
to maintain livepatches using so-called cumulative patches.

Signed-off-by: Petr Mladek 
---
 Documentation/livepatch/cumulative-patches.txt | 83 ++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/livepatch/cumulative-patches.txt

diff --git a/Documentation/livepatch/cumulative-patches.txt 
b/Documentation/livepatch/cumulative-patches.txt
new file mode 100644
index ..c041fc1bd259
--- /dev/null
+++ b/Documentation/livepatch/cumulative-patches.txt
@@ -0,0 +1,83 @@
+===
+Atomic Replace & Cumulative Patches
+===
+
+There might be dependencies between livepatches. If multiple patches need
+to do different changes to the same function(s) then we need to define
+an order in which the patches will be installed. And function implementations
+from any newer livepatch must be done on top of the older ones.
+
+This might become a maintenance nightmare. Especially if anyone would want
+to remove a patch that is in the middle of the stack.
+
+An elegant solution comes with the feature called "Atomic Replace". It allows
+to create so called "Cumulative Patches". They include all wanted changes
+from all older livepatches and completely replace them in one transition.
+
+Usage
+-
+
+The atomic replace can be enabled by setting "replace" flag in struct 
klp_patch,
+for example:
+
+   static struct klp_patch patch = {
+   .mod = THIS_MODULE,
+   .objs = objs,
+   .replace = true,
+   };
+
+Such a patch is added on top of the livepatch stack when registered. It can
+be enabled even when some earlier patches have not been enabled yet.
+
+All processes are then migrated to use the code only from the new patch.
+Once the transition is finished, all older patches are removed from the stack
+of patches. Even the older not-enabled patches mentioned above.
+
+Ftrace handlers are transparently removed from functions that are no
+longer modified by the new cumulative patch.
+
+As a result, the livepatch author might maintain sources only for one
+cumulative patch. It helps to keep the patch consistent while adding or
+removing various fixes or features.
+
+
+Limitations:
+
+
+  + Replaced patches can no longer be enabled. But if the transition
+to the cumulative patch was not forced, the kernel modules with
+the older livepatches can be removed and eventually added again.
+
+A good practice is to set .replace flag in any released livepatch.
+Then re-adding an older livepatch is equivalent to downgrading
+to that patch. This is safe as long as the livepatches do _not_ do
+extra modifications in (un)patching callbacks or in the module_init()
+or module_exit() functions, see below.
+
+
+  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
+executed. Any callbacks from the replaced patches are ignored.
+
+By other words, the cumulative patch is responsible for doing any actions
+that are necessary to properly replace any older patch.
+
+As a result, it might be dangerous to replace newer cumulative patches by
+older ones. The old livepatches might not provide the necessary callbacks.
+
+This might be seen as a limitation in some scenarios. But it makes the life
+easier in many others. Only the new cumulative livepatch knows what
+fixes/features are added/removed and what special actions are necessary
+for a smooth transition.
+
+In each case, it would be a nightmare to think about the order of
+the various callbacks and their interactions if the callbacks from all
+enabled patches were called.
+
+
+  + There is no special handling of shadow variables. Livepatch authors
+must create their own rules how to pass them from one cumulative
+patch to the other. Especially they should not blindly remove them
+in module_exit() functions.
+
+A good practice might be to remove shadow variables in the post-unpatch
+callback. It is called only when the livepatch is properly disabled.
-- 
2.13.6



[PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-21 Thread Petr Mladek
User documentation for the atomic replace feature. It makes it easier
to maintain livepatches using so-called cumulative patches.

Signed-off-by: Petr Mladek 
---
 Documentation/livepatch/cumulative-patches.txt | 83 ++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/livepatch/cumulative-patches.txt

diff --git a/Documentation/livepatch/cumulative-patches.txt 
b/Documentation/livepatch/cumulative-patches.txt
new file mode 100644
index ..c041fc1bd259
--- /dev/null
+++ b/Documentation/livepatch/cumulative-patches.txt
@@ -0,0 +1,83 @@
+===
+Atomic Replace & Cumulative Patches
+===
+
+There might be dependencies between livepatches. If multiple patches need
+to do different changes to the same function(s) then we need to define
+an order in which the patches will be installed. And function implementations
+from any newer livepatch must be done on top of the older ones.
+
+This might become a maintenance nightmare. Especially if anyone would want
+to remove a patch that is in the middle of the stack.
+
+An elegant solution comes with the feature called "Atomic Replace". It allows
+to create so called "Cumulative Patches". They include all wanted changes
+from all older livepatches and completely replace them in one transition.
+
+Usage
+-
+
+The atomic replace can be enabled by setting "replace" flag in struct 
klp_patch,
+for example:
+
+   static struct klp_patch patch = {
+   .mod = THIS_MODULE,
+   .objs = objs,
+   .replace = true,
+   };
+
+Such a patch is added on top of the livepatch stack when registered. It can
+be enabled even when some earlier patches have not been enabled yet.
+
+All processes are then migrated to use the code only from the new patch.
+Once the transition is finished, all older patches are removed from the stack
+of patches. Even the older not-enabled patches mentioned above.
+
+Ftrace handlers are transparently removed from functions that are no
+longer modified by the new cumulative patch.
+
+As a result, the livepatch author might maintain sources only for one
+cumulative patch. It helps to keep the patch consistent while adding or
+removing various fixes or features.
+
+
+Limitations:
+
+
+  + Replaced patches can no longer be enabled. But if the transition
+to the cumulative patch was not forced, the kernel modules with
+the older livepatches can be removed and eventually added again.
+
+A good practice is to set .replace flag in any released livepatch.
+Then re-adding an older livepatch is equivalent to downgrading
+to that patch. This is safe as long as the livepatches do _not_ do
+extra modifications in (un)patching callbacks or in the module_init()
+or module_exit() functions, see below.
+
+
+  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
+executed. Any callbacks from the replaced patches are ignored.
+
+By other words, the cumulative patch is responsible for doing any actions
+that are necessary to properly replace any older patch.
+
+As a result, it might be dangerous to replace newer cumulative patches by
+older ones. The old livepatches might not provide the necessary callbacks.
+
+This might be seen as a limitation in some scenarios. But it makes the life
+easier in many others. Only the new cumulative livepatch knows what
+fixes/features are added/removed and what special actions are necessary
+for a smooth transition.
+
+In each case, it would be a nightmare to think about the order of
+the various callbacks and their interactions if the callbacks from all
+enabled patches were called.
+
+
+  + There is no special handling of shadow variables. Livepatch authors
+must create their own rules how to pass them from one cumulative
+patch to the other. Especially they should not blindly remove them
+in module_exit() functions.
+
+A good practice might be to remove shadow variables in the post-unpatch
+callback. It is called only when the livepatch is properly disabled.
-- 
2.13.6