| =================================== | 
 | 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 when more patches | 
 | modified the same function in different ways. | 
 |  | 
 | An elegant solution comes with the feature called "Atomic Replace". It allows | 
 | creation of 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, | 
 | 	}; | 
 |  | 
 | All processes are then migrated to use the code only from the new patch. | 
 | Once the transition is finished, all older patches are automatically | 
 | disabled. | 
 |  | 
 | Ftrace handlers are transparently removed from functions that are no | 
 | longer modified by the new cumulative patch. | 
 |  | 
 | As a result, the livepatch authors might maintain sources only for one | 
 | cumulative patch. It helps to keep the patch consistent while adding or | 
 | removing various fixes or features. | 
 |  | 
 | Users could keep only the last patch installed on the system after | 
 | the transition to has finished. It helps to clearly see what code is | 
 | actually in use. Also the livepatch might then be seen as a "normal" | 
 | module that modifies the kernel behavior. The only difference is that | 
 | it can be updated at runtime without breaking its functionality. | 
 |  | 
 |  | 
 | Features | 
 | -------- | 
 |  | 
 | The atomic replace allows: | 
 |  | 
 |   - Atomically revert some functions in a previous patch while | 
 |     upgrading other functions. | 
 |  | 
 |   - Remove eventual performance impact caused by core redirection | 
 |     for functions that are no longer patched. | 
 |  | 
 |   - Decrease user confusion about dependencies between livepatches. | 
 |  | 
 |  | 
 | Limitations: | 
 | ------------ | 
 |  | 
 |   - Once the operation finishes, there is no straightforward way | 
 |     to reverse it and restore the replaced patches atomically. | 
 |  | 
 |     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. | 
 |  | 
 |     Also note that the replaced patch can be removed and loaded again | 
 |     only when the transition was not forced. | 
 |  | 
 |  | 
 |   - Only the (un)patching callbacks from the _new_ cumulative livepatch are | 
 |     executed. Any callbacks from the replaced patches are ignored. | 
 |  | 
 |     In 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 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 any 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 that 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. |