When multiple patch modules patch the same function, there's no need to
patch all the intermediate functions. Just hook them all into the
original function and use the ftrace handler to find the newest one.
Also use a mutex in the register/unregister functions to protect changes
to kpatch_num_registered, kpatch_func_hash and calls to the ftrace
functions by other register/unregister invocations.
Use a mutex in the register/unregister functions to protect changes to
kpatch_num_registered, kpatch_func_hash and calls to the ftrace
functions by other register/unregister invocations.
There's no need to zero out the kpatch funcs array. The addr fields are
initialized by the patch module, the mod field is intialized by the core
module, and the node struct doesn't need to be initialized because its
fields are overwritten by hash_add.
My apologies for the size of this commit. I combined these two features
(updating API and using a hash table) into a single commit because their
implementations are tightly coupled and I didn't want to have to add
support for the old kpatch_funcs array with the new API just for the
sake of splitting up the commit :-)
- Update the core module API to get a more clear separation between core
module and patch module. This is cleaner and will help our case for
getting the core module merged upstream into the kernel.
- Convert the old kpatch_funcs array into a hash table. This is so much
nicer performance-wise and everything-else-wise than that ugly old
array.
- Do the incremental patching in stop machine. This ensures that the
funcs hash is up to date and we don't miss anything.
- Disable preemption in the ftrace handler when accessing the func hash.
That way we don't get conflicts with the stop_machine handler updating
the hash.
Currently, add-patches-section just blindly looks in vmlinux
for a function symbol matching the name of the patched function
in the input object file. However, for local symbols, they may
appear multiple times in the vmlinux symbol table since the symbol
name may be reused locally in different files.
This commit add support for "file hinting". It tracks what
file the symbol is in and searches for local symbols within
that file in vmlinux first. If it doesn't find one, it then
searches globally like it always has.
Fixes issue #53
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Print the loading/unloading messages after they have successfully
completed. Using the KERN_NOTICE log level which corresponds to a
"normal but significant condition."
Preemption shouldn't cause a problem with determining activeness safety.
Even if a thread is preempted, it'll be on the backtrace.
We may need to disable preemption when reading the kpatch_funcs array,
but I'm removing that comment for now because the kpatch_funcs array
will soon be replaced by a much better data structure, and we'll deal
with proper synchronization then.
Long ago, the kpatch_trampoline required being written in assembler, but
that's no longer needed now that it integrates nicely with ftrace.
Move it to a C function and rename it kpatch_ftrace_handler.
The current solution doesn't work because "$?" will always be 0, even if
there were no "CC" lines in the build log. Instead, just make sure the
changed_objs file isn't empty.
Add a patch testing step before compiling the kernel, so that users
don't have to wait for the kernel to compile before seeing if the patch
applies cleanly.
Also allow the printing of the patch command's stdout/stderr to make it
clear what files are being patched and whether there's any fuzz.
If the patch file fails to apply, it "corrupts" the cache by leaving the
old applied-patch file around. Fix that by always cleaning up after
ourselves.
Allow the user to supply a custom kernel source directory. This copies
the directory to ~/.kpatch/src instead of using it in place. Otherwise
the "make mrproper" (which is needed for compiling objects in a separate
tree) would modify the original source tree and remove its .config file.
There's currently no caching support for this option. If needed, we
could implement that pretty easily by calculating an md5sum of the
original source directory.
kpatch-build is outgrowing the kpatch script and probably is a better
fit as its own utility instead of being wrapped by kpatch. Install
kpatch-build into /usr/local/bin, remove the kpatch wrapper around it,
and update the README accordingly.
For a local object or function symbol, we expect that
the section offset, sym.st_value, be 0 because we used
-ffunction-sections and -fdata-section during compile.
If value != 0, it undermines assumptions we make and
should return an error. Exceptions should be handled
on a case by case basis, like __ksymtab_strings.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit introduces a simple automated testing system
with 3 simple testcase.
For each test case there is a .c, a .patch, and a .inventory
file. The .c is compiled, using the flags from the kflags file,
to create the original object. The .c file is then patched
with the .patch file and rebuilt to create the patched object.
The files are then analyzed by the differencing tool and an
output object is generated with a .inventory file that lists
the sections and symbol included in the output object. That
inventory file is then compared to the .inventory file for
that testcase. If they are the same, the test passes. If
not, the differences in the inventory files are displayed,
and the test fails.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
In preparation for adding an automated test framework,
add an ability to create-object-diff that will create
a human readable list of included sections and symbols
with type and bind information so that the test framework
can compare against a known-good reference list with the
expected set of sections and symbols.
The file is created when the -i/--inventory option is
used. The inventory filename is the user supplied output
file name suffixed by .inventory
Signed-off-by: Seth Jennings <sjenning@redhat.com>