Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
1efbd99e
Commit
1efbd99e
authored
May 06, 2019
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'for-5.1/upstream-fixes' and 'for-5.2/core' into for-linus
parents
802c2471
f68d67cf
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
43 additions
and
55 deletions
+43
-55
Makefile
Makefile
+4
-0
include/linux/livepatch.h
include/linux/livepatch.h
+0
-3
kernel/livepatch/core.c
kernel/livepatch/core.c
+39
-52
No files found.
Makefile
View file @
1efbd99e
...
...
@@ -796,6 +796,10 @@ KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
LDFLAGS_vmlinux
+=
--gc-sections
endif
ifdef
CONFIG_LIVEPATCH
KBUILD_CFLAGS
+=
$(
call
cc-option,
-flive-patching
=
inline-clone
)
endif
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS
+=
-nostdinc
-isystem
$(
shell
$(CC)
-print-file-name
=
include
)
...
...
include/linux/livepatch.h
View file @
1efbd99e
...
...
@@ -86,7 +86,6 @@ struct klp_func {
struct
list_head
node
;
struct
list_head
stack_node
;
unsigned
long
old_size
,
new_size
;
bool
kobj_added
;
bool
nop
;
bool
patched
;
bool
transition
;
...
...
@@ -141,7 +140,6 @@ struct klp_object {
struct
list_head
func_list
;
struct
list_head
node
;
struct
module
*
mod
;
bool
kobj_added
;
bool
dynamic
;
bool
patched
;
};
...
...
@@ -170,7 +168,6 @@ struct klp_patch {
struct
list_head
list
;
struct
kobject
kobj
;
struct
list_head
obj_list
;
bool
kobj_added
;
bool
enabled
;
bool
forced
;
struct
work_struct
free_work
;
...
...
kernel/livepatch/core.c
View file @
1efbd99e
...
...
@@ -426,7 +426,13 @@ static void klp_free_object_dynamic(struct klp_object *obj)
kfree
(
obj
);
}
static
struct
klp_object
*
klp_alloc_object_dynamic
(
const
char
*
name
)
static
void
klp_init_func_early
(
struct
klp_object
*
obj
,
struct
klp_func
*
func
);
static
void
klp_init_object_early
(
struct
klp_patch
*
patch
,
struct
klp_object
*
obj
);
static
struct
klp_object
*
klp_alloc_object_dynamic
(
const
char
*
name
,
struct
klp_patch
*
patch
)
{
struct
klp_object
*
obj
;
...
...
@@ -442,7 +448,7 @@ static struct klp_object *klp_alloc_object_dynamic(const char *name)
}
}
INIT_LIST_HEAD
(
&
obj
->
func_list
);
klp_init_object_early
(
patch
,
obj
);
obj
->
dynamic
=
true
;
return
obj
;
...
...
@@ -471,6 +477,7 @@ static struct klp_func *klp_alloc_func_nop(struct klp_func *old_func,
}
}
klp_init_func_early
(
obj
,
func
);
/*
* func->new_func is same as func->old_func. These addresses are
* set when the object is loaded, see klp_init_object_loaded().
...
...
@@ -490,11 +497,9 @@ static int klp_add_object_nops(struct klp_patch *patch,
obj
=
klp_find_object
(
patch
,
old_obj
);
if
(
!
obj
)
{
obj
=
klp_alloc_object_dynamic
(
old_obj
->
name
);
obj
=
klp_alloc_object_dynamic
(
old_obj
->
name
,
patch
);
if
(
!
obj
)
return
-
ENOMEM
;
list_add_tail
(
&
obj
->
node
,
&
patch
->
obj_list
);
}
klp_for_each_func
(
old_obj
,
old_func
)
{
...
...
@@ -505,8 +510,6 @@ static int klp_add_object_nops(struct klp_patch *patch,
func
=
klp_alloc_func_nop
(
old_func
,
obj
);
if
(
!
func
)
return
-
ENOMEM
;
list_add_tail
(
&
func
->
node
,
&
obj
->
func_list
);
}
return
0
;
...
...
@@ -588,13 +591,7 @@ static void __klp_free_funcs(struct klp_object *obj, bool nops_only)
continue
;
list_del
(
&
func
->
node
);
/* Might be called from klp_init_patch() error path. */
if
(
func
->
kobj_added
)
{
kobject_put
(
&
func
->
kobj
);
}
else
if
(
func
->
nop
)
{
klp_free_func_nop
(
func
);
}
kobject_put
(
&
func
->
kobj
);
}
}
...
...
@@ -624,13 +621,7 @@ static void __klp_free_objects(struct klp_patch *patch, bool nops_only)
continue
;
list_del
(
&
obj
->
node
);
/* Might be called from klp_init_patch() error path. */
if
(
obj
->
kobj_added
)
{
kobject_put
(
&
obj
->
kobj
);
}
else
if
(
obj
->
dynamic
)
{
klp_free_object_dynamic
(
obj
);
}
kobject_put
(
&
obj
->
kobj
);
}
}
...
...
@@ -675,10 +666,8 @@ static void klp_free_patch_finish(struct klp_patch *patch)
* this is called when the patch gets disabled and it
* cannot get enabled again.
*/
if
(
patch
->
kobj_added
)
{
kobject_put
(
&
patch
->
kobj
);
wait_for_completion
(
&
patch
->
finish
);
}
kobject_put
(
&
patch
->
kobj
);
wait_for_completion
(
&
patch
->
finish
);
/* Put the module after the last access to struct klp_patch. */
if
(
!
patch
->
forced
)
...
...
@@ -700,8 +689,6 @@ static void klp_free_patch_work_fn(struct work_struct *work)
static
int
klp_init_func
(
struct
klp_object
*
obj
,
struct
klp_func
*
func
)
{
int
ret
;
if
(
!
func
->
old_name
)
return
-
EINVAL
;
...
...
@@ -724,13 +711,9 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func)
* object. If the user selects 0 for old_sympos, then 1 will be used
* since a unique symbol will be the first occurrence.
*/
ret
=
kobject_init_and_add
(
&
func
->
kobj
,
&
klp_ktype_func
,
&
obj
->
kobj
,
"%s,%lu"
,
func
->
old_name
,
func
->
old_sympos
?
func
->
old_sympos
:
1
);
if
(
!
ret
)
func
->
kobj_added
=
true
;
return
ret
;
return
kobject_add
(
&
func
->
kobj
,
&
obj
->
kobj
,
"%s,%lu"
,
func
->
old_name
,
func
->
old_sympos
?
func
->
old_sympos
:
1
);
}
/* Arches may override this to finish any remaining arch-specific tasks */
...
...
@@ -801,11 +784,9 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
klp_find_object_module
(
obj
);
name
=
klp_is_module
(
obj
)
?
obj
->
name
:
"vmlinux"
;
ret
=
kobject_init_and_add
(
&
obj
->
kobj
,
&
klp_ktype_object
,
&
patch
->
kobj
,
"%s"
,
name
);
ret
=
kobject_add
(
&
obj
->
kobj
,
&
patch
->
kobj
,
"%s"
,
name
);
if
(
ret
)
return
ret
;
obj
->
kobj_added
=
true
;
klp_for_each_func
(
obj
,
func
)
{
ret
=
klp_init_func
(
obj
,
func
);
...
...
@@ -819,6 +800,21 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
return
ret
;
}
static
void
klp_init_func_early
(
struct
klp_object
*
obj
,
struct
klp_func
*
func
)
{
kobject_init
(
&
func
->
kobj
,
&
klp_ktype_func
);
list_add_tail
(
&
func
->
node
,
&
obj
->
func_list
);
}
static
void
klp_init_object_early
(
struct
klp_patch
*
patch
,
struct
klp_object
*
obj
)
{
INIT_LIST_HEAD
(
&
obj
->
func_list
);
kobject_init
(
&
obj
->
kobj
,
&
klp_ktype_object
);
list_add_tail
(
&
obj
->
node
,
&
patch
->
obj_list
);
}
static
int
klp_init_patch_early
(
struct
klp_patch
*
patch
)
{
struct
klp_object
*
obj
;
...
...
@@ -829,7 +825,7 @@ static int klp_init_patch_early(struct klp_patch *patch)
INIT_LIST_HEAD
(
&
patch
->
list
);
INIT_LIST_HEAD
(
&
patch
->
obj_list
);
patch
->
kobj_added
=
false
;
kobject_init
(
&
patch
->
kobj
,
&
klp_ktype_patch
)
;
patch
->
enabled
=
false
;
patch
->
forced
=
false
;
INIT_WORK
(
&
patch
->
free_work
,
klp_free_patch_work_fn
);
...
...
@@ -839,13 +835,10 @@ static int klp_init_patch_early(struct klp_patch *patch)
if
(
!
obj
->
funcs
)
return
-
EINVAL
;
INIT_LIST_HEAD
(
&
obj
->
func_list
);
obj
->
kobj_added
=
false
;
list_add_tail
(
&
obj
->
node
,
&
patch
->
obj_list
);
klp_init_object_early
(
patch
,
obj
);
klp_for_each_func_static
(
obj
,
func
)
{
func
->
kobj_added
=
false
;
list_add_tail
(
&
func
->
node
,
&
obj
->
func_list
);
klp_init_func_early
(
obj
,
func
);
}
}
...
...
@@ -860,11 +853,9 @@ static int klp_init_patch(struct klp_patch *patch)
struct
klp_object
*
obj
;
int
ret
;
ret
=
kobject_init_and_add
(
&
patch
->
kobj
,
&
klp_ktype_patch
,
klp_root_kobj
,
"%s"
,
patch
->
mod
->
name
);
ret
=
kobject_add
(
&
patch
->
kobj
,
klp_root_kobj
,
"%s"
,
patch
->
mod
->
name
);
if
(
ret
)
return
ret
;
patch
->
kobj_added
=
true
;
if
(
patch
->
replace
)
{
ret
=
klp_add_nops
(
patch
);
...
...
@@ -926,9 +917,6 @@ static int __klp_enable_patch(struct klp_patch *patch)
if
(
WARN_ON
(
patch
->
enabled
))
return
-
EINVAL
;
if
(
!
patch
->
kobj_added
)
return
-
EINVAL
;
pr_notice
(
"enabling patch '%s'
\n
"
,
patch
->
mod
->
name
);
klp_init_transition
(
patch
,
KLP_PATCHED
);
...
...
@@ -1003,11 +991,10 @@ int klp_enable_patch(struct klp_patch *patch)
return
-
ENODEV
;
if
(
!
klp_have_reliable_stack
())
{
pr_
err
(
"This architecture doesn't have support for the livepatch consistency model.
\n
"
);
return
-
EOPNOTSUPP
;
pr_
warn
(
"This architecture doesn't have support for the livepatch consistency model.
\n
"
);
pr_warn
(
"The livepatch transition may never complete.
\n
"
)
;
}
mutex_lock
(
&
klp_mutex
);
ret
=
klp_init_patch_early
(
patch
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment