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