1*4882a593Smuzhiyun=================================== 2*4882a593SmuzhiyunAtomic Replace & Cumulative Patches 3*4882a593Smuzhiyun=================================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThere might be dependencies between livepatches. If multiple patches need 6*4882a593Smuzhiyunto do different changes to the same function(s) then we need to define 7*4882a593Smuzhiyunan order in which the patches will be installed. And function implementations 8*4882a593Smuzhiyunfrom any newer livepatch must be done on top of the older ones. 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunThis might become a maintenance nightmare. Especially when more patches 11*4882a593Smuzhiyunmodified the same function in different ways. 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunAn elegant solution comes with the feature called "Atomic Replace". It allows 14*4882a593Smuzhiyuncreation of so called "Cumulative Patches". They include all wanted changes 15*4882a593Smuzhiyunfrom all older livepatches and completely replace them in one transition. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunUsage 18*4882a593Smuzhiyun----- 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunThe atomic replace can be enabled by setting "replace" flag in struct klp_patch, 21*4882a593Smuzhiyunfor example:: 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun static struct klp_patch patch = { 24*4882a593Smuzhiyun .mod = THIS_MODULE, 25*4882a593Smuzhiyun .objs = objs, 26*4882a593Smuzhiyun .replace = true, 27*4882a593Smuzhiyun }; 28*4882a593Smuzhiyun 29*4882a593SmuzhiyunAll processes are then migrated to use the code only from the new patch. 30*4882a593SmuzhiyunOnce the transition is finished, all older patches are automatically 31*4882a593Smuzhiyundisabled. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunFtrace handlers are transparently removed from functions that are no 34*4882a593Smuzhiyunlonger modified by the new cumulative patch. 35*4882a593Smuzhiyun 36*4882a593SmuzhiyunAs a result, the livepatch authors might maintain sources only for one 37*4882a593Smuzhiyuncumulative patch. It helps to keep the patch consistent while adding or 38*4882a593Smuzhiyunremoving various fixes or features. 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunUsers could keep only the last patch installed on the system after 41*4882a593Smuzhiyunthe transition to has finished. It helps to clearly see what code is 42*4882a593Smuzhiyunactually in use. Also the livepatch might then be seen as a "normal" 43*4882a593Smuzhiyunmodule that modifies the kernel behavior. The only difference is that 44*4882a593Smuzhiyunit can be updated at runtime without breaking its functionality. 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunFeatures 48*4882a593Smuzhiyun-------- 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunThe atomic replace allows: 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun - Atomically revert some functions in a previous patch while 53*4882a593Smuzhiyun upgrading other functions. 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun - Remove eventual performance impact caused by core redirection 56*4882a593Smuzhiyun for functions that are no longer patched. 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun - Decrease user confusion about dependencies between livepatches. 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunLimitations: 62*4882a593Smuzhiyun------------ 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun - Once the operation finishes, there is no straightforward way 65*4882a593Smuzhiyun to reverse it and restore the replaced patches atomically. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun A good practice is to set .replace flag in any released livepatch. 68*4882a593Smuzhiyun Then re-adding an older livepatch is equivalent to downgrading 69*4882a593Smuzhiyun to that patch. This is safe as long as the livepatches do _not_ do 70*4882a593Smuzhiyun extra modifications in (un)patching callbacks or in the module_init() 71*4882a593Smuzhiyun or module_exit() functions, see below. 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun Also note that the replaced patch can be removed and loaded again 74*4882a593Smuzhiyun only when the transition was not forced. 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun - Only the (un)patching callbacks from the _new_ cumulative livepatch are 78*4882a593Smuzhiyun executed. Any callbacks from the replaced patches are ignored. 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun In other words, the cumulative patch is responsible for doing any actions 81*4882a593Smuzhiyun that are necessary to properly replace any older patch. 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun As a result, it might be dangerous to replace newer cumulative patches by 84*4882a593Smuzhiyun older ones. The old livepatches might not provide the necessary callbacks. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun This might be seen as a limitation in some scenarios. But it makes life 87*4882a593Smuzhiyun easier in many others. Only the new cumulative livepatch knows what 88*4882a593Smuzhiyun fixes/features are added/removed and what special actions are necessary 89*4882a593Smuzhiyun for a smooth transition. 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun In any case, it would be a nightmare to think about the order of 92*4882a593Smuzhiyun the various callbacks and their interactions if the callbacks from all 93*4882a593Smuzhiyun enabled patches were called. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun - There is no special handling of shadow variables. Livepatch authors 97*4882a593Smuzhiyun must create their own rules how to pass them from one cumulative 98*4882a593Smuzhiyun patch to the other. Especially that they should not blindly remove 99*4882a593Smuzhiyun them in module_exit() functions. 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun A good practice might be to remove shadow variables in the post-unpatch 102*4882a593Smuzhiyun callback. It is called only when the livepatch is properly disabled. 103