Skip to contentSkip to conversation

Add livepatch kselftests

PATCH Superseded Joe Lawrence 6 participants 13 messages Apr 10, 2018 – Apr 17, 2018

Subsystems (4)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Joe Lawrence

author maintainer
#0 lore raw

PATCH v2 1/1 Add livepatch kselftests

Round two cleans up a few misc script and build items, adds a shadow variable test, and reduces the total livepatch kselftest runtime to ~45 seconds.

The tests run on top of Petr's v11 atomic replace feature and v2 of the shadow variable enhancement patchsets:

[PATCH 0/8] livepatch: Atomic replace feature
https://lkml.kernel.org/r/20180323120028.31451-1-pmladek at suse.com

[PATCH v2 0/2] livepatch: Allocate and free shadow variables more safely
https://lkml.kernel.org/r/20180405122315.29065-1-pmladek at suse.com

Questions for v3:

- Should we split off the atomic replace and shadow variable update tests so that the this patchset could be merged before the ones listed above?

- I didn't remove any of the sample modules. If anyone thinks any of them should go, let me know. They serve as nice, simple examples so I thought they should all stay.

- Module naming convention: to make the test script easier to grep module names and filenames, I broke with livepatch convention and used underscores instead of dashes. I didn't think it worth the regex foo to flip back and forth in the test script.

- More tests from Libor and Nicolai would be welcome!
-- Maybe we separate quicktests (like these) from longer tests if
needed?

Here's a sample output from a successful test run:

