|  | ==================== | 
|  | System State Changes | 
|  | ==================== | 
|  |  | 
|  | Some users are really reluctant to reboot a system. This brings the need | 
|  | to provide more livepatches and maintain some compatibility between them. | 
|  |  | 
|  | Maintaining more livepatches is much easier with cumulative livepatches. | 
|  | Each new livepatch completely replaces any older one. It can keep, | 
|  | add, and even remove fixes. And it is typically safe to replace any version | 
|  | of the livepatch with any other one thanks to the atomic replace feature. | 
|  |  | 
|  | The problems might come with shadow variables and callbacks. They might | 
|  | change the system behavior or state so that it is no longer safe to | 
|  | go back and use an older livepatch or the original kernel code. Also | 
|  | any new livepatch must be able to detect what changes have already been | 
|  | done by the already installed livepatches. | 
|  |  | 
|  | This is where the livepatch system state tracking gets useful. It | 
|  | allows to: | 
|  |  | 
|  | - store data needed to manipulate and restore the system state | 
|  |  | 
|  | - define compatibility between livepatches using a change id | 
|  | and version | 
|  |  | 
|  |  | 
|  | 1. Livepatch system state API | 
|  | ============================= | 
|  |  | 
|  | The state of the system might get modified either by several livepatch callbacks | 
|  | or by the newly used code. Also it must be possible to find changes done by | 
|  | already installed livepatches. | 
|  |  | 
|  | Each modified state is described by struct klp_state, see | 
|  | include/linux/livepatch.h. | 
|  |  | 
|  | Each livepatch defines an array of struct klp_states. They mention | 
|  | all states that the livepatch modifies. | 
|  |  | 
|  | The livepatch author must define the following two fields for each | 
|  | struct klp_state: | 
|  |  | 
|  | - *id* | 
|  |  | 
|  | - Non-zero number used to identify the affected system state. | 
|  |  | 
|  | - *version* | 
|  |  | 
|  | - Number describing the variant of the system state change that | 
|  | is supported by the given livepatch. | 
|  |  | 
|  | The state can be manipulated using two functions: | 
|  |  | 
|  | - klp_get_state() | 
|  |  | 
|  | - Get struct klp_state associated with the given livepatch | 
|  | and state id. | 
|  |  | 
|  | - klp_get_prev_state() | 
|  |  | 
|  | - Get struct klp_state associated with the given feature id and | 
|  | already installed livepatches. | 
|  |  | 
|  | 2. Livepatch compatibility | 
|  | ========================== | 
|  |  | 
|  | The system state version is used to prevent loading incompatible livepatches. | 
|  | The check is done when the livepatch is enabled. The rules are: | 
|  |  | 
|  | - Any completely new system state modification is allowed. | 
|  |  | 
|  | - System state modifications with the same or higher version are allowed | 
|  | for already modified system states. | 
|  |  | 
|  | - Cumulative livepatches must handle all system state modifications from | 
|  | already installed livepatches. | 
|  |  | 
|  | - Non-cumulative livepatches are allowed to touch already modified | 
|  | system states. | 
|  |  | 
|  | 3. Supported scenarios | 
|  | ====================== | 
|  |  | 
|  | Livepatches have their life-cycle and the same is true for the system | 
|  | state changes. Every compatible livepatch has to support the following | 
|  | scenarios: | 
|  |  | 
|  | - Modify the system state when the livepatch gets enabled and the state | 
|  | has not been already modified by a livepatches that are being | 
|  | replaced. | 
|  |  | 
|  | - Take over or update the system state modification when is has already | 
|  | been done by a livepatch that is being replaced. | 
|  |  | 
|  | - Restore the original state when the livepatch is disabled. | 
|  |  | 
|  | - Restore the previous state when the transition is reverted. | 
|  | It might be the original system state or the state modification | 
|  | done by livepatches that were being replaced. | 
|  |  | 
|  | - Remove any already made changes when error occurs and the livepatch | 
|  | cannot get enabled. | 
|  |  | 
|  | 4. Expected usage | 
|  | ================= | 
|  |  | 
|  | System states are usually modified by livepatch callbacks. The expected | 
|  | role of each callback is as follows: | 
|  |  | 
|  | *pre_patch()* | 
|  |  | 
|  | - Allocate *state->data* when necessary. The allocation might fail | 
|  | and *pre_patch()* is the only callback that could stop loading | 
|  | of the livepatch. The allocation is not needed when the data | 
|  | are already provided by previously installed livepatches. | 
|  |  | 
|  | - Do any other preparatory action that is needed by | 
|  | the new code even before the transition gets finished. | 
|  | For example, initialize *state->data*. | 
|  |  | 
|  | The system state itself is typically modified in *post_patch()* | 
|  | when the entire system is able to handle it. | 
|  |  | 
|  | - Clean up its own mess in case of error. It might be done by a custom | 
|  | code or by calling *post_unpatch()* explicitly. | 
|  |  | 
|  | *post_patch()* | 
|  |  | 
|  | - Copy *state->data* from the previous livepatch when they are | 
|  | compatible. | 
|  |  | 
|  | - Do the actual system state modification. Eventually allow | 
|  | the new code to use it. | 
|  |  | 
|  | - Make sure that *state->data* has all necessary information. | 
|  |  | 
|  | - Free *state->data* from replaces livepatches when they are | 
|  | not longer needed. | 
|  |  | 
|  | *pre_unpatch()* | 
|  |  | 
|  | - Prevent the code, added by the livepatch, relying on the system | 
|  | state change. | 
|  |  | 
|  | - Revert the system state modification.. | 
|  |  | 
|  | *post_unpatch()* | 
|  |  | 
|  | - Distinguish transition reverse and livepatch disabling by | 
|  | checking *klp_get_prev_state()*. | 
|  |  | 
|  | - In case of transition reverse, restore the previous system | 
|  | state. It might mean doing nothing. | 
|  |  | 
|  | - Remove any not longer needed setting or data. | 
|  |  | 
|  | .. note:: | 
|  |  | 
|  | *pre_unpatch()* typically does symmetric operations to *post_patch()*. | 
|  | Except that it is called only when the livepatch is being disabled. | 
|  | Therefore it does not need to care about any previously installed | 
|  | livepatch. | 
|  |  | 
|  | *post_unpatch()* typically does symmetric operations to *pre_patch()*. | 
|  | It might be called also during the transition reverse. Therefore it | 
|  | has to handle the state of the previously installed livepatches. |