€•Â]Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ'/translations/zh_CN/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/zh_TW/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/it_IT/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ja_JP/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ko_KR/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/pt_BR/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/sp_SP/livepatch/callbacks”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ(Un)patching Callbacks”h]”hŒ(Un)patching Callbacks”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒA/var/lib/git/docbuild/linux/Documentation/livepatch/callbacks.rst”h´KubhŒ paragraph”“”)”}”(hŒêLivepatch (un)patch-callbacks provide a mechanism for livepatch modules to execute callback functions when a kernel object is (un)patched. They can be considered a **power feature** that **extends livepatching abilities** to include:”h]”(hŒ¥Livepatch (un)patch-callbacks provide a mechanism for livepatch modules to execute callback functions when a kernel object is (un)patched. They can be considered a ”…””}”(hhÍh²hh³Nh´NubhŒstrong”“”)”}”(hŒ**power feature**”h]”hŒ power feature”…””}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÍubhŒ that ”…””}”(hhÍh²hh³Nh´NubhÖ)”}”(hŒ"**extends livepatching abilities**”h]”hŒextends livepatching abilities”…””}”(hhéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÍubhŒ to include:”…””}”(hhÍh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhŒ block_quote”“”)”}”(hŒ~- Safe updates to global data - "Patches" to init and probe functions - Patching otherwise unpatchable code (i.e. assembly) ”h]”hŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒSafe updates to global data ”h]”hÌ)”}”(hŒSafe updates to global data”h]”hŒSafe updates to global data”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )”}”(hŒ&"Patches" to init and probe functions ”h]”hÌ)”}”(hŒ%"Patches" to init and probe functions”h]”hŒ)“Patches†to init and probe functions”…””}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hj&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )”}”(hŒ4Patching otherwise unpatchable code (i.e. assembly) ”h]”hÌ)”}”(hŒ3Patching otherwise unpatchable code (i.e. assembly)”h]”hŒ3Patching otherwise unpatchable code (i.e. assembly)”…””}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jh³hÊh´K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K hh·h²hubhÌ)”}”(hŒÏIn most cases, (un)patch callbacks will need to be used in conjunction with memory barriers and kernel synchronization primitives, like mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.”h]”hŒÏIn most cases, (un)patch callbacks will need to be used in conjunction with memory barriers and kernel synchronization primitives, like mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.”…””}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒ 1. Motivation”h]”hŒ 1. Motivation”…””}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjrh²hh³hÊh´KubhÌ)”}”(hŒ1Callbacks differ from existing kernel facilities:”h]”hŒ1Callbacks differ from existing kernel facilities:”…””}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjrh²hubj)”}”(hŒ“- Module init/exit code doesn't run when disabling and re-enabling a patch. - A module notifier can't stop a to-be-patched module from loading. ”h]”j)”}”(hhh]”(j )”}”(hŒJModule init/exit code doesn't run when disabling and re-enabling a patch. ”h]”hÌ)”}”(hŒIModule init/exit code doesn't run when disabling and re-enabling a patch.”h]”hŒKModule init/exit code doesn’t run when disabling and re-enabling a patch.”…””}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj˜ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj•ubj )”}”(hŒBA module notifier can't stop a to-be-patched module from loading. ”h]”hÌ)”}”(hŒAA module notifier can't stop a to-be-patched module from loading.”h]”hŒCA module notifier can’t stop a to-be-patched module from loading.”…””}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj°ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj•ubeh}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´Khj‘ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Khjrh²hubhÌ)”}”(hŒÒCallbacks are part of the klp_object structure and their implementation is specific to that klp_object. Other livepatch objects may or may not be patched, irrespective of the target klp_object's current state.”h]”hŒÔCallbacks are part of the klp_object structure and their implementation is specific to that klp_object. Other livepatch objects may or may not be patched, irrespective of the target klp_object’s current state.”…””}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjrh²hubeh}”(h]”Œ motivation”ah ]”h"]”Œ 1. motivation”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒ2. Callback types”h]”hŒ2. Callback types”…””}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjêh²hh³hÊh´K#ubhÌ)”}”(hŒ@Callbacks can be registered for the following livepatch actions:”h]”hŒ@Callbacks can be registered for the following livepatch actions:”…””}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K%hjêh²hubj)”}”(hX6* Pre-patch - before a klp_object is patched * Post-patch - after a klp_object has been patched and is active across all tasks * Pre-unpatch - before a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources * Post-unpatch - after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources ”h]”j)”}”(hhh]”(j )”}”(hŒ8Pre-patch - before a klp_object is patched ”h]”hŒdefinition_list”“”)”}”(hhh]”hŒdefinition_list_item”“”)”}”(hŒ+Pre-patch - before a klp_object is patched ”h]”(hŒterm”“”)”}”(hŒ Pre-patch”h]”hŒ Pre-patch”…””}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K(hjubhŒ definition”“”)”}”(hhh]”j)”}”(hhh]”j )”}”(hŒbefore a klp_object is patched ”h]”hÌ)”}”(hŒbefore a klp_object is patched”h]”hŒbefore a klp_object is patched”…””}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K(hj7ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4ubah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´K(hj1ubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K(hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )”}”(hŒlPost-patch - after a klp_object has been patched and is active across all tasks ”h]”j)”}”(hhh]”j)”}”(hŒRPost-patch - after a klp_object has been patched and is active across all tasks ”h]”(j )”}”(hŒ Post-patch”h]”hŒ Post-patch”…””}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K,hjtubj0)”}”(hhh]”j)”}”(hhh]”j )”}”(hŒCafter a klp_object has been patched and is active across all tasks ”h]”hÌ)”}”(hŒBafter a klp_object has been patched and is active across all tasks”h]”hŒBafter a klp_object has been patched and is active across all tasks”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K+hjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj‰ubah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´K+hj†ubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hjtubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K,hjqubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjmubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )”}”(hŒ§Pre-unpatch - before a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources ”h]”j)”}”(hhh]”j)”}”(hŒ€Pre-unpatch - before a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources ”h]”(j )”}”(hŒ Pre-unpatch”h]”hŒ Pre-unpatch”…””}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K1hjÉubj0)”}”(hhh]”j)”}”(hhh]”j )”}”(hŒnbefore a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources ”h]”hÌ)”}”(hŒmbefore a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources”h]”hŒmbefore a klp_object is unpatched (ie, patched code is active), used to clean up post-patch callback resources”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K/hjáubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÞubah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´K/hjÛubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hjÉubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K1hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÂubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )”}”(hŒÎPost-unpatch - after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources ”h]”j)”}”(hhh]”j)”}”(hŒ§Post-unpatch - after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources ”h]”(j )”}”(hŒ Post-unpatch”h]”hŒ Post-unpatch”…””}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K6hjubj0)”}”(hhh]”j)”}”(hhh]”j )”}”(hŒ”after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources ”h]”hÌ)”}”(hŒ“after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources”h]”hŒ“after a klp_object has been patched, all code has been restored and no tasks are running patched code, used to cleanup pre-patch callback resources”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K4hj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj3ubah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´K4hj0ubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K6hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubeh}”(h]”h ]”h"]”h$]”h&]”j\Œ*”uh1jh³hÊh´K'hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K'hjêh²hubeh}”(h]”Œcallback-types”ah ]”h"]”Œ2. callback types”ah$]”h&]”uh1hµhh·h²hh³hÊh´K#ubh¶)”}”(hhh]”(h»)”}”(hŒ3. How it works”h]”hŒ3. How it works”…””}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´K9ubhÌ)”}”(hXñEach callback is optional, omitting one does not preclude specifying any other. However, the livepatching core executes the handlers in symmetry: pre-patch callbacks have a post-unpatch counterpart and post-patch callbacks have a pre-unpatch counterpart. An unpatch callback will only be executed if its corresponding patch callback was executed. Typical use cases pair a patch handler that acquires and configures resources with an unpatch handler tears down and releases those same resources.”h]”hXñEach callback is optional, omitting one does not preclude specifying any other. However, the livepatching core executes the handlers in symmetry: pre-patch callbacks have a post-unpatch counterpart and post-patch callbacks have a pre-unpatch counterpart. An unpatch callback will only be executed if its corresponding patch callback was executed. Typical use cases pair a patch handler that acquires and configures resources with an unpatch handler tears down and releases those same resources.”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K;hjh²hubhÌ)”}”(hXxA callback is only executed if its host klp_object is loaded. For in-kernel vmlinux targets, this means that callbacks will always execute when a livepatch is enabled/disabled. For patch target kernel modules, callbacks will only execute if the target module is loaded. When a module target is (un)loaded, its callbacks will execute only if the livepatch module is enabled.”h]”hXxA callback is only executed if its host klp_object is loaded. For in-kernel vmlinux targets, this means that callbacks will always execute when a livepatch is enabled/disabled. For patch target kernel modules, callbacks will only execute if the target module is loaded. When a module target is (un)loaded, its callbacks will execute only if the livepatch module is enabled.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KDhjh²hubhÌ)”}”(hXžThe pre-patch callback, if specified, is expected to return a status code (0 for success, -ERRNO on error). An error status code indicates to the livepatching core that patching of the current klp_object is not safe and to stop the current patching request. (When no pre-patch callback is provided, the transition is assumed to be safe.) If a pre-patch callback returns failure, the kernel's module loader will:”h]”hX The pre-patch callback, if specified, is expected to return a status code (0 for success, -ERRNO on error). An error status code indicates to the livepatching core that patching of the current klp_object is not safe and to stop the current patching request. (When no pre-patch callback is provided, the transition is assumed to be safe.) If a pre-patch callback returns failure, the kernel’s module loader will:”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KKhjh²hubj)”}”(hŒ§- Refuse to load a livepatch, if the livepatch is loaded after targeted code. or: - Refuse to load a module, if the livepatch was already successfully loaded. ”h]”j)”}”(hhh]”(j )”}”(hŒQRefuse to load a livepatch, if the livepatch is loaded after targeted code. or: ”h]”(hÌ)”}”(hŒKRefuse to load a livepatch, if the livepatch is loaded after targeted code.”h]”hŒKRefuse to load a livepatch, if the livepatch is loaded after targeted code.”…””}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KRhjÃubhÌ)”}”(hŒor:”h]”hŒor:”…””}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KUhjÃubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjÀubj )”}”(hŒKRefuse to load a module, if the livepatch was already successfully loaded. ”h]”hÌ)”}”(hŒJRefuse to load a module, if the livepatch was already successfully loaded.”h]”hŒJRefuse to load a module, if the livepatch was already successfully loaded.”…””}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KWhjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÀubeh}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jh³hÊh´KRhj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KRhjh²hubhÌ)”}”(hŒ¸No post-patch, pre-unpatch, or post-unpatch callbacks will be executed for a given klp_object if the object failed to patch, due to a failed pre_patch callback or for any other reason.”h]”hŒ¸No post-patch, pre-unpatch, or post-unpatch callbacks will be executed for a given klp_object if the object failed to patch, due to a failed pre_patch callback or for any other reason.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KZhjh²hubhÌ)”}”(hŒÕIf a patch transition is reversed, no pre-unpatch handlers will be run (this follows the previously mentioned symmetry -- pre-unpatch callbacks will only occur if their corresponding post-patch callback executed).”h]”hŒÕIf a patch transition is reversed, no pre-unpatch handlers will be run (this follows the previously mentioned symmetry -- pre-unpatch callbacks will only occur if their corresponding post-patch callback executed).”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K^hjh²hubhÌ)”}”(hŒ¶If the object did successfully patch, but the patch transition never started for some reason (e.g., if another object failed to patch), only the post-unpatch callback will be called.”h]”hŒ¶If the object did successfully patch, but the patch transition never started for some reason (e.g., if another object failed to patch), only the post-unpatch callback will be called.”…””}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kbhjh²hubeh}”(h]”Œ how-it-works”ah ]”h"]”Œ3. how it works”ah$]”h&]”uh1hµhh·h²hh³hÊh´K9ubh¶)”}”(hhh]”(h»)”}”(hŒ 4. Use cases”h]”hŒ 4. Use cases”…””}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj?h²hh³hÊh´KgubhÌ)”}”(hŒÉSample livepatch modules demonstrating the callback API can be found in samples/livepatch/ directory. These samples were modified for use in kselftests and can be found in the lib/livepatch directory.”h]”hŒÉSample livepatch modules demonstrating the callback API can be found in samples/livepatch/ directory. These samples were modified for use in kselftests and can be found in the lib/livepatch directory.”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kihj?h²hubh¶)”}”(hhh]”(h»)”}”(hŒGlobal data update”h]”hŒGlobal data update”…””}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj^h²hh³hÊh´KnubhÌ)”}”(hŒâA pre-patch callback can be useful to update a global variable. For example, commit 75ff39ccc1bd ("tcp: make challenge acks less predictable") changes a global sysctl, as well as patches the tcp_send_challenge_ack() function.”h]”hŒæA pre-patch callback can be useful to update a global variable. For example, commit 75ff39ccc1bd (“tcp: make challenge acks less predictableâ€) changes a global sysctl, as well as patches the tcp_send_challenge_ack() function.”…””}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kphj^h²hubhÌ)”}”(hŒúIn this case, if we're being super paranoid, it might make sense to patch the data *after* patching is complete with a post-patch callback, so that tcp_send_challenge_ack() could first be changed to read sysctl_tcp_challenge_ack_limit with READ_ONCE.”h]”(hŒUIn this case, if we’re being super paranoid, it might make sense to patch the data ”…””}”(hj}h²hh³Nh´NubhŒemphasis”“”)”}”(hŒ*after*”h]”hŒafter”…””}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j…hj}ubhŒ  patching is complete with a post-patch callback, so that tcp_send_challenge_ack() could first be changed to read sysctl_tcp_challenge_ack_limit with READ_ONCE.”…””}”(hj}h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kuhj^h²hubeh}”(h]”Œglobal-data-update”ah ]”h"]”Œglobal data update”ah$]”h&]”uh1hµhj?h²hh³hÊh´Knubh¶)”}”(hhh]”(h»)”}”(hŒ)__init and probe function patches support”h]”hŒ)__init and probe function patches support”…””}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj§h²hh³hÊh´K{ubhÌ)”}”(hŒ’Although __init and probe functions are not directly livepatch-able, it may be possible to implement similar updates via pre/post-patch callbacks.”h]”hŒ’Although __init and probe functions are not directly livepatch-able, it may be possible to implement similar updates via pre/post-patch callbacks.”…””}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K}hj§h²hubhÌ)”}”(hXHThe commit 48900cb6af42 ("virtio-net: drop NETIF_F_FRAGLIST") change the way that virtnet_probe() initialized its driver's net_device features. A pre/post-patch callback could iterate over all such devices, making a similar change to their hw_features value. (Client functions of the value may need to be updated accordingly.)”h]”hXNThe commit 48900cb6af42 (“virtio-net: drop NETIF_F_FRAGLISTâ€) change the way that virtnet_probe() initialized its driver’s net_device features. A pre/post-patch callback could iterate over all such devices, making a similar change to their hw_features value. (Client functions of the value may need to be updated accordingly.)”…””}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj§h²hubeh}”(h]”Œ'init-and-probe-function-patches-support”ah ]”h"]”Œ)__init and probe function patches support”ah$]”h&]”uh1hµhj?h²hh³hÊh´K{ubeh}”(h]”Œ use-cases”ah ]”h"]”Œ 4. use cases”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kgubeh}”(h]”Œun-patching-callbacks”ah ]”h"]”Œ(un)patching callbacks”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jéjæjçjäj~j{j<j9jájÞj¤j¡jÙjÖuŒ nametypes”}”(jé‰jç‰j~‰j<‰já‰j¤‰jÙ‰uh}”(jæh·jäjrj{jêj9jjÞj?j¡j^jÖj§uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.