1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
4
5. $(dirname $0)/functions.sh
6
7MOD_LIVEPATCH=test_klp_callbacks_demo
8MOD_LIVEPATCH2=test_klp_callbacks_demo2
9MOD_TARGET=test_klp_callbacks_mod
10MOD_TARGET_BUSY=test_klp_callbacks_busy
11
12setup_config
13
14
15# Test a combination of loading a kernel module and a livepatch that
16# patches a function in the first module.  Load the target module
17# before the livepatch module.  Unload them in the same order.
18#
19# - On livepatch enable, before the livepatch transition starts,
20#   pre-patch callbacks are executed for vmlinux and $MOD_TARGET (those
21#   klp_objects currently loaded).  After klp_objects are patched
22#   according to the klp_patch, their post-patch callbacks run and the
23#   transition completes.
24#
25# - Similarly, on livepatch disable, pre-patch callbacks run before the
26#   unpatching transition starts.  klp_objects are reverted, post-patch
27#   callbacks execute and the transition completes.
28
29start_test "target module before livepatch"
30
31load_mod $MOD_TARGET
32load_lp $MOD_LIVEPATCH
33disable_lp $MOD_LIVEPATCH
34unload_lp $MOD_LIVEPATCH
35unload_mod $MOD_TARGET
36
37check_result "% modprobe $MOD_TARGET
38$MOD_TARGET: ${MOD_TARGET}_init
39% modprobe $MOD_LIVEPATCH
40livepatch: enabling patch '$MOD_LIVEPATCH'
41livepatch: '$MOD_LIVEPATCH': initializing patching transition
42$MOD_LIVEPATCH: pre_patch_callback: vmlinux
43$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
44livepatch: '$MOD_LIVEPATCH': starting patching transition
45livepatch: '$MOD_LIVEPATCH': completing patching transition
46$MOD_LIVEPATCH: post_patch_callback: vmlinux
47$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
48livepatch: '$MOD_LIVEPATCH': patching complete
49% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
50livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
51$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
52$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
53livepatch: '$MOD_LIVEPATCH': starting unpatching transition
54livepatch: '$MOD_LIVEPATCH': completing unpatching transition
55$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
56$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
57livepatch: '$MOD_LIVEPATCH': unpatching complete
58% rmmod $MOD_LIVEPATCH
59% rmmod $MOD_TARGET
60$MOD_TARGET: ${MOD_TARGET}_exit"
61
62
63# This test is similar to the previous test, but (un)load the livepatch
64# module before the target kernel module.  This tests the livepatch
65# core's module_coming handler.
66#
67# - On livepatch enable, only pre/post-patch callbacks are executed for
68#   currently loaded klp_objects, in this case, vmlinux.
69#
70# - When a targeted module is subsequently loaded, only its
71#   pre/post-patch callbacks are executed.
72#
73# - On livepatch disable, all currently loaded klp_objects' (vmlinux and
74#   $MOD_TARGET) pre/post-unpatch callbacks are executed.
75
76start_test "module_coming notifier"
77
78load_lp $MOD_LIVEPATCH
79load_mod $MOD_TARGET
80disable_lp $MOD_LIVEPATCH
81unload_lp $MOD_LIVEPATCH
82unload_mod $MOD_TARGET
83
84check_result "% modprobe $MOD_LIVEPATCH
85livepatch: enabling patch '$MOD_LIVEPATCH'
86livepatch: '$MOD_LIVEPATCH': initializing patching transition
87$MOD_LIVEPATCH: pre_patch_callback: vmlinux
88livepatch: '$MOD_LIVEPATCH': starting patching transition
89livepatch: '$MOD_LIVEPATCH': completing patching transition
90$MOD_LIVEPATCH: post_patch_callback: vmlinux
91livepatch: '$MOD_LIVEPATCH': patching complete
92% modprobe $MOD_TARGET
93livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
94$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
95$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
96$MOD_TARGET: ${MOD_TARGET}_init
97% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
98livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
99$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
100$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
101livepatch: '$MOD_LIVEPATCH': starting unpatching transition
102livepatch: '$MOD_LIVEPATCH': completing unpatching transition
103$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
104$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
105livepatch: '$MOD_LIVEPATCH': unpatching complete
106% rmmod $MOD_LIVEPATCH
107% rmmod $MOD_TARGET
108$MOD_TARGET: ${MOD_TARGET}_exit"
109
110
111# Test loading the livepatch after a targeted kernel module, then unload
112# the kernel module before disabling the livepatch.  This tests the
113# livepatch core's module_going handler.
114#
115# - First load a target module, then the livepatch.
116#
117# - When a target module is unloaded, the livepatch is only reverted
118#   from that klp_object ($MOD_TARGET).  As such, only its pre and
119#   post-unpatch callbacks are executed when this occurs.
120#
121# - When the livepatch is disabled, pre and post-unpatch callbacks are
122#   run for the remaining klp_object, vmlinux.
123
124start_test "module_going notifier"
125
126load_mod $MOD_TARGET
127load_lp $MOD_LIVEPATCH
128unload_mod $MOD_TARGET
129disable_lp $MOD_LIVEPATCH
130unload_lp $MOD_LIVEPATCH
131
132check_result "% modprobe $MOD_TARGET
133$MOD_TARGET: ${MOD_TARGET}_init
134% modprobe $MOD_LIVEPATCH
135livepatch: enabling patch '$MOD_LIVEPATCH'
136livepatch: '$MOD_LIVEPATCH': initializing patching transition
137$MOD_LIVEPATCH: pre_patch_callback: vmlinux
138$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
139livepatch: '$MOD_LIVEPATCH': starting patching transition
140livepatch: '$MOD_LIVEPATCH': completing patching transition
141$MOD_LIVEPATCH: post_patch_callback: vmlinux
142$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
143livepatch: '$MOD_LIVEPATCH': patching complete
144% rmmod $MOD_TARGET
145$MOD_TARGET: ${MOD_TARGET}_exit
146$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
147livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
148$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
149% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
150livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
151$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
152livepatch: '$MOD_LIVEPATCH': starting unpatching transition
153livepatch: '$MOD_LIVEPATCH': completing unpatching transition
154$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
155livepatch: '$MOD_LIVEPATCH': unpatching complete
156% rmmod $MOD_LIVEPATCH"
157
158
159# This test is similar to the previous test, however the livepatch is
160# loaded first.  This tests the livepatch core's module_coming and
161# module_going handlers.
162#
163# - First load the livepatch.
164#
165# - When a targeted kernel module is subsequently loaded, only its
166#   pre/post-patch callbacks are executed.
167#
168# - When the target module is unloaded, the livepatch is only reverted
169#   from the $MOD_TARGET klp_object.  As such, only pre and
170#   post-unpatch callbacks are executed when this occurs.
171
172start_test "module_coming and module_going notifiers"
173
174load_lp $MOD_LIVEPATCH
175load_mod $MOD_TARGET
176unload_mod $MOD_TARGET
177disable_lp $MOD_LIVEPATCH
178unload_lp $MOD_LIVEPATCH
179
180check_result "% modprobe $MOD_LIVEPATCH
181livepatch: enabling patch '$MOD_LIVEPATCH'
182livepatch: '$MOD_LIVEPATCH': initializing patching transition
183$MOD_LIVEPATCH: pre_patch_callback: vmlinux
184livepatch: '$MOD_LIVEPATCH': starting patching transition
185livepatch: '$MOD_LIVEPATCH': completing patching transition
186$MOD_LIVEPATCH: post_patch_callback: vmlinux
187livepatch: '$MOD_LIVEPATCH': patching complete
188% modprobe $MOD_TARGET
189livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
190$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
191$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
192$MOD_TARGET: ${MOD_TARGET}_init
193% rmmod $MOD_TARGET
194$MOD_TARGET: ${MOD_TARGET}_exit
195$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
196livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
197$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
198% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
199livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
200$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
201livepatch: '$MOD_LIVEPATCH': starting unpatching transition
202livepatch: '$MOD_LIVEPATCH': completing unpatching transition
203$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
204livepatch: '$MOD_LIVEPATCH': unpatching complete
205% rmmod $MOD_LIVEPATCH"
206
207
208# A simple test of loading a livepatch without one of its patch target
209# klp_objects ever loaded ($MOD_TARGET).
210#
211# - Load the livepatch.
212#
213# - As expected, only pre/post-(un)patch handlers are executed for
214#   vmlinux.
215
216start_test "target module not present"
217
218load_lp $MOD_LIVEPATCH
219disable_lp $MOD_LIVEPATCH
220unload_lp $MOD_LIVEPATCH
221
222check_result "% modprobe $MOD_LIVEPATCH
223livepatch: enabling patch '$MOD_LIVEPATCH'
224livepatch: '$MOD_LIVEPATCH': initializing patching transition
225$MOD_LIVEPATCH: pre_patch_callback: vmlinux
226livepatch: '$MOD_LIVEPATCH': starting patching transition
227livepatch: '$MOD_LIVEPATCH': completing patching transition
228$MOD_LIVEPATCH: post_patch_callback: vmlinux
229livepatch: '$MOD_LIVEPATCH': patching complete
230% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
231livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
232$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
233livepatch: '$MOD_LIVEPATCH': starting unpatching transition
234livepatch: '$MOD_LIVEPATCH': completing unpatching transition
235$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
236livepatch: '$MOD_LIVEPATCH': unpatching complete
237% rmmod $MOD_LIVEPATCH"
238
239
240# Test a scenario where a vmlinux pre-patch callback returns a non-zero
241# status (ie, failure).
242#
243# - First load a target module.
244#
245# - Load the livepatch module, setting its 'pre_patch_ret' value to -19
246#   (-ENODEV).  When its vmlinux pre-patch callback executes, this
247#   status code will propagate back to the module-loading subsystem.
248#   The result is that the insmod command refuses to load the livepatch
249#   module.
250
251start_test "pre-patch callback -ENODEV"
252
253load_mod $MOD_TARGET
254load_failing_mod $MOD_LIVEPATCH pre_patch_ret=-19
255unload_mod $MOD_TARGET
256
257check_result "% modprobe $MOD_TARGET
258$MOD_TARGET: ${MOD_TARGET}_init
259% modprobe $MOD_LIVEPATCH pre_patch_ret=-19
260livepatch: enabling patch '$MOD_LIVEPATCH'
261livepatch: '$MOD_LIVEPATCH': initializing patching transition
262test_klp_callbacks_demo: pre_patch_callback: vmlinux
263livepatch: pre-patch callback failed for object 'vmlinux'
264livepatch: failed to enable patch '$MOD_LIVEPATCH'
265livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
266livepatch: '$MOD_LIVEPATCH': completing unpatching transition
267livepatch: '$MOD_LIVEPATCH': unpatching complete
268modprobe: ERROR: could not insert '$MOD_LIVEPATCH': No such device
269% rmmod $MOD_TARGET
270$MOD_TARGET: ${MOD_TARGET}_exit"
271
272
273# Similar to the previous test, setup a livepatch such that its vmlinux
274# pre-patch callback returns success.  However, when a targeted kernel
275# module is later loaded, have the livepatch return a failing status
276# code.
277#
278# - Load the livepatch, vmlinux pre-patch callback succeeds.
279#
280# - Set a trap so subsequent pre-patch callbacks to this livepatch will
281#   return -ENODEV.
282#
283# - The livepatch pre-patch callback for subsequently loaded target
284#   modules will return failure, so the module loader refuses to load
285#   the kernel module.  No post-patch or pre/post-unpatch callbacks are
286#   executed for this klp_object.
287#
288# - Pre/post-unpatch callbacks are run for the vmlinux klp_object.
289
290start_test "module_coming + pre-patch callback -ENODEV"
291
292load_lp $MOD_LIVEPATCH
293set_pre_patch_ret $MOD_LIVEPATCH -19
294load_failing_mod $MOD_TARGET
295disable_lp $MOD_LIVEPATCH
296unload_lp $MOD_LIVEPATCH
297
298check_result "% modprobe $MOD_LIVEPATCH
299livepatch: enabling patch '$MOD_LIVEPATCH'
300livepatch: '$MOD_LIVEPATCH': initializing patching transition
301$MOD_LIVEPATCH: pre_patch_callback: vmlinux
302livepatch: '$MOD_LIVEPATCH': starting patching transition
303livepatch: '$MOD_LIVEPATCH': completing patching transition
304$MOD_LIVEPATCH: post_patch_callback: vmlinux
305livepatch: '$MOD_LIVEPATCH': patching complete
306% echo -19 > /sys/module/$MOD_LIVEPATCH/parameters/pre_patch_ret
307% modprobe $MOD_TARGET
308livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
309$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
310livepatch: pre-patch callback failed for object '$MOD_TARGET'
311livepatch: patch '$MOD_LIVEPATCH' failed for module '$MOD_TARGET', refusing to load module '$MOD_TARGET'
312modprobe: ERROR: could not insert '$MOD_TARGET': No such device
313% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
314livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
315$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
316livepatch: '$MOD_LIVEPATCH': starting unpatching transition
317livepatch: '$MOD_LIVEPATCH': completing unpatching transition
318$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
319livepatch: '$MOD_LIVEPATCH': unpatching complete
320% rmmod $MOD_LIVEPATCH"
321
322
323# Test loading multiple targeted kernel modules.  This test-case is
324# mainly for comparing with the next test-case.
325#
326# - Load a target "busy" kernel module which kicks off a worker function
327#   that immediately exits.
328#
329# - Proceed with loading the livepatch and another ordinary target
330#   module.  Post-patch callbacks are executed and the transition
331#   completes quickly.
332
333start_test "multiple target modules"
334
335load_mod $MOD_TARGET_BUSY block_transition=N
336load_lp $MOD_LIVEPATCH
337load_mod $MOD_TARGET
338unload_mod $MOD_TARGET
339disable_lp $MOD_LIVEPATCH
340unload_lp $MOD_LIVEPATCH
341unload_mod $MOD_TARGET_BUSY
342
343check_result "% modprobe $MOD_TARGET_BUSY block_transition=N
344$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
345$MOD_TARGET_BUSY: busymod_work_func enter
346$MOD_TARGET_BUSY: busymod_work_func exit
347% modprobe $MOD_LIVEPATCH
348livepatch: enabling patch '$MOD_LIVEPATCH'
349livepatch: '$MOD_LIVEPATCH': initializing patching transition
350$MOD_LIVEPATCH: pre_patch_callback: vmlinux
351$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
352livepatch: '$MOD_LIVEPATCH': starting patching transition
353livepatch: '$MOD_LIVEPATCH': completing patching transition
354$MOD_LIVEPATCH: post_patch_callback: vmlinux
355$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
356livepatch: '$MOD_LIVEPATCH': patching complete
357% modprobe $MOD_TARGET
358livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
359$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
360$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
361$MOD_TARGET: ${MOD_TARGET}_init
362% rmmod $MOD_TARGET
363$MOD_TARGET: ${MOD_TARGET}_exit
364$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
365livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
366$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
367% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
368livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
369$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
370$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
371livepatch: '$MOD_LIVEPATCH': starting unpatching transition
372livepatch: '$MOD_LIVEPATCH': completing unpatching transition
373$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
374$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
375livepatch: '$MOD_LIVEPATCH': unpatching complete
376% rmmod $MOD_LIVEPATCH
377% rmmod $MOD_TARGET_BUSY
378$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
379
380
381# A similar test as the previous one, but force the "busy" kernel module
382# to block the livepatch transition.
383#
384# The livepatching core will refuse to patch a task that is currently
385# executing a to-be-patched function -- the consistency model stalls the
386# current patch transition until this safety-check is met.  Test a
387# scenario where one of a livepatch's target klp_objects sits on such a
388# function for a long time.  Meanwhile, load and unload other target
389# kernel modules while the livepatch transition is in progress.
390#
391# - Load the "busy" kernel module, this time make its work function loop
392#
393# - Meanwhile, the livepatch is loaded.  Notice that the patch
394#   transition does not complete as the targeted "busy" module is
395#   sitting on a to-be-patched function.
396#
397# - Load a second target module (this one is an ordinary idle kernel
398#   module).  Note that *no* post-patch callbacks will be executed while
399#   the livepatch is still in transition.
400#
401# - Request an unload of the simple kernel module.  The patch is still
402#   transitioning, so its pre-unpatch callbacks are skipped.
403#
404# - Finally the livepatch is disabled.  Since none of the patch's
405#   klp_object's post-patch callbacks executed, the remaining
406#   klp_object's pre-unpatch callbacks are skipped.
407
408start_test "busy target module"
409
410load_mod $MOD_TARGET_BUSY block_transition=Y
411load_lp_nowait $MOD_LIVEPATCH
412
413# Wait until the livepatch reports in-transition state, i.e. that it's
414# stalled on $MOD_TARGET_BUSY::busymod_work_func()
415loop_until 'grep -q '^1$' /sys/kernel/livepatch/$MOD_LIVEPATCH/transition' ||
416	die "failed to stall transition"
417
418load_mod $MOD_TARGET
419unload_mod $MOD_TARGET
420disable_lp $MOD_LIVEPATCH
421unload_lp $MOD_LIVEPATCH
422unload_mod $MOD_TARGET_BUSY
423
424check_result "% modprobe $MOD_TARGET_BUSY block_transition=Y
425$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
426$MOD_TARGET_BUSY: busymod_work_func enter
427% modprobe $MOD_LIVEPATCH
428livepatch: enabling patch '$MOD_LIVEPATCH'
429livepatch: '$MOD_LIVEPATCH': initializing patching transition
430$MOD_LIVEPATCH: pre_patch_callback: vmlinux
431$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
432livepatch: '$MOD_LIVEPATCH': starting patching transition
433% modprobe $MOD_TARGET
434livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
435$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
436$MOD_TARGET: ${MOD_TARGET}_init
437% rmmod $MOD_TARGET
438$MOD_TARGET: ${MOD_TARGET}_exit
439livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
440$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
441% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
442livepatch: '$MOD_LIVEPATCH': reversing transition from patching to unpatching
443livepatch: '$MOD_LIVEPATCH': starting unpatching transition
444livepatch: '$MOD_LIVEPATCH': completing unpatching transition
445$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
446$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
447livepatch: '$MOD_LIVEPATCH': unpatching complete
448% rmmod $MOD_LIVEPATCH
449% rmmod $MOD_TARGET_BUSY
450$MOD_TARGET_BUSY: busymod_work_func exit
451$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
452
453
454# Test loading multiple livepatches.  This test-case is mainly for comparing
455# with the next test-case.
456#
457# - Load and unload two livepatches, pre and post (un)patch callbacks
458#   execute as each patch progresses through its (un)patching
459#   transition.
460
461start_test "multiple livepatches"
462
463load_lp $MOD_LIVEPATCH
464load_lp $MOD_LIVEPATCH2
465disable_lp $MOD_LIVEPATCH2
466disable_lp $MOD_LIVEPATCH
467unload_lp $MOD_LIVEPATCH2
468unload_lp $MOD_LIVEPATCH
469
470check_result "% modprobe $MOD_LIVEPATCH
471livepatch: enabling patch '$MOD_LIVEPATCH'
472livepatch: '$MOD_LIVEPATCH': initializing patching transition
473$MOD_LIVEPATCH: pre_patch_callback: vmlinux
474livepatch: '$MOD_LIVEPATCH': starting patching transition
475livepatch: '$MOD_LIVEPATCH': completing patching transition
476$MOD_LIVEPATCH: post_patch_callback: vmlinux
477livepatch: '$MOD_LIVEPATCH': patching complete
478% modprobe $MOD_LIVEPATCH2
479livepatch: enabling patch '$MOD_LIVEPATCH2'
480livepatch: '$MOD_LIVEPATCH2': initializing patching transition
481$MOD_LIVEPATCH2: pre_patch_callback: vmlinux
482livepatch: '$MOD_LIVEPATCH2': starting patching transition
483livepatch: '$MOD_LIVEPATCH2': completing patching transition
484$MOD_LIVEPATCH2: post_patch_callback: vmlinux
485livepatch: '$MOD_LIVEPATCH2': patching complete
486% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
487livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
488$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
489livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
490livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
491$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
492livepatch: '$MOD_LIVEPATCH2': unpatching complete
493% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
494livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
495$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
496livepatch: '$MOD_LIVEPATCH': starting unpatching transition
497livepatch: '$MOD_LIVEPATCH': completing unpatching transition
498$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
499livepatch: '$MOD_LIVEPATCH': unpatching complete
500% rmmod $MOD_LIVEPATCH2
501% rmmod $MOD_LIVEPATCH"
502
503
504# Load multiple livepatches, but the second as an 'atomic-replace'
505# patch.  When the latter loads, the original livepatch should be
506# disabled and *none* of its pre/post-unpatch callbacks executed.  On
507# the other hand, when the atomic-replace livepatch is disabled, its
508# pre/post-unpatch callbacks *should* be executed.
509#
510# - Load and unload two livepatches, the second of which has its
511#   .replace flag set true.
512#
513# - Pre and post patch callbacks are executed for both livepatches.
514#
515# - Once the atomic replace module is loaded, only its pre and post
516#   unpatch callbacks are executed.
517
518start_test "atomic replace"
519
520load_lp $MOD_LIVEPATCH
521load_lp $MOD_LIVEPATCH2 replace=1
522disable_lp $MOD_LIVEPATCH2
523unload_lp $MOD_LIVEPATCH2
524unload_lp $MOD_LIVEPATCH
525
526check_result "% modprobe $MOD_LIVEPATCH
527livepatch: enabling patch '$MOD_LIVEPATCH'
528livepatch: '$MOD_LIVEPATCH': initializing patching transition
529$MOD_LIVEPATCH: pre_patch_callback: vmlinux
530livepatch: '$MOD_LIVEPATCH': starting patching transition
531livepatch: '$MOD_LIVEPATCH': completing patching transition
532$MOD_LIVEPATCH: post_patch_callback: vmlinux
533livepatch: '$MOD_LIVEPATCH': patching complete
534% modprobe $MOD_LIVEPATCH2 replace=1
535livepatch: enabling patch '$MOD_LIVEPATCH2'
536livepatch: '$MOD_LIVEPATCH2': initializing patching transition
537$MOD_LIVEPATCH2: pre_patch_callback: vmlinux
538livepatch: '$MOD_LIVEPATCH2': starting patching transition
539livepatch: '$MOD_LIVEPATCH2': completing patching transition
540$MOD_LIVEPATCH2: post_patch_callback: vmlinux
541livepatch: '$MOD_LIVEPATCH2': patching complete
542% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
543livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
544$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
545livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
546livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
547$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
548livepatch: '$MOD_LIVEPATCH2': unpatching complete
549% rmmod $MOD_LIVEPATCH2
550% rmmod $MOD_LIVEPATCH"
551
552
553exit 0
554