% time make -C tools/testing/selftests TARGETS=livepatch run_tests
make: Entering directory /root/linux/tools/testing/selftests' make[1]: Entering directory /root/linux/tools/testing/selftests/livepatch' make[1]: Nothing to be done for `all'.
make[1]: Leaving directory /root/linux/tools/testing/selftests/livepatch' make[1]: Entering directory /root/linux/tools/testing/selftests/livepatch' TAP version 13
selftests: test-livepatch.sh
========================================
TEST: basic function patching ... ok
TEST: multiple livepatches ... ok
TEST: atomic replace livepatch ... ok
ok 1..1 selftests: test-livepatch.sh [PASS]
selftests: test-callbacks.sh
========================================
TEST: target module before livepatch ... ok
TEST: module_coming notifier ... ok
TEST: module_going notifier ... ok
TEST: module_coming and module_going notifiers ... ok
TEST: target module not present ... ok
TEST: pre-patch callback -ENODEV ... ok
TEST: module_coming + pre-patch callback -ENODEV ... ok
TEST: multiple target modules ... ok
TEST: busy target module ... ok
TEST: multiple livepatches ... ok
TEST: atomic replace ... ok
ok 1..2 selftests: test-callbacks.sh [PASS]
selftests: test-shadow-vars.sh
========================================
TEST: basic shadow variable API ... ok
ok 1..3 selftests: test-shadow-vars.sh [PASS]
make[1]: Leaving directory `/root/linux/tools/testing/selftests/livepatch'
make: Leaving directory `/root/linux/tools/testing/selftests'

  real    0m46.166s
  user    0m0.436s
  sys     0m1.244s

changes from v1:
- Only add $(CC_FLAGS_FTRACE) for target modules
- Remove between test delay
- Reduce RETRY_INTERVAL to .1 sec
- Reduce test_callback_mod's busymod_work_func delay from 60 to 10 sec
- s/PASS/ok and s/FAIL/not ok for test output
- Move test descriptions from Documentation/livepatch/callbacks.txt into tools/testing/selftests/livepatch/test-callbacks.sh
- Add a shadow variable test script and module
- Add a short tools/testing/selftests/livepatch/README
- to += linux-kselftest at vger.kernel.org
- cc += Libor, Nicolai, Artem

change from rfc:
- SPDX-License-Identifiers
- Moved livepatch test modules into lib/livepatch
- Renamed livepatch.sh (filename suffix)
- Reduced between-test delay time
- Split off common functions.sh file
- Split into separate livepatch, callbacks, and shadow-vars scrips
- Gave the tests short descriptions instead of TEST1, TEST2, etc.

Joe Lawrence (1):
selftests/livepatch: introduce tests

 Documentation/livepatch/callbacks.txt              | 487 -----------------
 lib/Kconfig.debug                                  |  12 +
 lib/Makefile                                       |   2 +
 lib/livepatch/Makefile                             |  15 +
 lib/livepatch/test_klp_atomic_replace.c            |  69 +++
 lib/livepatch/test_klp_callbacks_busy.c            |  43 ++
 lib/livepatch/test_klp_callbacks_demo.c            | 132 +++++
 lib/livepatch/test_klp_callbacks_demo2.c           | 104 ++++
 lib/livepatch/test_klp_callbacks_mod.c             |  24 +
 lib/livepatch/test_klp_livepatch.c                 |  62 +++
 lib/livepatch/test_klp_shadow_vars.c               | 235 ++++++++
 tools/testing/selftests/Makefile                   |   1 +
 tools/testing/selftests/livepatch/Makefile         |   8 +
 tools/testing/selftests/livepatch/config           |   1 +
 tools/testing/selftests/livepatch/functions.sh     | 196 +++++++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +++++++++++++++++++++
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++++++
 .../selftests/livepatch/test-shadow-vars.sh        |  60 ++
 18 files changed, 1744 insertions(+), 487 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

--
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

author maintainer
#1 lore raw

PATCH v2 1/1 selftests/livepatch: introduce tests

Add a few livepatch modules and simple target modules that the included regression suite can run tests against.

Signed-off-by Joe Lawrence <joe.lawrence at redhat.com>
---
 Documentation/livepatch/callbacks.txt              | 487 -----------------
 lib/Kconfig.debug                                  |  12 +
 lib/Makefile                                       |   2 +
 lib/livepatch/Makefile                             |  15 +
 lib/livepatch/test_klp_atomic_replace.c            |  69 +++
 lib/livepatch/test_klp_callbacks_busy.c            |  43 ++
 lib/livepatch/test_klp_callbacks_demo.c            | 132 +++++
 lib/livepatch/test_klp_callbacks_demo2.c           | 104 ++++
 lib/livepatch/test_klp_callbacks_mod.c             |  24 +
 lib/livepatch/test_klp_livepatch.c                 |  62 +++
 lib/livepatch/test_klp_shadow_vars.c               | 235 ++++++++
 tools/testing/selftests/Makefile                   |   1 +
 tools/testing/selftests/livepatch/Makefile         |   8 +
 tools/testing/selftests/livepatch/config           |   1 +
 tools/testing/selftests/livepatch/functions.sh     | 196 +++++++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +++++++++++++++++++++
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++++++
 .../selftests/livepatch/test-shadow-vars.sh        |  60 ++
 18 files changed, 1744 insertions(+), 487 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh
Documentation/livepatch/callbacks.txt +0 -487
index c9776f48e458..6ca2801a6bb9 100644
@@ -116,490 +116,3 @@ virtnet_probe() initialized its driver's net_device features.  A
 pre/post-patch callback could iterate over all such devices, making a
 similar change to their hw_features value.  (Client functions of the
 value may need to be updated accordingly.)
-
-
-Test cases
-==========
-
-What follows is not an exhaustive test suite of every possible livepatch
-pre/post-(un)patch combination, but a selection that demonstrates a few
-important concepts.  Each test case uses the kernel modules located in
-the samples/livepatch/ and assumes that no livepatches are loaded at the
-beginning of the test.
-
-
-Test 1
-------
-
-Test a combination of loading a kernel module and a livepatch that
-patches a function in the first module.  (Un)load the target module
-before the livepatch module:
-
-- load target module
-- load livepatch
-- disable livepatch
-- unload target module
-- unload livepatch
-
-First load a target module:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   34.475708] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-On livepatch enable, before the livepatch transition starts, pre-patch
-callbacks are executed for vmlinux and livepatch_callbacks_mod (those
-klp_objects currently loaded).  After klp_objects are patched according
-to the klp_patch, their post-patch callbacks run and the transition
-completes:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   36.503719] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   36.504213] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   36.504238] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   36.504721] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   36.505849] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   37.727133] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   37.727232] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   37.727860] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   37.728792] livepatch: 'livepatch_callbacks_demo': patching complete
-
-Similarly, on livepatch disable, pre-patch callbacks run before the
-unpatching transition starts.  klp_objects are reverted, post-patch
-callbacks execute and the transition completes:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   38.510209] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   38.510234] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   38.510982] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   38.512209] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   39.711132] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   39.711210] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   39.711779] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   39.712735] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   42.534183] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-
-
-Test 2
-------
-
-This test is similar to the previous test, but (un)load the livepatch
-module before the target kernel module.  This tests the livepatch core's
-module_coming handler:
-
-- load livepatch
-- load target module
-- disable livepatch
-- unload livepatch
-- unload target module
-
-
-On livepatch enable, only pre/post-patch callbacks are executed for
-currently loaded klp_objects, in this case, vmlinux:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   44.553328] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   44.553997] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   44.554049] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   44.554845] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   45.727128] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   45.727212] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   45.727961] livepatch: 'livepatch_callbacks_demo': patching complete
-
-When a targeted module is subsequently loaded, only its pre/post-patch
-callbacks are executed:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   46.560845] livepatch: applying patch 'livepatch_callbacks_demo' to loading module 'livepatch_callbacks_mod'
-  [   46.561988] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [   46.563452] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [   46.565495] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-On livepatch disable, all currently loaded klp_objects' (vmlinux and
-livepatch_callbacks_mod) pre/post-unpatch callbacks are executed:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   48.568885] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   48.568910] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   48.569441] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   48.570502] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   49.759091] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   49.759171] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   49.759742] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   49.760690] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   52.592283] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-
-
-Test 3
-------
-
-Test loading the livepatch after a targeted kernel module, then unload
-the kernel module before disabling the livepatch.  This tests the
-livepatch core's module_going handler:
-
-- load target module
-- load livepatch
-- unload target module
-- disable livepatch
-- unload livepatch
-
-First load a target module, then the livepatch:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   54.607948] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   56.613919] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   56.614411] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   56.614436] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   56.614818] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   56.615656] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   57.759070] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   57.759147] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   57.759621] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   57.760307] livepatch: 'livepatch_callbacks_demo': patching complete
-
-When a target module is unloaded, the livepatch is only reverted from
-that klp_object (livepatch_callbacks_mod).  As such, only its pre and
-post-unpatch callbacks are executed when this occurs:
-
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   58.623409] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-  [   58.623903] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-  [   58.624658] livepatch: reverting patch 'livepatch_callbacks_demo' on unloading module 'livepatch_callbacks_mod'
-  [   58.625305] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-
-When the livepatch is disabled, pre and post-unpatch callbacks are run
-for the remaining klp_object, vmlinux:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   60.638420] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   60.638444] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   60.638996] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   61.727088] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   61.727165] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   61.727985] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-
-
-Test 4
-------
-
-This test is similar to the previous test, however the livepatch is
-loaded first.  This tests the livepatch core's module_coming and
-module_going handlers:
-
-- load livepatch
-- load target module
-- unload target module
-- disable livepatch
-- unload livepatch
-
-First load the livepatch:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   64.661552] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   64.662147] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   64.662175] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   64.662850] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   65.695056] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   65.695147] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   65.695561] livepatch: 'livepatch_callbacks_demo': patching complete
-
-When a targeted kernel module is subsequently loaded, only its
-pre/post-patch callbacks are executed:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   66.669196] livepatch: applying patch 'livepatch_callbacks_demo' to loading module 'livepatch_callbacks_mod'
-  [   66.669882] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [   66.670744] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [   66.672873] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-When the target module is unloaded, the livepatch is only reverted from
-the livepatch_callbacks_mod klp_object.  As such, only pre and
-post-unpatch callbacks are executed when this occurs:
-
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   68.680065] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-  [   68.680688] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-  [   68.681452] livepatch: reverting patch 'livepatch_callbacks_demo' on unloading module 'livepatch_callbacks_mod'
-  [   68.682094] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   70.689225] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   70.689256] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   70.689882] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   71.711080] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   71.711481] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   71.711988] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-
-
-Test 5
-------
-
-A simple test of loading a livepatch without one of its patch target
-klp_objects ever loaded (livepatch_callbacks_mod):
-
-- load livepatch
-- disable livepatch
-- unload livepatch
-
-Load the livepatch:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   74.711081] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   74.711595] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   74.711639] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   74.712272] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   75.743137] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   75.743219] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   75.743867] livepatch: 'livepatch_callbacks_demo': patching complete
-
-As expected, only pre/post-(un)patch handlers are executed for vmlinux:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   76.716254] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   76.716278] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   76.716666] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   77.727089] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   77.727194] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   77.727907] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-
-
-Test 6
-------
-
-Test a scenario where a vmlinux pre-patch callback returns a non-zero
-status (ie, failure):
-
-- load target module
-- load livepatch -ENODEV
-- unload target module
-
-First load a target module:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   80.740520] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-Load the livepatch module, setting its 'pre_patch_ret' value to -19
-(-ENODEV).  When its vmlinux pre-patch callback executed, this status
-code will propagate back to the module-loading subsystem.  The result is
-that the insmod command refuses to load the livepatch module:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko pre_patch_ret=-19
-  [   82.747326] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   82.747743] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   82.747767] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   82.748237] livepatch: pre-patch callback failed for object 'vmlinux'
-  [   82.748637] livepatch: failed to enable patch 'livepatch_callbacks_demo'
-  [   82.749059] livepatch: 'livepatch_callbacks_demo': canceling transition, going to unpatch
-  [   82.749060] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   82.749868] livepatch: 'livepatch_callbacks_demo': unpatching complete
-  [   82.765809] insmod: ERROR: could not insert module samples/livepatch/livepatch-callbacks-demo.ko: No such device
-
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   84.774238] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-
-
-Test 7
-------
-
-Similar to the previous test, setup a livepatch such that its vmlinux
-pre-patch callback returns success.  However, when a targeted kernel
-module is later loaded, have the livepatch return a failing status code:
-
-- load livepatch
-- setup -ENODEV
-- load target module
-- disable livepatch
-- unload livepatch
-
-Load the livepatch, notice vmlinux pre-patch callback succeeds:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   86.787845] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   86.788325] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   86.788427] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   86.788821] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   87.711069] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   87.711143] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   87.711886] livepatch: 'livepatch_callbacks_demo': patching complete
-
-Set a trap so subsequent pre-patch callbacks to this livepatch will
-return -ENODEV:
-
-  % echo -19 > /sys/module/livepatch_callbacks_demo/parameters/pre_patch_ret
-
-The livepatch pre-patch callback for subsequently loaded target modules
-will return failure, so the module loader refuses to load the kernel
-module.  Notice that no post-patch or pre/post-unpatch callbacks are
-executed for this klp_object:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   90.796976] livepatch: applying patch 'livepatch_callbacks_demo' to loading module 'livepatch_callbacks_mod'
-  [   90.797834] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [   90.798900] livepatch: pre-patch callback failed for object 'livepatch_callbacks_mod'
-  [   90.799652] livepatch: patch 'livepatch_callbacks_demo' failed for module 'livepatch_callbacks_mod', refusing to load module 'livepatch_callbacks_mod'
-  [   90.819737] insmod: ERROR: could not insert module samples/livepatch/livepatch-callbacks-mod.ko: No such device
-
-However, pre/post-unpatch callbacks run for the vmlinux klp_object:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   92.823547] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [   92.823573] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [   92.824331] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [   93.727128] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [   93.727327] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [   93.727861] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-
-
-Test 8
-------
-
-Test loading multiple targeted kernel modules.  This test-case is
-mainly for comparing with the next test-case.
-
-- load busy target module (0s sleep),
-- load livepatch
-- load target module
-- unload target module
-- disable livepatch
-- unload livepatch
-- unload busy target module
-
-
-Load a target "busy" kernel module which kicks off a worker function
-that immediately exits:
-
-  % insmod samples/livepatch/livepatch-callbacks-busymod.ko sleep_secs=0
-  [   96.910107] livepatch_callbacks_busymod: livepatch_callbacks_mod_init
-  [   96.910600] livepatch_callbacks_busymod: busymod_work_func, sleeping 0 seconds ...
-  [   96.913024] livepatch_callbacks_busymod: busymod_work_func exit
-
-Proceed with loading the livepatch and another ordinary target module,
-notice that the post-patch callbacks are executed and the transition
-completes quickly:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   98.917892] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   98.918426] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [   98.918453] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   98.918955] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [   98.923835] livepatch: 'livepatch_callbacks_demo': starting patching transition
-  [   99.743104] livepatch: 'livepatch_callbacks_demo': completing patching transition
-  [   99.743156] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   99.743679] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [   99.744616] livepatch: 'livepatch_callbacks_demo': patching complete
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [  100.930955] livepatch: applying patch 'livepatch_callbacks_demo' to loading module 'livepatch_callbacks_mod'
-  [  100.931668] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [  100.932645] livepatch_callbacks_demo: post_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [  100.934125] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [  102.942805] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-  [  102.943640] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-  [  102.944585] livepatch: reverting patch 'livepatch_callbacks_demo' on unloading module 'livepatch_callbacks_mod'
-  [  102.945455] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [  104.953815] livepatch: 'livepatch_callbacks_demo': initializing unpatching transition
-  [  104.953838] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
-  [  104.954431] livepatch_callbacks_demo: pre_unpatch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [  104.955426] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [  106.719073] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [  106.722633] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [  106.723282] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [  106.724279] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-  % rmmod samples/livepatch/livepatch-callbacks-busymod.ko
-  [  108.975660] livepatch_callbacks_busymod: livepatch_callbacks_mod_exit
-
-
-Test 9
-------
-
-A similar test as the previous one, but force the "busy" kernel module
-to do longer work.
-
-The livepatching core will refuse to patch a task that is currently
-executing a to-be-patched function -- the consistency model stalls the
-current patch transition until this safety-check is met.  Test a
-scenario where one of a livepatch's target klp_objects sits on such a
-function for a long time.  Meanwhile, load and unload other target
-kernel modules while the livepatch transition is in progress.
-
-- load busy target module (30s sleep)
-- load livepatch
-- load target module
-- unload target module
-- disable livepatch
-- unload livepatch
-- unload busy target module
-
-
-Load the "busy" kernel module, this time make it do 30 seconds worth of
-work:
-
-  % insmod samples/livepatch/livepatch-callbacks-busymod.ko sleep_secs=30
-  [  110.993362] livepatch_callbacks_busymod: livepatch_callbacks_mod_init
-  [  110.994059] livepatch_callbacks_busymod: busymod_work_func, sleeping 30 seconds ...
-
-Meanwhile, the livepatch is loaded.  Notice that the patch transition
-does not complete as the targeted "busy" module is sitting on a
-to-be-patched function:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [  113.000309] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [  113.000764] livepatch: 'livepatch_callbacks_demo': initializing patching transition
-  [  113.000791] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [  113.001289] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [  113.005208] livepatch: 'livepatch_callbacks_demo': starting patching transition
-
-Load a second target module (this one is an ordinary idle kernel
-module).  Note that *no* post-patch callbacks will be executed while the
-livepatch is still in transition:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [  115.012740] livepatch: applying patch 'livepatch_callbacks_demo' to loading module 'livepatch_callbacks_mod'
-  [  115.013406] livepatch_callbacks_demo: pre_patch_callback: livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running module_init
-  [  115.015315] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-Request an unload of the simple kernel module.  The patch is still
-transitioning, so its pre-unpatch callbacks are skipped:
-
-  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
-  [  117.022626] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
-  [  117.023376] livepatch: reverting patch 'livepatch_callbacks_demo' on unloading module 'livepatch_callbacks_mod'
-  [  117.024533] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_mod -> [MODULE_STATE_GOING] Going away
-
-Finally the livepatch is disabled.  Since none of the patch's
-klp_object's post-patch callbacks executed, the remaining klp_object's
-pre-unpatch callbacks are skipped:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [  119.035408] livepatch: 'livepatch_callbacks_demo': reversing transition from patching to unpatching
-  [  119.035485] livepatch: 'livepatch_callbacks_demo': starting unpatching transition
-  [  119.711166] livepatch: 'livepatch_callbacks_demo': completing unpatching transition
-  [  119.714179] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
-  [  119.714653] livepatch_callbacks_demo: post_unpatch_callback: livepatch_callbacks_busymod -> [MODULE_STATE_LIVE] Normal state
-  [  119.715437] livepatch: 'livepatch_callbacks_demo': unpatching complete
-
-  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
-  % rmmod samples/livepatch/livepatch-callbacks-busymod.ko
-  [  141.279111] livepatch_callbacks_busymod: busymod_work_func exit
-  [  141.279760] livepatch_callbacks_busymod: livepatch_callbacks_mod_exit
lib/Kconfig.debug +12 -0
index 64155e310a9f..e4a0e81542ff 100644
@@ -1932,6 +1932,18 @@ config TEST_DEBUG_VIRTUAL
 
 	  If unsure, say N.
 
+config TEST_LIVEPATCH
+	tristate "Test livepatching"
+	default n
+	depends on LIVEPATCH
+	depends on m
+	help
+	  Test various kernel livepatching features for correctness.
+	  The tests will load test modules that will be livepatched
+	  in various scenarios.
+
+	  If unsure, say N.
+
 endif # RUNTIME_TESTING_MENU
 
 config MEMTEST
lib/Makefile +2 -0
index a90d4fcd748f..98a38441afb0 100644
@@ -67,6 +67,8 @@ obj-$(CONFIG_TEST_PARMAN) += test_parman.o
 obj-$(CONFIG_TEST_KMOD) += test_kmod.o
 obj-$(CONFIG_TEST_DEBUG_VIRTUAL) += test_debug_virtual.o
 
+obj-$(CONFIG_TEST_LIVEPATCH) += livepatch/
+
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
 CFLAGS_kobject_uevent.o += -DDEBUG
lib/livepatch/Makefile new file +15 -0
new file mode 100644
index 000000000000..26900ddaef82
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for livepatch test code.
+
+obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_atomic_replace.o \
+				test_klp_callbacks_demo.o \
+				test_klp_callbacks_demo2.o \
+				test_klp_callbacks_busy.o \
+				test_klp_callbacks_mod.o \
+				test_klp_livepatch.o \
+				test_klp_shadow_vars.o
+
+# Target modules to be livepatched require CC_FLAGS_FTRACE
+CFLAGS_test_klp_callbacks_busy.o	+= $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_mod.o		+= $(CC_FLAGS_FTRACE)
lib/livepatch/test_klp_atomic_replace.c new file +69 -0

69 lines not on this page · raw message

lib/livepatch/test_klp_callbacks_busy.c new file +43 -0

43 lines not on this page · raw message

lib/livepatch/test_klp_callbacks_demo.c new file +132 -0

132 lines not on this page · raw message

lib/livepatch/test_klp_callbacks_demo2.c new file +104 -0

104 lines not on this page · raw message

lib/livepatch/test_klp_callbacks_mod.c new file +24 -0
new file mode 100644
index 000000000000..8fbe645b1c2c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Joe Lawrence <joe.lawrence at redhat.com>
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int test_klp_callbacks_mod_init(void)
+{
+	pr_info("%s\n", __func__);
+	return 0;
+}
+
+static void test_klp_callbacks_mod_exit(void)
+{
+	pr_info("%s\n", __func__);
+}
+
+module_init(test_klp_callbacks_mod_init);
+module_exit(test_klp_callbacks_mod_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joe Lawrence <joe.lawrence at redhat.com>");
+MODULE_DESCRIPTION("Livepatch test: target module");
lib/livepatch/test_klp_livepatch.c new file +62 -0

62 lines not on this page · raw message

lib/livepatch/test_klp_shadow_vars.c new file +235 -0

235 lines not on this page · raw message

tools/testing/selftests/Makefile +1 -0
index 7442dfb73b7f..d92c63bde9b6 100644
@@ -15,6 +15,7 @@ TARGETS += intel_pstate
 TARGETS += ipc
 TARGETS += kcmp
 TARGETS += lib
+TARGETS += livepatch
 TARGETS += membarrier
 TARGETS += memfd
 TARGETS += memory-hotplug
tools/testing/selftests/livepatch/Makefile new file +8 -0
new file mode 100644
index 000000000000..af4aee79bebb
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+TEST_GEN_PROGS := \
+	test-livepatch.sh \
+	test-callbacks.sh \
+	test-shadow-vars.sh
+
+include ../lib.mk
tools/testing/selftests/livepatch/config new file +1 -0
new file mode 100644
index 000000000000..0dd7700464a8
@@ -0,0 +1 @@
+CONFIG_TEST_LIVEPATCH=m
tools/testing/selftests/livepatch/functions.sh new file +196 -0

196 lines not on this page · raw message

tools/testing/selftests/livepatch/test-callbacks.sh new file +607 -0

607 lines not on this page · raw message

tools/testing/selftests/livepatch/test-livepatch.sh new file +173 -0

173 lines not on this page · raw message

tools/testing/selftests/livepatch/test-shadow-vars.sh new file +60 -0

60 lines not on this page · raw message

Signature · 6 lines
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw

Re: [PATCH v2] selftests/livepatch: introduce tests

lib/livepatch/test_klp_shadow_vars.c line 232

Quoted 6 lines · Joe Lawrence
lib/livepatch/test_klp_shadow_vars.c new file +6 -0
+static void test_klp_shadow_vars_exit(void)
+{
+}
+
+module_init(test_klp_shadow_vars_init);
+module_init(test_klp_shadow_vars_exit);

For this last line, s/module_init/module_exit/, though I think the exit function can just be removed altogether?

Also I get the following bug (run on latest Linus master + Petr's two patch sets):

[  106.302072] % modprobe test_klp_shadow_vars
[  106.311165] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = PTR0
[  106.313080] test_klp_shadow_vars:   got expected NULL result
[  106.314811] BUG: sleeping function called from invalid context at mm/slab.h:421
[  106.316518] in_atomic(): 1, irqs_disabled(): 1, pid: 2254, name: modprobe
[  106.318107] 1 lock held by modprobe/2254:
[  106.319332]  #0: 00000000d0851080 (klp_shadow_lock){....}, at: __klp_shadow_get_or_alloc+0x88/0x1b0
[  106.321220] irq event stamp: 4408
[  106.322176] hardirqs last  enabled at (4407): [<ffffffff8114c28e>] console_unlock+0x44e/0x680
[  106.323598] hardirqs last disabled at (4408): [<ffffffff8199e6c7>] _raw_spin_lock_irqsave+0x27/0x90
[  106.325041] softirqs last  enabled at (4404): [<ffffffff81c0039b>] __do_softirq+0x39b/0x4fc
[  106.326469] softirqs last disabled at (4367): [<ffffffff810d8450>] irq_exit+0xe0/0xf0
[  106.327901] Preemption disabled at:
[  106.327905] [<ffffffff81167c28>] __klp_shadow_get_or_alloc+0x88/0x1b0
[  106.330117] CPU: 7 PID: 2254 Comm: modprobe Tainted: G              K  4.16.0+ #60
[  106.331565] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
[  106.333143] Call Trace:
[  106.334011]  dump_stack+0x8e/0xd5
[  106.334962]  ___might_sleep+0x185/0x260
[  106.335997]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.337170]  __might_sleep+0x4a/0x80
[  106.338137]  kmem_cache_alloc_trace+0x20b/0x300
[  106.339183]  ? ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
[  106.340341]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.341506]  ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
[  106.342725]  shadow_ctor+0x20/0x40 [test_klp_shadow_vars]
[  106.343998]  __klp_shadow_get_or_alloc+0xc4/0x1b0
[  106.345184]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.346494]  klp_shadow_alloc+0x10/0x20
[  106.347583]  shadow_alloc+0x28/0xa0 [test_klp_shadow_vars]
[  106.348871]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
[  106.350200]  test_klp_shadow_vars_init+0x96/0x400 [test_klp_shadow_vars]
[  106.351646]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
[  106.352949]  do_one_initcall+0x61/0x37f
[  106.353963]  ? rcu_read_lock_sched_held+0x79/0x80
[  106.355040]  ? kmem_cache_alloc_trace+0x29d/0x300
[  106.356098]  ? do_init_module+0x27/0x213
[  106.357090]  do_init_module+0x5f/0x213
[  106.358047]  load_module+0x2815/0x2e70
[  106.358992]  ? vfs_read+0x12d/0x150
[  106.359920]  SYSC_finit_module+0xfc/0x120
[  106.360870]  ? SYSC_finit_module+0xfc/0x120
[  106.361839]  SyS_finit_module+0xe/0x10
[  106.362753]  do_syscall_64+0x7e/0x240
[  106.363645]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
[  106.364711] RIP: 0033:0x7f26d0d40b19
[  106.365799] RSP: 002b:00007ffee1de19a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[  106.367306] RAX: ffffffffffffffda RBX: 00005636550d54b0 RCX: 00007f26d0d40b19
[  106.368573] RDX: 0000000000000000 RSI: 0000563654134186 RDI: 0000000000000003
[  106.369950] RBP: 0000563654134186 R08: 0000000000000000 R09: 00005636550d4270
[  106.371164] R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
[  106.372422] R13: 00005636550d53b0 R14: 0000000000040000 R15: 00005636550d54b0
[  106.373900] test_klp_shadow_vars: shadow_ctor: PTR6 -> PTR1
[  106.375249] test_klp_shadow_vars: klp_shadow_alloc(obj=PTR5, id=0x1234, size=8, gfp_flags=GFP_KERNEL), ctor=PTR7, ctor_data=PTR1 = PTR6
[  106.378893] test_klp_shadow_vars: shadow_ctor: PTR8 -> PTR2
[  106.380305] test_klp_shadow_vars: klp_shadow_alloc(obj=PTR9, id=0x1234, size=8, gfp_flags=GFP_KERNEL), ctor=PTR7, ctor_data=PTR2 = PTR8
[  106.382779] test_klp_shadow_vars: shadow_ctor: PTR10 -> PTR3
[  106.384131] test_klp_shadow_vars: klp_shadow_alloc(obj=PTR5, id=0x1235, size=8, gfp_flags=GFP_KERNEL), ctor=PTR7, ctor_data=PTR3 = PTR10
[  106.386584] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = PTR6
[  106.387929] test_klp_shadow_vars:   got expected PTR6 -> PTR1 result
[  106.389181] test_klp_shadow_vars: klp_shadow_get(obj=PTR9, id=0x1234) = PTR8
[  106.390488] test_klp_shadow_vars:   got expected PTR8 -> PTR2 result
[  106.391731] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1235) = PTR10
[  106.393066] test_klp_shadow_vars:   got expected PTR10 -> PTR3 result
[  106.394347] test_klp_shadow_vars: shadow_ctor: PTR11 -> PTR4
[  106.395523] test_klp_shadow_vars: klp_shadow_get_or_alloc(obj=PTR12, id=0x1234, size=8, gfp_flags=GFP_KERNEL), ctor=PTR7, ctor_data=PTR4 = PTR11
[  106.398033] test_klp_shadow_vars: klp_shadow_get_or_alloc(obj=PTR12, id=0x1234, size=8, gfp_flags=GFP_KERNEL), ctor=PTR7, ctor_data=PTR4 = PTR11
[  106.400554] test_klp_shadow_vars:   got expected PTR11 -> PTR4 result
[  106.401937] test_klp_shadow_vars: shadow_dtor(obj=PTR5, shadow_data=PTR6)
[  106.403592] test_klp_shadow_vars: klp_shadow_free(obj=PTR5, id=0x1234, dtor=PTR13)
[  106.405083] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = PTR0
[  106.406500] test_klp_shadow_vars:   got expected NULL result
[  106.407735] test_klp_shadow_vars: shadow_dtor(obj=PTR9, shadow_data=PTR8)
[  106.409252] test_klp_shadow_vars: klp_shadow_free(obj=PTR9, id=0x1234, dtor=PTR13)
[  106.410867] test_klp_shadow_vars: klp_shadow_get(obj=PTR9, id=0x1234) = PTR0
[  106.412232] test_klp_shadow_vars:   got expected NULL result
[  106.413461] test_klp_shadow_vars: shadow_dtor(obj=PTR12, shadow_data=PTR11)
[  106.414888] test_klp_shadow_vars: klp_shadow_free(obj=PTR12, id=0x1234, dtor=PTR13)
[  106.416319] test_klp_shadow_vars: klp_shadow_get(obj=PTR12, id=0x1234) = PTR0
[  106.417681] test_klp_shadow_vars:   got expected NULL result
[  106.418947] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1235) = PTR10
[  106.420314] test_klp_shadow_vars:   got expected PTR10 -> PTR3 result
[  106.421658] test_klp_shadow_vars: shadow_dtor(obj=PTR5, shadow_data=PTR10)
[  106.423065] test_klp_shadow_vars: klp_shadow_free_all(id=0x1235, dtor=PTR13)
[  106.424421] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = PTR0
[  106.425745] test_klp_shadow_vars:   shadow_get() got expected NULL result
[  106.438719] % rmmod test_klp_shadow_vars
Signature · 5 lines
Josh
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#3 lore raw

Re: [PATCH v2] selftests/livepatch: introduce tests

Quoted 10 lines · Josh Poimboeuf

lib/livepatch/test_klp_shadow_vars.c line 232

Quoted 6 lines · Joe Lawrence
lib/livepatch/test_klp_shadow_vars.c new file +6 -0
+static void test_klp_shadow_vars_exit(void)
+{
+}
+
+module_init(test_klp_shadow_vars_init);
+module_init(test_klp_shadow_vars_exit);

For this last line, s/module_init/module_exit/, though I think the exit function can just be removed altogether?

D'oh workspace / git user error, I posted an older version :(

But the exit function seems to be required if an init function is provided. Here I omitted the exit function:

% modprobe test_klp_shadow_vars
% lsmod | grep test_klp_shadow_vars
test_klp_shadow_vars 16384 0
% rmmod test_klp_shadow_vars
rmmod: ERROR: could not remove 'test_klp_shadow_vars': Device or
resource busy
rmmod: ERROR: could not remove module test_klp_shadow_vars: Device or
resource busy

and from kernel/module.c

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
...

        /* If it has an init func, it must have an exit func to unload*/
        if (mod->init && !mod->exit) {
                forced = try_force_unload(flags);
                if (!forced) {
                        /* This module can't be removed */
                        ret = -EBUSY;
                        goto out;
                }
        }

...

Quoted 48 lines

Also I get the following bug (run on latest Linus master + Petr's two patch sets):

[  106.302072] % modprobe test_klp_shadow_vars
[  106.311165] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = PTR0
[  106.313080] test_klp_shadow_vars:   got expected NULL result
[  106.314811] BUG: sleeping function called from invalid context at mm/slab.h:421
[  106.316518] in_atomic(): 1, irqs_disabled(): 1, pid: 2254, name: modprobe
[  106.318107] 1 lock held by modprobe/2254:
[  106.319332]  #0: 00000000d0851080 (klp_shadow_lock){....}, at: __klp_shadow_get_or_alloc+0x88/0x1b0
[  106.321220] irq event stamp: 4408
[  106.322176] hardirqs last  enabled at (4407): [<ffffffff8114c28e>] console_unlock+0x44e/0x680
[  106.323598] hardirqs last disabled at (4408): [<ffffffff8199e6c7>] _raw_spin_lock_irqsave+0x27/0x90
[  106.325041] softirqs last  enabled at (4404): [<ffffffff81c0039b>] __do_softirq+0x39b/0x4fc
[  106.326469] softirqs last disabled at (4367): [<ffffffff810d8450>] irq_exit+0xe0/0xf0
[  106.327901] Preemption disabled at:
[  106.327905] [<ffffffff81167c28>] __klp_shadow_get_or_alloc+0x88/0x1b0
[  106.330117] CPU: 7 PID: 2254 Comm: modprobe Tainted: G              K  4.16.0+ #60
[  106.331565] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
[  106.333143] Call Trace:
[  106.334011]  dump_stack+0x8e/0xd5
[  106.334962]  ___might_sleep+0x185/0x260
[  106.335997]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.337170]  __might_sleep+0x4a/0x80
[  106.338137]  kmem_cache_alloc_trace+0x20b/0x300
[  106.339183]  ? ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
[  106.340341]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.341506]  ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
[  106.342725]  shadow_ctor+0x20/0x40 [test_klp_shadow_vars]
[  106.343998]  __klp_shadow_get_or_alloc+0xc4/0x1b0
[  106.345184]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
[  106.346494]  klp_shadow_alloc+0x10/0x20
[  106.347583]  shadow_alloc+0x28/0xa0 [test_klp_shadow_vars]
[  106.348871]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
[  106.350200]  test_klp_shadow_vars_init+0x96/0x400 [test_klp_shadow_vars]
[  106.351646]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
[  106.352949]  do_one_initcall+0x61/0x37f
[  106.353963]  ? rcu_read_lock_sched_held+0x79/0x80
[  106.355040]  ? kmem_cache_alloc_trace+0x29d/0x300
[  106.356098]  ? do_init_module+0x27/0x213
[  106.357090]  do_init_module+0x5f/0x213
[  106.358047]  load_module+0x2815/0x2e70
[  106.358992]  ? vfs_read+0x12d/0x150
[  106.359920]  SYSC_finit_module+0xfc/0x120
[  106.360870]  ? SYSC_finit_module+0xfc/0x120
[  106.361839]  SyS_finit_module+0xe/0x10
[  106.362753]  do_syscall_64+0x7e/0x240
Quoted 8 lines
[  106.363645]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
[  106.364711] RIP: 0033:0x7f26d0d40b19
[  106.365799] RSP: 002b:00007ffee1de19a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[  106.367306] RAX: ffffffffffffffda RBX: 00005636550d54b0 RCX: 00007f26d0d40b19
[  106.368573] RDX: 0000000000000000 RSI: 0000563654134186 RDI: 0000000000000003
[  106.369950] RBP: 0000563654134186 R08: 0000000000000000 R09: 00005636550d4270
[  106.371164] R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
[  106.372422] R13: 00005636550d53b0 R14: 0000000000040000 R15: 00005636550d54b0

I missed Petr's commit msg note "that the constructor is called under klp_shadow_lock." I'll convert the test to use GFP_ATOMIC for this allocation.

I'll also add CONFIG_PM_SLEEP_DEBUG=y to my test VM kernel .config. Any other debug option suggestions?

-- Joe
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [PATCH v2] selftests/livepatch: introduce tests

Quoted 40 lines · Joe Lawrence
Quoted 10 lines · Josh Poimboeuf

lib/livepatch/test_klp_shadow_vars.c line 232

Quoted 6 lines · Joe Lawrence
lib/livepatch/test_klp_shadow_vars.c new file +6 -0
+static void test_klp_shadow_vars_exit(void)
+{
+}
+
+module_init(test_klp_shadow_vars_init);
+module_init(test_klp_shadow_vars_exit);

For this last line, s/module_init/module_exit/, though I think the exit function can just be removed altogether?

D'oh workspace / git user error, I posted an older version :(

But the exit function seems to be required if an init function is provided. Here I omitted the exit function:

% modprobe test_klp_shadow_vars
% lsmod | grep test_klp_shadow_vars
test_klp_shadow_vars 16384 0
% rmmod test_klp_shadow_vars
rmmod: ERROR: could not remove 'test_klp_shadow_vars': Device or
resource busy
rmmod: ERROR: could not remove module test_klp_shadow_vars: Device or
resource busy

and from kernel/module.c

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
...

        /* If it has an init func, it must have an exit func to unload*/
        if (mod->init && !mod->exit) {
                forced = try_force_unload(flags);
                if (!forced) {
                        /* This module can't be removed */
                        ret = -EBUSY;
                        goto out;
                }
        }
Quoted 1 line

...

Hm, ok, though that seems like a weird limitation...

Quoted 6 lines

I missed Petr's commit msg note "that the constructor is called under klp_shadow_lock." I'll convert the test to use GFP_ATOMIC for this allocation.

I'll also add CONFIG_PM_SLEEP_DEBUG=y to my test VM kernel .config. Any other debug option suggestions?

I think CONFIG_LOCKDEP is always a good idea. Otherwise, I dunno... Here's my .config:

https://paste.fedoraproject.org/paste/cnM-J18uVWJrxz2DAdSchg

Signature · 5 lines
Josh
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw

Re: [PATCH v2] selftests/livepatch: introduce tests

Quoted 1 line · Josh Poimboeuf

I think CONFIG_LOCKDEP is always a good idea.

FWIW CONFIG_LOCKDEP mostly enables the infrastructure, but CONFIG_PROVE_LOCKING is what turns most of the cleverness on.

Signature · 7 lines
Jiri Kosina
SUSE Labs

--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#6 lore raw

Re: [PATCH v2] selftests/livepatch: introduce tests

In reply to Joe Lawrence
Thank you for the patch! Yet something to improve:

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v4.16]
[also build test ERROR on next-20180410]
[cannot apply to linus/master jikos-livepatching/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Joe-Lawrence/selftests-livepatch-introduce-tests/20180411-093112
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:

        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

lib/livepatch/test_klp_shadow_vars.c:76:9: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:76:9: sparse: got "\001"
lib/livepatch/test_klp_shadow_vars.c:79:9: sparse: Trying to use reserved word 'return' as identifier
lib/livepatch/test_klp_shadow_vars.c:79:16: sparse: Expected ; at end of declaration
lib/livepatch/test_klp_shadow_vars.c:79:16: sparse: got ret
lib/livepatch/test_klp_shadow_vars.c:80:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:80:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:88:9: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:88:9: sparse: got "\001"
lib/livepatch/test_klp_shadow_vars.c:91:9: sparse: Trying to use reserved word 'return' as identifier
lib/livepatch/test_klp_shadow_vars.c:91:16: sparse: Expected ; at end of declaration
lib/livepatch/test_klp_shadow_vars.c:91:16: sparse: got ret
lib/livepatch/test_klp_shadow_vars.c:92:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:92:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:97:9: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:97:9: sparse: got "\001"
lib/livepatch/test_klp_shadow_vars.c:99:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:99:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:104:9: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:104:9: sparse: got "\001"
lib/livepatch/test_klp_shadow_vars.c:106:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:106:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:114:9: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:114:9: sparse: got "\001"
lib/livepatch/test_klp_shadow_vars.c:117:9: sparse: Trying to use reserved word 'return' as identifier
lib/livepatch/test_klp_shadow_vars.c:117:16: sparse: Expected ; at end of declaration
lib/livepatch/test_klp_shadow_vars.c:117:16: sparse: got 0
lib/livepatch/test_klp_shadow_vars.c:118:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:118:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:124:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:124:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:138:16: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:138:16: sparse: got 0
lib/livepatch/test_klp_shadow_vars.c:139:16: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:139:16: sparse: got &
lib/livepatch/test_klp_shadow_vars.c:140:16: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:140:16: sparse: got &
lib/livepatch/test_klp_shadow_vars.c:141:16: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:141:16: sparse: got &
lib/livepatch/test_klp_shadow_vars.c:142:16: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:142:16: sparse: got &
lib/livepatch/test_klp_shadow_vars.c:149:13: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:149:13: sparse: got !
lib/livepatch/test_klp_shadow_vars.c:149:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:164:17: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:164:17: sparse: got ==
lib/livepatch/test_klp_shadow_vars.c:164:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:168:17: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:168:17: sparse: got ==
lib/livepatch/test_klp_shadow_vars.c:168:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:172:17: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:172:17: sparse: got ==
lib/livepatch/test_klp_shadow_vars.c:172:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:182:17: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:182:17: sparse: got ==
lib/livepatch/test_klp_shadow_vars.c:182:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:192:13: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:192:13: sparse: got !
lib/livepatch/test_klp_shadow_vars.c:192:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:195:25: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:195:25: sparse: got +
lib/livepatch/test_klp_shadow_vars.c:197:13: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:197:13: sparse: got !
lib/livepatch/test_klp_shadow_vars.c:197:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:200:25: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:200:25: sparse: got +
lib/livepatch/test_klp_shadow_vars.c:202:13: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:202:13: sparse: got !
lib/livepatch/test_klp_shadow_vars.c:202:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:209:17: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:209:17: sparse: got ==
lib/livepatch/test_klp_shadow_vars.c:209:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:216:28: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:216:28: sparse: got +
lib/livepatch/test_klp_shadow_vars.c:218:13: sparse: Expected ) in function declarator
lib/livepatch/test_klp_shadow_vars.c:218:13: sparse: got !
lib/livepatch/test_klp_shadow_vars.c:218:9: sparse: Trying to use reserved word 'if' as identifier
lib/livepatch/test_klp_shadow_vars.c:224:9: sparse: Trying to use reserved word 'return' as identifier
lib/livepatch/test_klp_shadow_vars.c:224:16: sparse: Expected ; at end of declaration
lib/livepatch/test_klp_shadow_vars.c:224:16: sparse: got 0
lib/livepatch/test_klp_shadow_vars.c:225:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:225:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:231:1: sparse: Expected ; at the end of type declaration
lib/livepatch/test_klp_shadow_vars.c:231:1: sparse: got }
lib/livepatch/test_klp_shadow_vars.c:113:23: sparse: undefined identifier 'ctor_data'
lib/livepatch/test_klp_shadow_vars.c:148:26: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:148:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types lib/livepatch/test_klp_shadow_vars.c:155:28: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:155:9: sparse: symbol 'sv1' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types lib/livepatch/test_klp_shadow_vars.c:156:28: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:156:9: sparse: symbol 'sv2' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types lib/livepatch/test_klp_shadow_vars.c:157:28: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:157:9: sparse: symbol 'sv3' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types lib/livepatch/test_klp_shadow_vars.c:163:26: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:163:9: sparse: symbol 'ret' has multiple initializers (originally initialized at lib/livepatch/test_klp_shadow_vars.c:148) lib/livepatch/test_klp_shadow_vars.c:163:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types lib/livepatch/test_klp_shadow_vars.c:167:26: sparse: undefined identifier 'obj'
lib/livepatch/test_klp_shadow_vars.c:167:9: sparse: symbol 'ret' has multiple initializers (originally initialized at lib/livepatch/test_klp_shadow_vars.c:163) lib/livepatch/test_klp_shadow_vars.c:167:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types lib/livepatch/test_klp_shadow_vars.c:171:26: sparse: too many errors

>> lib/livepatch/test_klp_shadow_vars.c:72:6: error: unknown type name 'klp_shadow_ctor_t'
         klp_shadow_ctor_t ctor, void *ctor_data)
         ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c:83:23: error: unknown type name 'klp_shadow_ctor_t'
         gfp_t gfp_flags, klp_shadow_ctor_t ctor,
                          ^~~~~~~~~~~~~~~~~
>> lib/livepatch/test_klp_shadow_vars.c:94:47: error: unknown type name 'klp_shadow_dtor_t'
    void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
                                                  ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c:101:40: error: unknown type name 'klp_shadow_dtor_t'
    void shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
                                           ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c: In function 'test_klp_shadow_vars_init':
>> lib/livepatch/test_klp_shadow_vars.c:155:8: error: implicit declaration of function 'shadow_alloc'; did you mean 'shadow_dtor'? [-Werror=implicit-function-declaration]
     sv1 = shadow_alloc(obj, id, size, gfp_flags, shadow_ctor, &var1);
           ^~~~~~~~~~~~
           shadow_dtor
>> lib/livepatch/test_klp_shadow_vars.c:155:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv1 = shadow_alloc(obj, id, size, gfp_flags, shadow_ctor, &var1);
         ^
   lib/livepatch/test_klp_shadow_vars.c:156:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv2 = shadow_alloc(obj + 1, id, size, gfp_flags, shadow_ctor, &var2);
         ^
   lib/livepatch/test_klp_shadow_vars.c:157:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv3 = shadow_alloc(obj, id + 1, size, gfp_flags, shadow_ctor, &var3);
         ^
>> lib/livepatch/test_klp_shadow_vars.c:180:8: error: implicit declaration of function 'shadow_get_or_alloc'; did you mean 'klp_shadow_get_or_alloc'? [-Werror=implicit-function-declaration]
     sv4 = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
           ^~~~~~~~~~~~~~~~~~~
           klp_shadow_get_or_alloc
   lib/livepatch/test_klp_shadow_vars.c:180:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv4 = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
         ^
   lib/livepatch/test_klp_shadow_vars.c:181:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     ret = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
         ^
>> lib/livepatch/test_klp_shadow_vars.c:190:2: error: implicit declaration of function 'shadow_free'; did you mean 'shadow_get'? [-Werror=implicit-function-declaration]
     shadow_free(obj, id, shadow_dtor);   /* sv1 */
     ^~~~~~~~~~~
     shadow_get
>> lib/livepatch/test_klp_shadow_vars.c:216:2: error: implicit declaration of function 'shadow_free_all'; did you mean 'klp_shadow_free_all'? [-Werror=implicit-function-declaration]
     shadow_free_all(id + 1, shadow_dtor);   /* sv3 */
     ^~~~~~~~~~~~~~~
     klp_shadow_free_all
   In file included from lib/livepatch/test_klp_shadow_vars.c:6:0:
   lib/livepatch/test_klp_shadow_vars.c: At top level:
   include/linux/module.h:130:42: error: redefinition of '__inittest'
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
>> lib/livepatch/test_klp_shadow_vars.c:232:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_exit);
    ^~~~~~~~~~~
   include/linux/module.h:130:42: note: previous definition of '__inittest' was here
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
   lib/livepatch/test_klp_shadow_vars.c:231:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_init);
    ^~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c: In function '__inittest':
>> lib/livepatch/test_klp_shadow_vars.c:232:13: error: return from incompatible pointer type [-Werror=incompatible-pointer-types]
    module_init(test_klp_shadow_vars_exit);
                ^
   include/linux/module.h:131:11: note: in definition of macro 'module_init'
     { return initfn; }     \
              ^~~~~~
   lib/livepatch/test_klp_shadow_vars.c: At top level:
   include/linux/module.h:132:6: error: redefinition of 'init_module'
     int init_module(void) __attribute__((alias(#initfn)));
         ^
>> lib/livepatch/test_klp_shadow_vars.c:232:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_exit);
    ^~~~~~~~~~~
   include/linux/module.h:132:6: note: previous definition of 'init_module' was here
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   lib/livepatch/test_klp_shadow_vars.c:231:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_init);
    ^~~~~~~~~~~

cc1: some warnings being treated as errors

sparse warnings: (new ones prefixed by >>)

lib/livepatch/test_klp_atomic_replace.c:46:14: sparse: no member 'replace' in struct klp_patch

>> lib/livepatch/test_klp_atomic_replace.c:46:14: sparse: generating address of non-lvalue (8)
   lib/livepatch/test_klp_atomic_replace.c: In function 'test_klp_atomic_replace_init':
   lib/livepatch/test_klp_atomic_replace.c:46:7: error: 'struct klp_patch' has no member named 'replace'
     patch.replace = replace;
          ^
--
   lib/livepatch/test_klp_callbacks_demo2.c:81:14: sparse: no member 'replace' in struct klp_patch
>> lib/livepatch/test_klp_callbacks_demo2.c:81:14: sparse: generating address of non-lvalue (8)
   lib/livepatch/test_klp_callbacks_demo2.c: In function 'test_klp_callbacks_demo2_init':
   lib/livepatch/test_klp_callbacks_demo2.c:81:7: error: 'struct klp_patch' has no member named 'replace'
     patch.replace = replace;
          ^

--
lib/livepatch/test_klp_shadow_vars.c:72:38: sparse: Expected ) in function declarator lib/livepatch/test_klp_shadow_vars.c:72:38: sparse: got ctor lib/livepatch/test_klp_shadow_vars.c:76:9: sparse: Expected ) in function declarator lib/livepatch/test_klp_shadow_vars.c:76:9: sparse: got "001"

>> lib/livepatch/test_klp_shadow_vars.c:79:9: sparse: Trying to use reserved word 'return' as identifier
   lib/livepatch/test_klp_shadow_vars.c:79:16: sparse: Expected ; at end of declaration
   lib/livepatch/test_klp_shadow_vars.c:79:16: sparse: got ret
   lib/livepatch/test_klp_shadow_vars.c:80:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:80:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:88:9: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:88:9: sparse: got "001"
   lib/livepatch/test_klp_shadow_vars.c:91:9: sparse: Trying to use reserved word 'return' as identifier
   lib/livepatch/test_klp_shadow_vars.c:91:16: sparse: Expected ; at end of declaration
   lib/livepatch/test_klp_shadow_vars.c:91:16: sparse: got ret
   lib/livepatch/test_klp_shadow_vars.c:92:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:92:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:97:9: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:97:9: sparse: got "001"
   lib/livepatch/test_klp_shadow_vars.c:99:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:99:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:104:9: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:104:9: sparse: got "001"
   lib/livepatch/test_klp_shadow_vars.c:106:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:106:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:114:9: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:114:9: sparse: got "001"
   lib/livepatch/test_klp_shadow_vars.c:117:9: sparse: Trying to use reserved word 'return' as identifier
   lib/livepatch/test_klp_shadow_vars.c:117:16: sparse: Expected ; at end of declaration
   lib/livepatch/test_klp_shadow_vars.c:117:16: sparse: got 0
   lib/livepatch/test_klp_shadow_vars.c:118:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:118:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:124:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:124:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:138:16: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:138:16: sparse: got 0
   lib/livepatch/test_klp_shadow_vars.c:139:16: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:139:16: sparse: got &
   lib/livepatch/test_klp_shadow_vars.c:140:16: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:140:16: sparse: got &
   lib/livepatch/test_klp_shadow_vars.c:141:16: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:141:16: sparse: got &
   lib/livepatch/test_klp_shadow_vars.c:142:16: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:142:16: sparse: got &
   lib/livepatch/test_klp_shadow_vars.c:149:13: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:149:13: sparse: got !
>> lib/livepatch/test_klp_shadow_vars.c:149:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:164:17: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:164:17: sparse: got ==
   lib/livepatch/test_klp_shadow_vars.c:164:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:168:17: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:168:17: sparse: got ==
   lib/livepatch/test_klp_shadow_vars.c:168:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:172:17: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:172:17: sparse: got ==
   lib/livepatch/test_klp_shadow_vars.c:172:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:182:17: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:182:17: sparse: got ==
   lib/livepatch/test_klp_shadow_vars.c:182:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:192:13: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:192:13: sparse: got !
   lib/livepatch/test_klp_shadow_vars.c:192:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:195:25: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:195:25: sparse: got +
   lib/livepatch/test_klp_shadow_vars.c:197:13: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:197:13: sparse: got !
   lib/livepatch/test_klp_shadow_vars.c:197:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:200:25: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:200:25: sparse: got +
   lib/livepatch/test_klp_shadow_vars.c:202:13: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:202:13: sparse: got !
   lib/livepatch/test_klp_shadow_vars.c:202:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:209:17: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:209:17: sparse: got ==
   lib/livepatch/test_klp_shadow_vars.c:209:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:216:28: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:216:28: sparse: got +
   lib/livepatch/test_klp_shadow_vars.c:218:13: sparse: Expected ) in function declarator
   lib/livepatch/test_klp_shadow_vars.c:218:13: sparse: got !
   lib/livepatch/test_klp_shadow_vars.c:218:9: sparse: Trying to use reserved word 'if' as identifier
   lib/livepatch/test_klp_shadow_vars.c:224:9: sparse: Trying to use reserved word 'return' as identifier
   lib/livepatch/test_klp_shadow_vars.c:224:16: sparse: Expected ; at end of declaration
   lib/livepatch/test_klp_shadow_vars.c:224:16: sparse: got 0
   lib/livepatch/test_klp_shadow_vars.c:225:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:225:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:231:1: sparse: Expected ; at the end of type declaration
   lib/livepatch/test_klp_shadow_vars.c:231:1: sparse: got }
   lib/livepatch/test_klp_shadow_vars.c:113:23: sparse: undefined identifier 'ctor_data'
   lib/livepatch/test_klp_shadow_vars.c:148:26: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:148:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types
   lib/livepatch/test_klp_shadow_vars.c:155:28: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:155:9: sparse: symbol 'sv1' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types
   lib/livepatch/test_klp_shadow_vars.c:156:28: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:156:9: sparse: symbol 'sv2' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types
   lib/livepatch/test_klp_shadow_vars.c:157:28: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:157:9: sparse: symbol 'sv3' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:134) - different base types
   lib/livepatch/test_klp_shadow_vars.c:163:26: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:163:9: sparse: symbol 'ret' has multiple initializers (originally initialized at lib/livepatch/test_klp_shadow_vars.c:148)
   lib/livepatch/test_klp_shadow_vars.c:163:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types
   lib/livepatch/test_klp_shadow_vars.c:167:26: sparse: undefined identifier 'obj'
   lib/livepatch/test_klp_shadow_vars.c:167:9: sparse: symbol 'ret' has multiple initializers (originally initialized at lib/livepatch/test_klp_shadow_vars.c:163)
   lib/livepatch/test_klp_shadow_vars.c:167:9: sparse: symbol 'ret' redeclared with different type (originally declared at lib/livepatch/test_klp_shadow_vars.c:136) - different base types
>> lib/livepatch/test_klp_shadow_vars.c:171:26: sparse: too many errors
   lib/livepatch/test_klp_shadow_vars.c:72:6: error: unknown type name 'klp_shadow_ctor_t'
         klp_shadow_ctor_t ctor, void *ctor_data)
         ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c:83:23: error: unknown type name 'klp_shadow_ctor_t'
         gfp_t gfp_flags, klp_shadow_ctor_t ctor,
                          ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c:94:47: error: unknown type name 'klp_shadow_dtor_t'
    void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
                                                  ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c:101:40: error: unknown type name 'klp_shadow_dtor_t'
    void shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
                                           ^~~~~~~~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c: In function 'test_klp_shadow_vars_init':
   lib/livepatch/test_klp_shadow_vars.c:155:8: error: implicit declaration of function 'shadow_alloc'; did you mean 'shadow_dtor'? [-Werror=implicit-function-declaration]
     sv1 = shadow_alloc(obj, id, size, gfp_flags, shadow_ctor, &var1);
           ^~~~~~~~~~~~
           shadow_dtor
   lib/livepatch/test_klp_shadow_vars.c:155:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv1 = shadow_alloc(obj, id, size, gfp_flags, shadow_ctor, &var1);
         ^
   lib/livepatch/test_klp_shadow_vars.c:156:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv2 = shadow_alloc(obj + 1, id, size, gfp_flags, shadow_ctor, &var2);
         ^
   lib/livepatch/test_klp_shadow_vars.c:157:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv3 = shadow_alloc(obj, id + 1, size, gfp_flags, shadow_ctor, &var3);
         ^
   lib/livepatch/test_klp_shadow_vars.c:180:8: error: implicit declaration of function 'shadow_get_or_alloc'; did you mean 'klp_shadow_get_or_alloc'? [-Werror=implicit-function-declaration]
     sv4 = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
           ^~~~~~~~~~~~~~~~~~~
           klp_shadow_get_or_alloc
   lib/livepatch/test_klp_shadow_vars.c:180:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     sv4 = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
         ^
   lib/livepatch/test_klp_shadow_vars.c:181:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     ret = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
         ^
   lib/livepatch/test_klp_shadow_vars.c:190:2: error: implicit declaration of function 'shadow_free'; did you mean 'shadow_get'? [-Werror=implicit-function-declaration]
     shadow_free(obj, id, shadow_dtor);   /* sv1 */
     ^~~~~~~~~~~
     shadow_get
   lib/livepatch/test_klp_shadow_vars.c:216:2: error: implicit declaration of function 'shadow_free_all'; did you mean 'klp_shadow_free_all'? [-Werror=implicit-function-declaration]
     shadow_free_all(id + 1, shadow_dtor);   /* sv3 */
     ^~~~~~~~~~~~~~~
     klp_shadow_free_all
   In file included from lib/livepatch/test_klp_shadow_vars.c:6:0:
   lib/livepatch/test_klp_shadow_vars.c: At top level:
   include/linux/module.h:130:42: error: redefinition of '__inittest'
     static inline initcall_t __maybe_unused __inittest(void)  151-                                          ^
   lib/livepatch/test_klp_shadow_vars.c:232:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_exit);
    ^~~~~~~~~~~
   include/linux/module.h:130:42: note: previous definition of '__inittest' was here
     static inline initcall_t __maybe_unused __inittest(void)  157-                                          ^
   lib/livepatch/test_klp_shadow_vars.c:231:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_init);
    ^~~~~~~~~~~
   lib/livepatch/test_klp_shadow_vars.c: In function '__inittest':
   lib/livepatch/test_klp_shadow_vars.c:232:13: error: return from incompatible pointer type [-Werror=incompatible-pointer-types]
    module_init(test_klp_shadow_vars_exit);
                ^
   include/linux/module.h:131:11: note: in definition of macro 'module_init'
     { return initfn; }     167-           ^~~~~~
   lib/livepatch/test_klp_shadow_vars.c: At top level:
   include/linux/module.h:132:6: error: redefinition of 'init_module'
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   lib/livepatch/test_klp_shadow_vars.c:232:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_exit);
    ^~~~~~~~~~~
   include/linux/module.h:132:6: note: previous definition of 'init_module' was here
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   lib/livepatch/test_klp_shadow_vars.c:231:1: note: in expansion of macro 'module_init'
    module_init(test_klp_shadow_vars_init);
    ^~~~~~~~~~~

cc1: some warnings being treated as errors

vim +/klp_shadow_ctor_t +72 lib/livepatch/test_klp_shadow_vars.c

70
71 void *shadow_alloc(void *obj, unsigned long id, size_t size, gfp_t gfp_flags,

  > 72			   klp_shadow_ctor_t ctor, void *ctor_data)
    73	{
    74		void *ret = klp_shadow_alloc(obj, id, size, gfp_flags, ctor,
    75					     ctor_data);
    76		pr_info("klp_%s(obj=PTR%d, id=0x%lx, size=%zx, gfp_flags=%pGg), ctor=PTR%d, ctor_data=PTR%d = PTR%d\n",
    77			__func__, ptr_id(obj), id, size, &gfp_flags, ptr_id(ctor),
    78			ptr_id(ctor_data), ptr_id(ret));
  > 79		return ret;
    80	}
    81	
    82	void *shadow_get_or_alloc(void *obj, unsigned long id, size_t size,
    83				  gfp_t gfp_flags, klp_shadow_ctor_t ctor,
    84				  void *ctor_data)
    85	{
    86		void *ret = klp_shadow_get_or_alloc(obj, id, size, gfp_flags, ctor,
    87						    ctor_data);
    88		pr_info("klp_%s(obj=PTR%d, id=0x%lx, size=%zx, gfp_flags=%pGg), ctor=PTR%d, ctor_data=PTR%d = PTR%d\n",
    89			__func__, ptr_id(obj), id, size, &gfp_flags, ptr_id(ctor),
    90			ptr_id(ctor_data), ptr_id(ret));
    91		return ret;
    92	}
    93	
  > 94	void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
    95	{
    96		klp_shadow_free(obj, id, dtor);
    97		pr_info("klp_%s(obj=PTR%d, id=0x%lx, dtor=PTR%d)\n",
    98			__func__, ptr_id(obj), id, ptr_id(dtor));
    99	}
   100	
 > 101	void shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
   102	{
   103		klp_shadow_free_all(id, dtor);
   104		pr_info("klp_%s(id=0x%lx, dtor=PTR%d)\n",
   105			__func__, id, ptr_id(dtor));
   106	}
   107	
   108	
   109	/* Shadow variable constructor - remember simple pointer data */
   110	static int shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
   111	{
   112		int **shadow_int = shadow_data;
   113		*shadow_int = ctor_data;
   114		pr_info("%s: PTR%d -> PTR%d\n",
   115			__func__, ptr_id(shadow_int), ptr_id(ctor_data));
   116	
   117		return 0;
   118	}
   119	
   120	static void shadow_dtor(void *obj, void *shadow_data)
   121	{
   122		pr_info("%s(obj=PTR%d, shadow_data=PTR%d)\n",
   123			__func__, ptr_id(obj), ptr_id(shadow_data));
   124	}
   125	
   126	static int test_klp_shadow_vars_init(void)
   127	{
   128		void *obj			= THIS_MODULE;
   129		int id			= 0x1234;
   130		size_t size		= sizeof(int *);
   131		gfp_t gfp_flags		= GFP_KERNEL;
   132	
   133		int var1, var2, var3, var4;
   134		int **sv1, **sv2, **sv3, **sv4;
   135	
   136		void *ret;
   137	
   138		ptr_id(0);
 > 139		ptr_id(&var1);
   140		ptr_id(&var2);
   141		ptr_id(&var3);
   142		ptr_id(&var4);
   143	
   144		/*
   145		 * With an empty shadow variable hash table, expect not to find
   146		 * any matches.
   147		 */
   148		ret = shadow_get(obj, id);
 > 149		if (!ret)
   150			pr_info("  got expected NULL result\n");
   151	
   152		/*
   153		 * Allocate a few shadow variables with different <obj> and <id>.
   154		 */
 > 155		sv1 = shadow_alloc(obj, id, size, gfp_flags, shadow_ctor, &var1);
 > 156		sv2 = shadow_alloc(obj + 1, id, size, gfp_flags, shadow_ctor, &var2);
 > 157		sv3 = shadow_alloc(obj, id + 1, size, gfp_flags, shadow_ctor, &var3);
   158	
   159		/*
   160		 * Verify we can find our new shadow variables and that they point
   161		 * to expected data.
   162		 */
   163		ret = shadow_get(obj, id);
   164		if (ret == sv1 && *sv1 == &var1)
   165			pr_info("  got expected PTR%d -> PTR%d result\n",
   166				ptr_id(sv1), ptr_id(*sv1));
 > 167		ret = shadow_get(obj + 1, id);
   168		if (ret == sv2 && *sv2 == &var2)
   169			pr_info("  got expected PTR%d -> PTR%d result\n",
   170				ptr_id(sv2), ptr_id(*sv2));
 > 171		ret = shadow_get(obj, id + 1);
   172		if (ret == sv3 && *sv3 == &var3)
   173			pr_info("  got expected PTR%d -> PTR%d result\n",
   174				ptr_id(sv3), ptr_id(*sv3));
   175	
   176		/*
   177		 * Allocate or get a few more, this time with the same <obj>, <id>.
   178		 * The second invocation should return the same shadow var.
   179		 */
 > 180		sv4 = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
 > 181		ret = shadow_get_or_alloc(obj + 2, id, size, gfp_flags, shadow_ctor, &var4);
   182		if (ret == sv4 && *sv4 == &var4)
   183			pr_info("  got expected PTR%d -> PTR%d result\n",
   184				ptr_id(sv4), ptr_id(*sv4));
   185	
   186		/*
   187		 * Free the <obj=*, id> shadow variables and check that we can no
   188		 * longer find them.
   189		 */
 > 190		shadow_free(obj, id, shadow_dtor);			/* sv1 */
   191		ret = shadow_get(obj, id);
   192		if (!ret)
   193			pr_info("  got expected NULL result\n");
   194	
   195		shadow_free(obj + 1, id, shadow_dtor);			/* sv2 */
   196		ret = shadow_get(obj + 1, id);
   197		if (!ret)
   198			pr_info("  got expected NULL result\n");
   199	
   200		shadow_free(obj + 2, id, shadow_dtor);			/* sv4 */
   201		ret = shadow_get(obj + 2, id);
   202		if (!ret)
   203			pr_info("  got expected NULL result\n");
   204	
   205		/*
   206		 * We should still find an <id+1> variable.
   207		 */
   208		ret = shadow_get(obj, id + 1);
   209		if (ret == sv3 && *sv3 == &var3)
   210			pr_info("  got expected PTR%d -> PTR%d result\n",
   211				ptr_id(sv3), ptr_id(*sv3));
   212	
   213		/*
   214		 * Free all the <id+1> variables, too.
   215		 */
 > 216		shadow_free_all(id + 1, shadow_dtor);			/* sv3 */
   217		ret = shadow_get(obj, id);
   218		if (!ret)
   219			pr_info("  shadow_get() got expected NULL result\n");
   220	
   221	
   222		free_ptr_list();
   223	
   224		return 0;
   225	}
   226	
   227	static void test_klp_shadow_vars_exit(void)
   228	{
   229	}
   230	
 > 231	module_init(test_klp_shadow_vars_init);
 > 232	module_init(test_klp_shadow_vars_exit);

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#7 lore raw

PATCH v2 1/1 selftests/livepatch: introduce tests

Quoted 8 lines · kbuild test robot

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v4.16]
[also build test ERROR on next-20180410]
[cannot apply to linus/master jikos-livepatching/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

                                   ^^^^^^^^^^^^^^

Hi kbuild test robot,

Thank you for testing! Yet something to improve:

Is there syntax one can add to a commit, or better yet, patchset cover letter to specify a git tree URL in which the patch(set) is based on?

I can't find anything at [1] that documents such feature.

[1] https://01.org/lkp/documentation/0-day-test-service

Thanks,

-- Joe
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

PATCH v2 1/1 selftests/livepatch: introduce tests

Quoted 9 lines · Joe Lawrence
Quoted 8 lines · kbuild test robot

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v4.16]
[also build test ERROR on next-20180410]
[cannot apply to linus/master jikos-livepatching/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

Quoted 7 lines
                                   ^^^^^^^^^^^^^^

Hi kbuild test robot,

Thank you for testing! Yet something to improve:

Is there syntax one can add to a commit, or better yet, patchset cover letter to specify a git tree URL in which the patch(set) is based on?

thanks Joe, currently we recommend to use --base option when using git format-patch. This will record the base of your series, and 0day would act accordingly to apply to that base.

Quoted 5 lines

I can't find anything at [1] that documents such feature.

[1] https://01.org/lkp/documentation/0-day-test-service

Quoted 7 lines

Thanks,

-- Joe
_______________________________________________
kbuild-all mailing list
kbuild-all at lists.01.org
https://lists.01.org/mailman/listinfo/kbuild-all

--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

PATCH v2 1/1 selftests/livepatch: introduce tests

Quoted 13 lines · Philip Li
Quoted 12 lines · Joe Lawrence
Quoted 8 lines · kbuild test robot

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v4.16]
[also build test ERROR on next-20180410]
[cannot apply to linus/master jikos-livepatching/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

                                   ^^^^^^^^^^^^^^

Hi kbuild test robot,

Quoted 7 lines
Quoted 4 lines

Thank you for testing! Yet something to improve:

Is there syntax one can add to a commit, or better yet, patchset cover letter to specify a git tree URL in which the patch(set) is based on?

thanks Joe, currently we recommend to use --base option when using git format-patch. This will record the base of your series, and 0day would act accordingly to apply to that base.

I didn't know about the --base option, that looks like a cool feature. BTW, I assume that "well-known patches" would apply to those posted to any upstream mailing list that the kbuild test robot is currently listening to?

-- Joe
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw

PATCH v2 1/1 selftests/livepatch: introduce tests

Quoted 18 lines · Joe Lawrence
Quoted 17 lines · Philip Li
Quoted 16 lines · Joe Lawrence
Quoted 8 lines · kbuild test robot

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v4.16]
[also build test ERROR on next-20180410]
[cannot apply to linus/master jikos-livepatching/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

                                   ^^^^^^^^^^^^^^

Hi kbuild test robot,

Thank you for testing! Yet something to improve:

Is there syntax one can add to a commit, or better yet, patchset cover letter to specify a git tree URL in which the patch(set) is based on?

Quoted 8 lines
Quoted 3 lines

thanks Joe, currently we recommend to use --base option when using git format-patch. This will record the base of your series, and 0day would act accordingly to apply to that base.

I didn't know about the --base option, that looks like a cool feature. BTW, I assume that "well-known patches" would apply to those posted to any upstream mailing list that the kbuild test robot is currently listening to?

Yes, as 0day monitors most of maintainers' and core kernel developers' trees that contain those "well known" patches.

Thanks,
Xiaolong

Quoted 6 lines

-- Joe
_______________________________________________
kbuild-all mailing list
kbuild-all at lists.01.org
https://lists.01.org/mailman/listinfo/kbuild-all

--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw
In reply to Joe Lawrence
Quoted 5 lines · Joe Lawrence

Questions for v3:

- Should we split off the atomic replace and shadow variable update tests so that the this patchset could be merged before the ones listed above?

Don't split it up on my account. We can just merge this one shortly after.

Signature · 5 lines
Josh
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
maintainer
#12 lore raw
In reply to Joe Lawrence
Quoted 5 lines

Questions for v3:

- Should we split off the atomic replace and shadow variable update tests so that the this patchset could be merged before the ones listed above?

What Josh said. If we merge it almost together, there is no need to split it.

Quoted 3 lines

- I didn't remove any of the sample modules. If anyone thinks any of them should go, let me know. They serve as nice, simple examples so I thought they should all stay.

Ok

Quoted 4 lines

- Module naming convention: to make the test script easier to grep module names and filenames, I broke with livepatch convention and used underscores instead of dashes. I didn't think it worth the regex foo to flip back and forth in the test script.

Ok

Miroslav
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html