Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 # Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
0004 
0005 . $(dirname $0)/functions.sh
0006 
0007 MOD_LIVEPATCH=test_klp_callbacks_demo
0008 MOD_LIVEPATCH2=test_klp_callbacks_demo2
0009 MOD_TARGET=test_klp_callbacks_mod
0010 MOD_TARGET_BUSY=test_klp_callbacks_busy
0011 
0012 setup_config
0013 
0014 
0015 # Test a combination of loading a kernel module and a livepatch that
0016 # patches a function in the first module.  Load the target module
0017 # before the livepatch module.  Unload them in the same order.
0018 #
0019 # - On livepatch enable, before the livepatch transition starts,
0020 #   pre-patch callbacks are executed for vmlinux and $MOD_TARGET (those
0021 #   klp_objects currently loaded).  After klp_objects are patched
0022 #   according to the klp_patch, their post-patch callbacks run and the
0023 #   transition completes.
0024 #
0025 # - Similarly, on livepatch disable, pre-patch callbacks run before the
0026 #   unpatching transition starts.  klp_objects are reverted, post-patch
0027 #   callbacks execute and the transition completes.
0028 
0029 start_test "target module before livepatch"
0030 
0031 load_mod $MOD_TARGET
0032 load_lp $MOD_LIVEPATCH
0033 disable_lp $MOD_LIVEPATCH
0034 unload_lp $MOD_LIVEPATCH
0035 unload_mod $MOD_TARGET
0036 
0037 check_result "% modprobe $MOD_TARGET
0038 $MOD_TARGET: ${MOD_TARGET}_init
0039 % modprobe $MOD_LIVEPATCH
0040 livepatch: enabling patch '$MOD_LIVEPATCH'
0041 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0042 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0043 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0044 livepatch: '$MOD_LIVEPATCH': starting patching transition
0045 livepatch: '$MOD_LIVEPATCH': completing patching transition
0046 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0047 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0048 livepatch: '$MOD_LIVEPATCH': patching complete
0049 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0050 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0051 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0052 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0053 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0054 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0055 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0056 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0057 livepatch: '$MOD_LIVEPATCH': unpatching complete
0058 % rmmod $MOD_LIVEPATCH
0059 % rmmod $MOD_TARGET
0060 $MOD_TARGET: ${MOD_TARGET}_exit"
0061 
0062 
0063 # This test is similar to the previous test, but (un)load the livepatch
0064 # module before the target kernel module.  This tests the livepatch
0065 # core's module_coming handler.
0066 #
0067 # - On livepatch enable, only pre/post-patch callbacks are executed for
0068 #   currently loaded klp_objects, in this case, vmlinux.
0069 #
0070 # - When a targeted module is subsequently loaded, only its
0071 #   pre/post-patch callbacks are executed.
0072 #
0073 # - On livepatch disable, all currently loaded klp_objects' (vmlinux and
0074 #   $MOD_TARGET) pre/post-unpatch callbacks are executed.
0075 
0076 start_test "module_coming notifier"
0077 
0078 load_lp $MOD_LIVEPATCH
0079 load_mod $MOD_TARGET
0080 disable_lp $MOD_LIVEPATCH
0081 unload_lp $MOD_LIVEPATCH
0082 unload_mod $MOD_TARGET
0083 
0084 check_result "% modprobe $MOD_LIVEPATCH
0085 livepatch: enabling patch '$MOD_LIVEPATCH'
0086 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0087 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0088 livepatch: '$MOD_LIVEPATCH': starting patching transition
0089 livepatch: '$MOD_LIVEPATCH': completing patching transition
0090 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0091 livepatch: '$MOD_LIVEPATCH': patching complete
0092 % modprobe $MOD_TARGET
0093 livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
0094 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0095 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0096 $MOD_TARGET: ${MOD_TARGET}_init
0097 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0098 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0099 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0100 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0101 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0102 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0103 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0104 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0105 livepatch: '$MOD_LIVEPATCH': unpatching complete
0106 % rmmod $MOD_LIVEPATCH
0107 % rmmod $MOD_TARGET
0108 $MOD_TARGET: ${MOD_TARGET}_exit"
0109 
0110 
0111 # Test loading the livepatch after a targeted kernel module, then unload
0112 # the kernel module before disabling the livepatch.  This tests the
0113 # livepatch core's module_going handler.
0114 #
0115 # - First load a target module, then the livepatch.
0116 #
0117 # - When a target module is unloaded, the livepatch is only reverted
0118 #   from that klp_object ($MOD_TARGET).  As such, only its pre and
0119 #   post-unpatch callbacks are executed when this occurs.
0120 #
0121 # - When the livepatch is disabled, pre and post-unpatch callbacks are
0122 #   run for the remaining klp_object, vmlinux.
0123 
0124 start_test "module_going notifier"
0125 
0126 load_mod $MOD_TARGET
0127 load_lp $MOD_LIVEPATCH
0128 unload_mod $MOD_TARGET
0129 disable_lp $MOD_LIVEPATCH
0130 unload_lp $MOD_LIVEPATCH
0131 
0132 check_result "% modprobe $MOD_TARGET
0133 $MOD_TARGET: ${MOD_TARGET}_init
0134 % modprobe $MOD_LIVEPATCH
0135 livepatch: enabling patch '$MOD_LIVEPATCH'
0136 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0137 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0138 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0139 livepatch: '$MOD_LIVEPATCH': starting patching transition
0140 livepatch: '$MOD_LIVEPATCH': completing patching transition
0141 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0142 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
0143 livepatch: '$MOD_LIVEPATCH': patching complete
0144 % rmmod $MOD_TARGET
0145 $MOD_TARGET: ${MOD_TARGET}_exit
0146 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0147 livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
0148 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0149 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0150 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0151 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0152 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0153 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0154 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0155 livepatch: '$MOD_LIVEPATCH': unpatching complete
0156 % rmmod $MOD_LIVEPATCH"
0157 
0158 
0159 # This test is similar to the previous test, however the livepatch is
0160 # loaded first.  This tests the livepatch core's module_coming and
0161 # module_going handlers.
0162 #
0163 # - First load the livepatch.
0164 #
0165 # - When a targeted kernel module is subsequently loaded, only its
0166 #   pre/post-patch callbacks are executed.
0167 #
0168 # - When the target module is unloaded, the livepatch is only reverted
0169 #   from the $MOD_TARGET klp_object.  As such, only pre and
0170 #   post-unpatch callbacks are executed when this occurs.
0171 
0172 start_test "module_coming and module_going notifiers"
0173 
0174 load_lp $MOD_LIVEPATCH
0175 load_mod $MOD_TARGET
0176 unload_mod $MOD_TARGET
0177 disable_lp $MOD_LIVEPATCH
0178 unload_lp $MOD_LIVEPATCH
0179 
0180 check_result "% modprobe $MOD_LIVEPATCH
0181 livepatch: enabling patch '$MOD_LIVEPATCH'
0182 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0183 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0184 livepatch: '$MOD_LIVEPATCH': starting patching transition
0185 livepatch: '$MOD_LIVEPATCH': completing patching transition
0186 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0187 livepatch: '$MOD_LIVEPATCH': patching complete
0188 % modprobe $MOD_TARGET
0189 livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
0190 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0191 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0192 $MOD_TARGET: ${MOD_TARGET}_init
0193 % rmmod $MOD_TARGET
0194 $MOD_TARGET: ${MOD_TARGET}_exit
0195 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0196 livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
0197 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0198 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0199 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0200 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0201 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0202 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0203 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0204 livepatch: '$MOD_LIVEPATCH': unpatching complete
0205 % rmmod $MOD_LIVEPATCH"
0206 
0207 
0208 # A simple test of loading a livepatch without one of its patch target
0209 # klp_objects ever loaded ($MOD_TARGET).
0210 #
0211 # - Load the livepatch.
0212 #
0213 # - As expected, only pre/post-(un)patch handlers are executed for
0214 #   vmlinux.
0215 
0216 start_test "target module not present"
0217 
0218 load_lp $MOD_LIVEPATCH
0219 disable_lp $MOD_LIVEPATCH
0220 unload_lp $MOD_LIVEPATCH
0221 
0222 check_result "% modprobe $MOD_LIVEPATCH
0223 livepatch: enabling patch '$MOD_LIVEPATCH'
0224 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0225 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0226 livepatch: '$MOD_LIVEPATCH': starting patching transition
0227 livepatch: '$MOD_LIVEPATCH': completing patching transition
0228 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0229 livepatch: '$MOD_LIVEPATCH': patching complete
0230 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0231 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0232 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0233 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0234 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0235 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0236 livepatch: '$MOD_LIVEPATCH': unpatching complete
0237 % rmmod $MOD_LIVEPATCH"
0238 
0239 
0240 # Test a scenario where a vmlinux pre-patch callback returns a non-zero
0241 # status (ie, failure).
0242 #
0243 # - First load a target module.
0244 #
0245 # - Load the livepatch module, setting its 'pre_patch_ret' value to -19
0246 #   (-ENODEV).  When its vmlinux pre-patch callback executes, this
0247 #   status code will propagate back to the module-loading subsystem.
0248 #   The result is that the insmod command refuses to load the livepatch
0249 #   module.
0250 
0251 start_test "pre-patch callback -ENODEV"
0252 
0253 load_mod $MOD_TARGET
0254 load_failing_mod $MOD_LIVEPATCH pre_patch_ret=-19
0255 unload_mod $MOD_TARGET
0256 
0257 check_result "% modprobe $MOD_TARGET
0258 $MOD_TARGET: ${MOD_TARGET}_init
0259 % modprobe $MOD_LIVEPATCH pre_patch_ret=-19
0260 livepatch: enabling patch '$MOD_LIVEPATCH'
0261 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0262 test_klp_callbacks_demo: pre_patch_callback: vmlinux
0263 livepatch: pre-patch callback failed for object 'vmlinux'
0264 livepatch: failed to enable patch '$MOD_LIVEPATCH'
0265 livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
0266 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0267 livepatch: '$MOD_LIVEPATCH': unpatching complete
0268 modprobe: ERROR: could not insert '$MOD_LIVEPATCH': No such device
0269 % rmmod $MOD_TARGET
0270 $MOD_TARGET: ${MOD_TARGET}_exit"
0271 
0272 
0273 # Similar to the previous test, setup a livepatch such that its vmlinux
0274 # pre-patch callback returns success.  However, when a targeted kernel
0275 # module is later loaded, have the livepatch return a failing status
0276 # code.
0277 #
0278 # - Load the livepatch, vmlinux pre-patch callback succeeds.
0279 #
0280 # - Set a trap so subsequent pre-patch callbacks to this livepatch will
0281 #   return -ENODEV.
0282 #
0283 # - The livepatch pre-patch callback for subsequently loaded target
0284 #   modules will return failure, so the module loader refuses to load
0285 #   the kernel module.  No post-patch or pre/post-unpatch callbacks are
0286 #   executed for this klp_object.
0287 #
0288 # - Pre/post-unpatch callbacks are run for the vmlinux klp_object.
0289 
0290 start_test "module_coming + pre-patch callback -ENODEV"
0291 
0292 load_lp $MOD_LIVEPATCH
0293 set_pre_patch_ret $MOD_LIVEPATCH -19
0294 load_failing_mod $MOD_TARGET
0295 disable_lp $MOD_LIVEPATCH
0296 unload_lp $MOD_LIVEPATCH
0297 
0298 check_result "% modprobe $MOD_LIVEPATCH
0299 livepatch: enabling patch '$MOD_LIVEPATCH'
0300 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0301 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0302 livepatch: '$MOD_LIVEPATCH': starting patching transition
0303 livepatch: '$MOD_LIVEPATCH': completing patching transition
0304 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0305 livepatch: '$MOD_LIVEPATCH': patching complete
0306 % echo -19 > /sys/module/$MOD_LIVEPATCH/parameters/pre_patch_ret
0307 % modprobe $MOD_TARGET
0308 livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
0309 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0310 livepatch: pre-patch callback failed for object '$MOD_TARGET'
0311 livepatch: patch '$MOD_LIVEPATCH' failed for module '$MOD_TARGET', refusing to load module '$MOD_TARGET'
0312 modprobe: ERROR: could not insert '$MOD_TARGET': No such device
0313 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0314 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0315 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0316 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0317 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0318 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0319 livepatch: '$MOD_LIVEPATCH': unpatching complete
0320 % rmmod $MOD_LIVEPATCH"
0321 
0322 
0323 # Test loading multiple targeted kernel modules.  This test-case is
0324 # mainly for comparing with the next test-case.
0325 #
0326 # - Load a target "busy" kernel module which kicks off a worker function
0327 #   that immediately exits.
0328 #
0329 # - Proceed with loading the livepatch and another ordinary target
0330 #   module.  Post-patch callbacks are executed and the transition
0331 #   completes quickly.
0332 
0333 start_test "multiple target modules"
0334 
0335 load_mod $MOD_TARGET_BUSY block_transition=N
0336 load_lp $MOD_LIVEPATCH
0337 load_mod $MOD_TARGET
0338 unload_mod $MOD_TARGET
0339 disable_lp $MOD_LIVEPATCH
0340 unload_lp $MOD_LIVEPATCH
0341 unload_mod $MOD_TARGET_BUSY
0342 
0343 check_result "% modprobe $MOD_TARGET_BUSY block_transition=N
0344 $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
0345 $MOD_TARGET_BUSY: busymod_work_func enter
0346 $MOD_TARGET_BUSY: busymod_work_func exit
0347 % modprobe $MOD_LIVEPATCH
0348 livepatch: enabling patch '$MOD_LIVEPATCH'
0349 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0350 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0351 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0352 livepatch: '$MOD_LIVEPATCH': starting patching transition
0353 livepatch: '$MOD_LIVEPATCH': completing patching transition
0354 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0355 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0356 livepatch: '$MOD_LIVEPATCH': patching complete
0357 % modprobe $MOD_TARGET
0358 livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
0359 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0360 $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0361 $MOD_TARGET: ${MOD_TARGET}_init
0362 % rmmod $MOD_TARGET
0363 $MOD_TARGET: ${MOD_TARGET}_exit
0364 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0365 livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
0366 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0367 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0368 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0369 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0370 $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0371 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0372 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0373 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0374 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0375 livepatch: '$MOD_LIVEPATCH': unpatching complete
0376 % rmmod $MOD_LIVEPATCH
0377 % rmmod $MOD_TARGET_BUSY
0378 $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
0379 
0380 
0381 # A similar test as the previous one, but force the "busy" kernel module
0382 # to block the livepatch transition.
0383 #
0384 # The livepatching core will refuse to patch a task that is currently
0385 # executing a to-be-patched function -- the consistency model stalls the
0386 # current patch transition until this safety-check is met.  Test a
0387 # scenario where one of a livepatch's target klp_objects sits on such a
0388 # function for a long time.  Meanwhile, load and unload other target
0389 # kernel modules while the livepatch transition is in progress.
0390 #
0391 # - Load the "busy" kernel module, this time make its work function loop
0392 #
0393 # - Meanwhile, the livepatch is loaded.  Notice that the patch
0394 #   transition does not complete as the targeted "busy" module is
0395 #   sitting on a to-be-patched function.
0396 #
0397 # - Load a second target module (this one is an ordinary idle kernel
0398 #   module).  Note that *no* post-patch callbacks will be executed while
0399 #   the livepatch is still in transition.
0400 #
0401 # - Request an unload of the simple kernel module.  The patch is still
0402 #   transitioning, so its pre-unpatch callbacks are skipped.
0403 #
0404 # - Finally the livepatch is disabled.  Since none of the patch's
0405 #   klp_object's post-patch callbacks executed, the remaining
0406 #   klp_object's pre-unpatch callbacks are skipped.
0407 
0408 start_test "busy target module"
0409 
0410 load_mod $MOD_TARGET_BUSY block_transition=Y
0411 load_lp_nowait $MOD_LIVEPATCH
0412 
0413 # Wait until the livepatch reports in-transition state, i.e. that it's
0414 # stalled on $MOD_TARGET_BUSY::busymod_work_func()
0415 loop_until 'grep -q '^1$' /sys/kernel/livepatch/$MOD_LIVEPATCH/transition' ||
0416         die "failed to stall transition"
0417 
0418 load_mod $MOD_TARGET
0419 unload_mod $MOD_TARGET
0420 disable_lp $MOD_LIVEPATCH
0421 unload_lp $MOD_LIVEPATCH
0422 unload_mod $MOD_TARGET_BUSY
0423 
0424 check_result "% modprobe $MOD_TARGET_BUSY block_transition=Y
0425 $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
0426 $MOD_TARGET_BUSY: busymod_work_func enter
0427 % modprobe $MOD_LIVEPATCH
0428 livepatch: enabling patch '$MOD_LIVEPATCH'
0429 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0430 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0431 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0432 livepatch: '$MOD_LIVEPATCH': starting patching transition
0433 % modprobe $MOD_TARGET
0434 livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
0435 $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
0436 $MOD_TARGET: ${MOD_TARGET}_init
0437 % rmmod $MOD_TARGET
0438 $MOD_TARGET: ${MOD_TARGET}_exit
0439 livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
0440 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
0441 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0442 livepatch: '$MOD_LIVEPATCH': reversing transition from patching to unpatching
0443 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0444 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0445 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0446 $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
0447 livepatch: '$MOD_LIVEPATCH': unpatching complete
0448 % rmmod $MOD_LIVEPATCH
0449 % rmmod $MOD_TARGET_BUSY
0450 $MOD_TARGET_BUSY: busymod_work_func exit
0451 $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
0452 
0453 
0454 # Test loading multiple livepatches.  This test-case is mainly for comparing
0455 # with the next test-case.
0456 #
0457 # - Load and unload two livepatches, pre and post (un)patch callbacks
0458 #   execute as each patch progresses through its (un)patching
0459 #   transition.
0460 
0461 start_test "multiple livepatches"
0462 
0463 load_lp $MOD_LIVEPATCH
0464 load_lp $MOD_LIVEPATCH2
0465 disable_lp $MOD_LIVEPATCH2
0466 disable_lp $MOD_LIVEPATCH
0467 unload_lp $MOD_LIVEPATCH2
0468 unload_lp $MOD_LIVEPATCH
0469 
0470 check_result "% modprobe $MOD_LIVEPATCH
0471 livepatch: enabling patch '$MOD_LIVEPATCH'
0472 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0473 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0474 livepatch: '$MOD_LIVEPATCH': starting patching transition
0475 livepatch: '$MOD_LIVEPATCH': completing patching transition
0476 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0477 livepatch: '$MOD_LIVEPATCH': patching complete
0478 % modprobe $MOD_LIVEPATCH2
0479 livepatch: enabling patch '$MOD_LIVEPATCH2'
0480 livepatch: '$MOD_LIVEPATCH2': initializing patching transition
0481 $MOD_LIVEPATCH2: pre_patch_callback: vmlinux
0482 livepatch: '$MOD_LIVEPATCH2': starting patching transition
0483 livepatch: '$MOD_LIVEPATCH2': completing patching transition
0484 $MOD_LIVEPATCH2: post_patch_callback: vmlinux
0485 livepatch: '$MOD_LIVEPATCH2': patching complete
0486 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
0487 livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
0488 $MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
0489 livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
0490 livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
0491 $MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
0492 livepatch: '$MOD_LIVEPATCH2': unpatching complete
0493 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
0494 livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
0495 $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
0496 livepatch: '$MOD_LIVEPATCH': starting unpatching transition
0497 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
0498 $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
0499 livepatch: '$MOD_LIVEPATCH': unpatching complete
0500 % rmmod $MOD_LIVEPATCH2
0501 % rmmod $MOD_LIVEPATCH"
0502 
0503 
0504 # Load multiple livepatches, but the second as an 'atomic-replace'
0505 # patch.  When the latter loads, the original livepatch should be
0506 # disabled and *none* of its pre/post-unpatch callbacks executed.  On
0507 # the other hand, when the atomic-replace livepatch is disabled, its
0508 # pre/post-unpatch callbacks *should* be executed.
0509 #
0510 # - Load and unload two livepatches, the second of which has its
0511 #   .replace flag set true.
0512 #
0513 # - Pre and post patch callbacks are executed for both livepatches.
0514 #
0515 # - Once the atomic replace module is loaded, only its pre and post
0516 #   unpatch callbacks are executed.
0517 
0518 start_test "atomic replace"
0519 
0520 load_lp $MOD_LIVEPATCH
0521 load_lp $MOD_LIVEPATCH2 replace=1
0522 disable_lp $MOD_LIVEPATCH2
0523 unload_lp $MOD_LIVEPATCH2
0524 unload_lp $MOD_LIVEPATCH
0525 
0526 check_result "% modprobe $MOD_LIVEPATCH
0527 livepatch: enabling patch '$MOD_LIVEPATCH'
0528 livepatch: '$MOD_LIVEPATCH': initializing patching transition
0529 $MOD_LIVEPATCH: pre_patch_callback: vmlinux
0530 livepatch: '$MOD_LIVEPATCH': starting patching transition
0531 livepatch: '$MOD_LIVEPATCH': completing patching transition
0532 $MOD_LIVEPATCH: post_patch_callback: vmlinux
0533 livepatch: '$MOD_LIVEPATCH': patching complete
0534 % modprobe $MOD_LIVEPATCH2 replace=1
0535 livepatch: enabling patch '$MOD_LIVEPATCH2'
0536 livepatch: '$MOD_LIVEPATCH2': initializing patching transition
0537 $MOD_LIVEPATCH2: pre_patch_callback: vmlinux
0538 livepatch: '$MOD_LIVEPATCH2': starting patching transition
0539 livepatch: '$MOD_LIVEPATCH2': completing patching transition
0540 $MOD_LIVEPATCH2: post_patch_callback: vmlinux
0541 livepatch: '$MOD_LIVEPATCH2': patching complete
0542 % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
0543 livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
0544 $MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
0545 livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
0546 livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
0547 $MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
0548 livepatch: '$MOD_LIVEPATCH2': unpatching complete
0549 % rmmod $MOD_LIVEPATCH2
0550 % rmmod $MOD_LIVEPATCH"
0551 
0552 
0553 exit 0