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 sleep_secs=0
360# give $MOD_TARGET_BUSY::busymod_work_func() a chance to run
361sleep 5
362load_lp $MOD_LIVEPATCH
363load_mod $MOD_TARGET
364unload_mod $MOD_TARGET
365disable_lp $MOD_LIVEPATCH
366unload_lp $MOD_LIVEPATCH
367unload_mod $MOD_TARGET_BUSY
368
369check_result "% modprobe $MOD_TARGET_BUSY sleep_secs=0
370$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
371$MOD_TARGET_BUSY: busymod_work_func, sleeping 0 seconds ...
372$MOD_TARGET_BUSY: busymod_work_func exit
373% modprobe $MOD_LIVEPATCH
374livepatch: enabling patch '$MOD_LIVEPATCH'
375livepatch: '$MOD_LIVEPATCH': initializing patching transition
376$MOD_LIVEPATCH: pre_patch_callback: vmlinux
377$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
378livepatch: '$MOD_LIVEPATCH': starting patching transition
379livepatch: '$MOD_LIVEPATCH': completing patching transition
380$MOD_LIVEPATCH: post_patch_callback: vmlinux
381$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
382livepatch: '$MOD_LIVEPATCH': patching complete
383% modprobe $MOD_TARGET
384livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
385$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
386$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
387$MOD_TARGET: ${MOD_TARGET}_init
388% rmmod $MOD_TARGET
389$MOD_TARGET: ${MOD_TARGET}_exit
390$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
391livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
392$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
393% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
394livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
395$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
396$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
397livepatch: '$MOD_LIVEPATCH': starting unpatching transition
398livepatch: '$MOD_LIVEPATCH': completing unpatching transition
399$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
400$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
401livepatch: '$MOD_LIVEPATCH': unpatching complete
402% rmmod $MOD_LIVEPATCH
403% rmmod $MOD_TARGET_BUSY
404$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
405
406
407
408# TEST: busy target module
409#
410# A similar test as the previous one, but force the "busy" kernel module
411# to do longer work.
412#
413# The livepatching core will refuse to patch a task that is currently
414# executing a to-be-patched function -- the consistency model stalls the
415# current patch transition until this safety-check is met.  Test a
416# scenario where one of a livepatch's target klp_objects sits on such a
417# function for a long time.  Meanwhile, load and unload other target
418# kernel modules while the livepatch transition is in progress.
419#
420# - Load the "busy" kernel module, this time make it do 10 seconds worth
421#   of work.
422#
423# - Meanwhile, the livepatch is loaded.  Notice that the patch
424#   transition does not complete as the targeted "busy" module is
425#   sitting on a to-be-patched function.
426#
427# - Load a second target module (this one is an ordinary idle kernel
428#   module).  Note that *no* post-patch callbacks will be executed while
429#   the livepatch is still in transition.
430#
431# - Request an unload of the simple kernel module.  The patch is still
432#   transitioning, so its pre-unpatch callbacks are skipped.
433#
434# - Finally the livepatch is disabled.  Since none of the patch's
435#   klp_object's post-patch callbacks executed, the remaining
436#   klp_object's pre-unpatch callbacks are skipped.
437
438echo -n "TEST: busy target module ... "
439dmesg -C
440
441load_mod $MOD_TARGET_BUSY sleep_secs=10
442load_lp_nowait $MOD_LIVEPATCH
443# Don't wait for transition, load $MOD_TARGET while the transition
444# is still stalled in $MOD_TARGET_BUSY::busymod_work_func()
445sleep 5
446load_mod $MOD_TARGET
447unload_mod $MOD_TARGET
448disable_lp $MOD_LIVEPATCH
449unload_lp $MOD_LIVEPATCH
450unload_mod $MOD_TARGET_BUSY
451
452check_result "% modprobe $MOD_TARGET_BUSY sleep_secs=10
453$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
454$MOD_TARGET_BUSY: busymod_work_func, sleeping 10 seconds ...
455% modprobe $MOD_LIVEPATCH
456livepatch: enabling patch '$MOD_LIVEPATCH'
457livepatch: '$MOD_LIVEPATCH': initializing patching transition
458$MOD_LIVEPATCH: pre_patch_callback: vmlinux
459$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
460livepatch: '$MOD_LIVEPATCH': starting patching transition
461% modprobe $MOD_TARGET
462livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
463$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
464$MOD_TARGET: ${MOD_TARGET}_init
465% rmmod $MOD_TARGET
466$MOD_TARGET: ${MOD_TARGET}_exit
467livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
468$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
469% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
470livepatch: '$MOD_LIVEPATCH': reversing transition from patching to unpatching
471livepatch: '$MOD_LIVEPATCH': starting unpatching transition
472livepatch: '$MOD_LIVEPATCH': completing unpatching transition
473$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
474$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
475livepatch: '$MOD_LIVEPATCH': unpatching complete
476% rmmod $MOD_LIVEPATCH
477% rmmod $MOD_TARGET_BUSY
478$MOD_TARGET_BUSY: busymod_work_func exit
479$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
480
481
482# TEST: multiple livepatches
483#
484# Test loading multiple livepatches.  This test-case is mainly for comparing
485# with the next test-case.
486#
487# - Load and unload two livepatches, pre and post (un)patch callbacks
488#   execute as each patch progresses through its (un)patching
489#   transition.
490
491echo -n "TEST: multiple livepatches ... "
492dmesg -C
493
494load_lp $MOD_LIVEPATCH
495load_lp $MOD_LIVEPATCH2
496disable_lp $MOD_LIVEPATCH2
497disable_lp $MOD_LIVEPATCH
498unload_lp $MOD_LIVEPATCH2
499unload_lp $MOD_LIVEPATCH
500
501check_result "% modprobe $MOD_LIVEPATCH
502livepatch: enabling patch '$MOD_LIVEPATCH'
503livepatch: '$MOD_LIVEPATCH': initializing patching transition
504$MOD_LIVEPATCH: pre_patch_callback: vmlinux
505livepatch: '$MOD_LIVEPATCH': starting patching transition
506livepatch: '$MOD_LIVEPATCH': completing patching transition
507$MOD_LIVEPATCH: post_patch_callback: vmlinux
508livepatch: '$MOD_LIVEPATCH': patching complete
509% modprobe $MOD_LIVEPATCH2
510livepatch: enabling patch '$MOD_LIVEPATCH2'
511livepatch: '$MOD_LIVEPATCH2': initializing patching transition
512$MOD_LIVEPATCH2: pre_patch_callback: vmlinux
513livepatch: '$MOD_LIVEPATCH2': starting patching transition
514livepatch: '$MOD_LIVEPATCH2': completing patching transition
515$MOD_LIVEPATCH2: post_patch_callback: vmlinux
516livepatch: '$MOD_LIVEPATCH2': patching complete
517% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
518livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
519$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
520livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
521livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
522$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
523livepatch: '$MOD_LIVEPATCH2': unpatching complete
524% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
525livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
526$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
527livepatch: '$MOD_LIVEPATCH': starting unpatching transition
528livepatch: '$MOD_LIVEPATCH': completing unpatching transition
529$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
530livepatch: '$MOD_LIVEPATCH': unpatching complete
531% rmmod $MOD_LIVEPATCH2
532% rmmod $MOD_LIVEPATCH"
533
534
535# TEST: atomic replace
536#
537# Load multiple livepatches, but the second as an 'atomic-replace'
538# patch.  When the latter loads, the original livepatch should be
539# disabled and *none* of its pre/post-unpatch callbacks executed.  On
540# the other hand, when the atomic-replace livepatch is disabled, its
541# pre/post-unpatch callbacks *should* be executed.
542#
543# - Load and unload two livepatches, the second of which has its
544#   .replace flag set true.
545#
546# - Pre and post patch callbacks are executed for both livepatches.
547#
548# - Once the atomic replace module is loaded, only its pre and post
549#   unpatch callbacks are executed.
550
551echo -n "TEST: atomic replace ... "
552dmesg -C
553
554load_lp $MOD_LIVEPATCH
555load_lp $MOD_LIVEPATCH2 replace=1
556disable_lp $MOD_LIVEPATCH2
557unload_lp $MOD_LIVEPATCH2
558unload_lp $MOD_LIVEPATCH
559
560check_result "% modprobe $MOD_LIVEPATCH
561livepatch: enabling patch '$MOD_LIVEPATCH'
562livepatch: '$MOD_LIVEPATCH': initializing patching transition
563$MOD_LIVEPATCH: pre_patch_callback: vmlinux
564livepatch: '$MOD_LIVEPATCH': starting patching transition
565livepatch: '$MOD_LIVEPATCH': completing patching transition
566$MOD_LIVEPATCH: post_patch_callback: vmlinux
567livepatch: '$MOD_LIVEPATCH': patching complete
568% modprobe $MOD_LIVEPATCH2 replace=1
569livepatch: enabling patch '$MOD_LIVEPATCH2'
570livepatch: '$MOD_LIVEPATCH2': initializing patching transition
571$MOD_LIVEPATCH2: pre_patch_callback: vmlinux
572livepatch: '$MOD_LIVEPATCH2': starting patching transition
573livepatch: '$MOD_LIVEPATCH2': completing patching transition
574$MOD_LIVEPATCH2: post_patch_callback: vmlinux
575livepatch: '$MOD_LIVEPATCH2': patching complete
576% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
577livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
578$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
579livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
580livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
581$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
582livepatch: '$MOD_LIVEPATCH2': unpatching complete
583% rmmod $MOD_LIVEPATCH2
584% rmmod $MOD_LIVEPATCH"
585
586
587exit 0
588