162306a36Sopenharmony_ci==================== 262306a36Sopenharmony_ciSystem State Changes 362306a36Sopenharmony_ci==================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciSome users are really reluctant to reboot a system. This brings the need 662306a36Sopenharmony_cito provide more livepatches and maintain some compatibility between them. 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciMaintaining more livepatches is much easier with cumulative livepatches. 962306a36Sopenharmony_ciEach new livepatch completely replaces any older one. It can keep, 1062306a36Sopenharmony_ciadd, and even remove fixes. And it is typically safe to replace any version 1162306a36Sopenharmony_ciof the livepatch with any other one thanks to the atomic replace feature. 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ciThe problems might come with shadow variables and callbacks. They might 1462306a36Sopenharmony_cichange the system behavior or state so that it is no longer safe to 1562306a36Sopenharmony_cigo back and use an older livepatch or the original kernel code. Also 1662306a36Sopenharmony_ciany new livepatch must be able to detect what changes have already been 1762306a36Sopenharmony_cidone by the already installed livepatches. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciThis is where the livepatch system state tracking gets useful. It 2062306a36Sopenharmony_ciallows to: 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci - store data needed to manipulate and restore the system state 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci - define compatibility between livepatches using a change id 2562306a36Sopenharmony_ci and version 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci1. Livepatch system state API 2962306a36Sopenharmony_ci============================= 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciThe state of the system might get modified either by several livepatch callbacks 3262306a36Sopenharmony_cior by the newly used code. Also it must be possible to find changes done by 3362306a36Sopenharmony_cialready installed livepatches. 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciEach modified state is described by struct klp_state, see 3662306a36Sopenharmony_ciinclude/linux/livepatch.h. 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ciEach livepatch defines an array of struct klp_states. They mention 3962306a36Sopenharmony_ciall states that the livepatch modifies. 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciThe livepatch author must define the following two fields for each 4262306a36Sopenharmony_cistruct klp_state: 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci - *id* 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci - Non-zero number used to identify the affected system state. 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci - *version* 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci - Number describing the variant of the system state change that 5162306a36Sopenharmony_ci is supported by the given livepatch. 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ciThe state can be manipulated using two functions: 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci - klp_get_state() 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci - Get struct klp_state associated with the given livepatch 5862306a36Sopenharmony_ci and state id. 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci - klp_get_prev_state() 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci - Get struct klp_state associated with the given feature id and 6362306a36Sopenharmony_ci already installed livepatches. 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci2. Livepatch compatibility 6662306a36Sopenharmony_ci========================== 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciThe system state version is used to prevent loading incompatible livepatches. 6962306a36Sopenharmony_ciThe check is done when the livepatch is enabled. The rules are: 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci - Any completely new system state modification is allowed. 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci - System state modifications with the same or higher version are allowed 7462306a36Sopenharmony_ci for already modified system states. 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci - Cumulative livepatches must handle all system state modifications from 7762306a36Sopenharmony_ci already installed livepatches. 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci - Non-cumulative livepatches are allowed to touch already modified 8062306a36Sopenharmony_ci system states. 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci3. Supported scenarios 8362306a36Sopenharmony_ci====================== 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciLivepatches have their life-cycle and the same is true for the system 8662306a36Sopenharmony_cistate changes. Every compatible livepatch has to support the following 8762306a36Sopenharmony_ciscenarios: 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci - Modify the system state when the livepatch gets enabled and the state 9062306a36Sopenharmony_ci has not been already modified by a livepatches that are being 9162306a36Sopenharmony_ci replaced. 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci - Take over or update the system state modification when is has already 9462306a36Sopenharmony_ci been done by a livepatch that is being replaced. 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci - Restore the original state when the livepatch is disabled. 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci - Restore the previous state when the transition is reverted. 9962306a36Sopenharmony_ci It might be the original system state or the state modification 10062306a36Sopenharmony_ci done by livepatches that were being replaced. 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci - Remove any already made changes when error occurs and the livepatch 10362306a36Sopenharmony_ci cannot get enabled. 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci4. Expected usage 10662306a36Sopenharmony_ci================= 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ciSystem states are usually modified by livepatch callbacks. The expected 10962306a36Sopenharmony_cirole of each callback is as follows: 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci*pre_patch()* 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci - Allocate *state->data* when necessary. The allocation might fail 11462306a36Sopenharmony_ci and *pre_patch()* is the only callback that could stop loading 11562306a36Sopenharmony_ci of the livepatch. The allocation is not needed when the data 11662306a36Sopenharmony_ci are already provided by previously installed livepatches. 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci - Do any other preparatory action that is needed by 11962306a36Sopenharmony_ci the new code even before the transition gets finished. 12062306a36Sopenharmony_ci For example, initialize *state->data*. 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci The system state itself is typically modified in *post_patch()* 12362306a36Sopenharmony_ci when the entire system is able to handle it. 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci - Clean up its own mess in case of error. It might be done by a custom 12662306a36Sopenharmony_ci code or by calling *post_unpatch()* explicitly. 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci*post_patch()* 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci - Copy *state->data* from the previous livepatch when they are 13162306a36Sopenharmony_ci compatible. 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci - Do the actual system state modification. Eventually allow 13462306a36Sopenharmony_ci the new code to use it. 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci - Make sure that *state->data* has all necessary information. 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci - Free *state->data* from replaces livepatches when they are 13962306a36Sopenharmony_ci not longer needed. 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci*pre_unpatch()* 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci - Prevent the code, added by the livepatch, relying on the system 14462306a36Sopenharmony_ci state change. 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci - Revert the system state modification.. 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci*post_unpatch()* 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci - Distinguish transition reverse and livepatch disabling by 15162306a36Sopenharmony_ci checking *klp_get_prev_state()*. 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci - In case of transition reverse, restore the previous system 15462306a36Sopenharmony_ci state. It might mean doing nothing. 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci - Remove any not longer needed setting or data. 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci.. note:: 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci *pre_unpatch()* typically does symmetric operations to *post_patch()*. 16162306a36Sopenharmony_ci Except that it is called only when the livepatch is being disabled. 16262306a36Sopenharmony_ci Therefore it does not need to care about any previously installed 16362306a36Sopenharmony_ci livepatch. 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci *post_unpatch()* typically does symmetric operations to *pre_patch()*. 16662306a36Sopenharmony_ci It might be called also during the transition reverse. Therefore it 16762306a36Sopenharmony_ci has to handle the state of the previously installed livepatches. 168