kpatch/kmod/core/kpatch.h

62 lines
1.5 KiB
C
Raw Normal View History

/*
* kpatch.h
*
* Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
* Copyright (C) 2013-2014 Josh Poimboeuf <jpoimboe@redhat.com>
*
2014-03-05 03:34:03 +00:00
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
2014-03-05 03:34:03 +00:00
*
* Contains the API for the core kpatch module used by the patch modules
*/
#ifndef _KPATCH_H_
#define _KPATCH_H_
#include <linux/types.h>
#include <linux/module.h>
2014-04-30 18:26:29 +00:00
enum kpatch_op {
KPATCH_OP_NONE,
KPATCH_OP_PATCH,
KPATCH_OP_UNPATCH,
};
struct kpatch_func {
kmod/core: NMI synchronization improvements This is an attempt to both simplify and improve the correctness of the NMI synchronization code. There's a race in kpatch_ftrace_handler() between the kpatch_get_func() and kpatch_finish_status() calls which could result in func being NULL. The retry was supposed to fix this. However, this race would still be a problem in the repatching case (if the function had already been previously patched), in which case func would not be NULL, but could instead point to the previously patched version of the function. In this case it wouldn't retry and it would be possible for the previous version of the function to run. The fix is to use a memory barrier between accesses of the func hash and the status variable, and then just call kpatch_get_func() *after* accessing the status variable. For OP_PATCH, if status is SUCCESS, then func is guaranteed to point to the new function. If status is FAILURE, func might point to the new function, in which case we can use get_prev_func to get the previous version of the function. I also made some pretty big changes to try to simplify the design so that there are less moving parts and so that it's hopefully easier to understand. I moved the OP field into the kpatch_func struct. This allows us to merge the two global state variables (status + op) into a single global state variable (state), which helps make the code quite a bit simpler. I turned it into a proper state machine and documented the meaning of each state in the comments. Moving the OP field to the kpatch_func struct also paves the way for an upcoming pull request which will allow patch modules to be atomically replaced ("kpatch load --replace <module>").
2014-04-28 16:41:20 +00:00
/* public */
unsigned long new_addr;
unsigned long new_size;
unsigned long old_addr;
unsigned long old_size;
kmod/core: NMI synchronization improvements This is an attempt to both simplify and improve the correctness of the NMI synchronization code. There's a race in kpatch_ftrace_handler() between the kpatch_get_func() and kpatch_finish_status() calls which could result in func being NULL. The retry was supposed to fix this. However, this race would still be a problem in the repatching case (if the function had already been previously patched), in which case func would not be NULL, but could instead point to the previously patched version of the function. In this case it wouldn't retry and it would be possible for the previous version of the function to run. The fix is to use a memory barrier between accesses of the func hash and the status variable, and then just call kpatch_get_func() *after* accessing the status variable. For OP_PATCH, if status is SUCCESS, then func is guaranteed to point to the new function. If status is FAILURE, func might point to the new function, in which case we can use get_prev_func to get the previous version of the function. I also made some pretty big changes to try to simplify the design so that there are less moving parts and so that it's hopefully easier to understand. I moved the OP field into the kpatch_func struct. This allows us to merge the two global state variables (status + op) into a single global state variable (state), which helps make the code quite a bit simpler. I turned it into a proper state machine and documented the meaning of each state in the comments. Moving the OP field to the kpatch_func struct also paves the way for an upcoming pull request which will allow patch modules to be atomically replaced ("kpatch load --replace <module>").
2014-04-28 16:41:20 +00:00
/* private */
struct hlist_node node;
struct kpatch_module *kpmod;
2014-04-30 18:26:29 +00:00
enum kpatch_op op;
};
struct kpatch_module {
struct module *mod;
struct kpatch_func *funcs;
int num_funcs;
bool enabled;
};
extern struct kobject *kpatch_patches_kobj;
extern int kpatch_register(struct kpatch_module *kpmod, bool replace);
extern int kpatch_unregister(struct kpatch_module *kpmod);
#endif /* _KPATCH_H_ */