Hi there, this patchset is based on POC which I have sent before Linus Plumbers 2013 and presented it there, see https://lore.kernel.org/r/20231110170428.6664-1-pmladek@xxxxxxxx The aim is to help maintaining lifetime of changes made by livepatch callbacks and shadow variables. Key changes include: - Per-state callbacks replace per-object callbacks, invoked only when a livepatch introduces or removes a state. - Shadow variable lifetime is now tied to the corresponding livepatch state lifetime. - The "version" field in `struct klp_state` has been replaced with the "block_disable" flag for improved compatibility handling. - The "data" field has been removed from `struct klp_state`; shadow variables are now the recommended way to store state-related data. Open question: Shadow variables are connected with the state only when state.is_shadow is set. It might make sense to always connect shadow variables with the state using the same "id". It would simplify the semantic and use. But it might be error prone when shadow variables are connected with a state by mistake. It might get improved when we allow to create a shadow variable only when a patch supporting the state with the same "id" is (being) registered. Motivation: The basic livepatch functionality is to redirect problematic functions to a fixed or improved variants. In addition, there are two features helping with more problematic situations: + pre_patch(), post_patch(), pre_unpatch(), post_unpatch() callbacks might be called before and after the respective transitions. For example, post_patch() callback might enable some functionality at the end of the transition when the entire system is using the new code. + Shadow variables allow to add new items into structures or other data objects. The practice has shown that these features were hard to use with the atomic replace feature. The new livepatch usually just adds more fixes. But it might also remove problematic ones. Originally, any version of the livepatch was allowed to replace any older or newer version of the patch. It was not clear how to handle the extra features. The new patch did not know whether to run the callbacks or if the changes were already done by the current livepatch. Or if it has to revert some changes or free shadow variables whey they would no longer be supported. It was even more complicated because only the callbacks from the newly installed livepatch were called. It means that older livepatch might not be able to revert changes supported only by newer livepatches. The above problems were supposed to be solved by adding livepatch states. Each livepatch might define which states are supported. The states are versioned. The livepatch core checks if the newly installed livepatch is able to handle all states used by the currently installed livepatch. Though the practice has shown that the states API was not easy to use either. It was not well connected with the callbacks and shadow variables. The states are per-patch. The callbacks are per-object. The livepatch does not know about the supported shadow variables at all. Changes against POC: + Renamed callbacks back to pre_patch, post_patch, pre_unpatch, and post_unpatch [Josh] + Remove .version field completely [Miroslav] + Removed .data field + Fixed the use of "atomic replace" vs. "cumulative livepatch" terms [Miroslav] + Set .is_shadow in the test module modifying console_loglevel [Miroslav] + Revert pre_unpatch() callbacks when the transition is reverted. [Petr] + Improved and added selftests. Split into many patches [Petr] + Updated documentation [Petr] [POC] https://lore.kernel.org/r/https://lore.kernel.org/r/20231110170428.6664-1-pmladek@xxxxxxxx Base commit: c45323b7560ec87c37c729b703c86ee65f136d75 (6.13-rc7+) Petr Mladek (19): livepatch: Add callbacks for introducing and removing states livepatch: Allow to handle lifetime of shadow variables using the livepatch state selftests/livepatch: Use per-state callbacks in state API tests livepatch: Add "block_disable" flag to per-state API and remove versioning livepatch: Remove "data" from struct klp_state selftests/livepatch: Remove callbacks from sysfs interface testing selftests/livepatch: Substitute hard-coded /sys/module path selftests/livepatch: Move basic tests for livepatching modules selftests/livepatch: Convert testing of multiple target modules selftests/livepatch: Create a simple selftest for state callbacks selftests/livepatch: Convert selftests for failing pre_patch callback selftests/livepatch: Convert selftest with blocked transition selftests/livepatch: Add more tests for state callbacks with blocked transitions selftests/livepatch: Convert selftests for testing callbacks with more livepatches selftests/livepatch: Do not use a livepatch with the obsolete per-object callbacks in the basic selftests selftests/livepatch: Remove obsolete test modules for per-object callbacks samples/livepatch: Replace sample module with obsolete per-object callbacks Documentation/livepatch: Update documentation for state, callbacks, and shadow variables livepatch: Remove obsolete per-object callbacks Documentation/livepatch/api.rst | 2 +- Documentation/livepatch/callbacks.rst | 166 +++--- Documentation/livepatch/index.rst | 4 +- Documentation/livepatch/shadow-vars.rst | 47 +- Documentation/livepatch/system-state.rst | 208 +++---- include/linux/livepatch.h | 81 +-- kernel/livepatch/core.c | 43 +- kernel/livepatch/core.h | 33 -- kernel/livepatch/state.c | 179 +++++- kernel/livepatch/state.h | 9 + kernel/livepatch/transition.c | 20 +- samples/livepatch/Makefile | 5 +- .../livepatch/livepatch-callbacks-busymod.c | 60 -- samples/livepatch/livepatch-callbacks-demo.c | 196 ------- samples/livepatch/livepatch-callbacks-mod.c | 41 -- samples/livepatch/livepatch-speaker-fix.c | 376 ++++++++++++ samples/livepatch/livepatch-speaker-mod.c | 203 +++++++ samples/livepatch/livepatch-speaker.h | 15 + tools/testing/selftests/livepatch/Makefile | 2 + .../testing/selftests/livepatch/functions.sh | 75 ++- .../selftests/livepatch/test-callbacks.sh | 553 ------------------ .../selftests/livepatch/test-livepatch.sh | 4 +- .../testing/selftests/livepatch/test-order.sh | 295 ++++++++++ .../livepatch/test-state-callbacks.sh | 451 ++++++++++++++ .../testing/selftests/livepatch/test-state.sh | 86 ++- .../testing/selftests/livepatch/test-sysfs.sh | 48 +- .../selftests/livepatch/test_modules/Makefile | 8 +- .../test_modules/test_klp_callbacks_busy.c | 70 --- .../test_modules/test_klp_callbacks_demo.c | 121 ---- .../test_modules/test_klp_callbacks_demo2.c | 93 --- .../test_modules/test_klp_callbacks_mod.c | 24 - .../livepatch/test_modules/test_klp_speaker.c | 203 +++++++ .../livepatch/test_modules/test_klp_speaker.h | 15 + .../test_modules/test_klp_speaker2.c | 8 + .../test_modules/test_klp_speaker_livepatch.c | 407 +++++++++++++ .../test_klp_speaker_livepatch2.c | 5 + .../livepatch/test_modules/test_klp_state.c | 143 ++--- .../livepatch/test_modules/test_klp_state2.c | 190 +----- .../livepatch/test_modules/test_klp_state3.c | 2 +- 39 files changed, 2664 insertions(+), 1827 deletions(-) delete mode 100644 samples/livepatch/livepatch-callbacks-busymod.c delete mode 100644 samples/livepatch/livepatch-callbacks-demo.c delete mode 100644 samples/livepatch/livepatch-callbacks-mod.c create mode 100644 samples/livepatch/livepatch-speaker-fix.c create mode 100644 samples/livepatch/livepatch-speaker-mod.c create mode 100644 samples/livepatch/livepatch-speaker.h delete mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh create mode 100755 tools/testing/selftests/livepatch/test-order.sh create mode 100755 tools/testing/selftests/livepatch/test-state-callbacks.sh delete mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_busy.c delete mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo.c delete mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_demo2.c delete mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_callbacks_mod.c create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker.h create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch2.c -- 2.47.1