From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965349AbeALT4B (ORCPT + 1 other); Fri, 12 Jan 2018 14:56:01 -0500 Received: from mx0b-00190b01.pphosted.com ([67.231.157.127]:39358 "EHLO mx0b-00190b01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965198AbeALTz4 (ORCPT ); Fri, 12 Jan 2018 14:55:56 -0500 From: Jason Baron To: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org Cc: jpoimboe@redhat.com, jeyu@kernel.org, jikos@kernel.org, mbenes@suse.cz, pmladek@suse.com Subject: [PATCH v5 2/3] livepatch: shuffle core.c function order Date: Fri, 12 Jan 2018 14:55:15 -0500 Message-Id: X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-01-12_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1801120267 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-01-12_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1801120267 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: In preparation for __klp_enable_patch() to call a number of 'static' functions, in a subsequent patch, move them earlier in core.c. This patch should be a nop from a functional pov. Signed-off-by: Jason Baron Cc: Josh Poimboeuf Cc: Jessica Yu Cc: Jiri Kosina Cc: Miroslav Benes Cc: Petr Mladek --- kernel/livepatch/core.c | 352 ++++++++++++++++++++++++------------------------ 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 49be67c..5f1de35 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -278,6 +278,182 @@ static int klp_write_object_relocations(struct module *pmod, return ret; } +static void klp_kobj_release_object(struct kobject *kobj) +{ +} + +static struct kobj_type klp_ktype_object = { + .release = klp_kobj_release_object, + .sysfs_ops = &kobj_sysfs_ops, +}; + +static void klp_kobj_release_func(struct kobject *kobj) +{ +} + +static struct kobj_type klp_ktype_func = { + .release = klp_kobj_release_func, + .sysfs_ops = &kobj_sysfs_ops, +}; + +/* + * Free all functions' kobjects in the array up to some limit. When limit is + * NULL, all kobjects are freed. + */ +static void klp_free_funcs_limited(struct klp_object *obj, + struct klp_func *limit) +{ + struct klp_func *func; + + for (func = obj->funcs; func->old_name && func != limit; func++) + kobject_put(&func->kobj); +} + +/* Clean up when a patched object is unloaded */ +static void klp_free_object_loaded(struct klp_object *obj) +{ + struct klp_func *func; + + obj->mod = NULL; + + klp_for_each_func(obj, func) + func->old_addr = 0; +} + +/* + * Free all objects' kobjects in the array up to some limit. When limit is + * NULL, all kobjects are freed. + */ +static void klp_free_objects_limited(struct klp_patch *patch, + struct klp_object *limit) +{ + struct klp_object *obj; + + for (obj = patch->objs; obj->funcs && obj != limit; obj++) { + klp_free_funcs_limited(obj, NULL); + kobject_put(&obj->kobj); + } +} + +static void klp_free_patch(struct klp_patch *patch) +{ + klp_free_objects_limited(patch, NULL); + if (!list_empty(&patch->list)) + list_del(&patch->list); +} + +static int klp_init_func(struct klp_object *obj, struct klp_func *func) +{ + if (!func->old_name || !func->new_func) + return -EINVAL; + + INIT_LIST_HEAD(&func->stack_node); + func->patched = false; + func->transition = false; + list_add(&func->func_entry, &obj->func_list); + + /* The format for the sysfs directory is where sympos + * is the nth occurrence of this symbol in kallsyms for the patched + * object. If the user selects 0 for old_sympos, then 1 will be used + * since a unique symbol will be the first occurrence. + */ + return kobject_init_and_add(&func->kobj, &klp_ktype_func, + &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 */ +void __weak arch_klp_init_object_loaded(struct klp_patch *patch, + struct klp_object *obj) +{ +} + +/* parts of the initialization that is done only when the object is loaded */ +static int klp_init_object_loaded(struct klp_patch *patch, + struct klp_object *obj) +{ + struct klp_func *func; + int ret; + + module_disable_ro(patch->mod); + ret = klp_write_object_relocations(patch->mod, obj); + if (ret) { + module_enable_ro(patch->mod, true); + return ret; + } + + arch_klp_init_object_loaded(patch, obj); + module_enable_ro(patch->mod, true); + + klp_for_each_func(obj, func) { + ret = klp_find_object_symbol(obj->name, func->old_name, + func->old_sympos, + &func->old_addr); + if (ret) + return ret; + + ret = kallsyms_lookup_size_offset(func->old_addr, + &func->old_size, NULL); + if (!ret) { + pr_err("kallsyms size lookup failed for '%s'\n", + func->old_name); + return -ENOENT; + } + + ret = kallsyms_lookup_size_offset((unsigned long)func->new_func, + &func->new_size, NULL); + if (!ret) { + pr_err("kallsyms size lookup failed for '%s' replacement\n", + func->old_name); + return -ENOENT; + } + } + + return 0; +} + +static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) +{ + struct klp_func *func; + int ret; + const char *name; + + if (!obj->funcs) + return -EINVAL; + + obj->patched = false; + obj->mod = NULL; + + 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); + if (ret) + return ret; + + list_add(&obj->obj_entry, &patch->obj_list); + INIT_LIST_HEAD(&obj->func_list); + klp_for_each_func_static(obj, func) { + ret = klp_init_func(obj, func); + if (ret) + goto free; + } + + if (klp_is_object_loaded(obj)) { + ret = klp_init_object_loaded(patch, obj); + if (ret) + goto free; + } + + return 0; + +free: + klp_free_funcs_limited(obj, func); + kobject_put(&obj->kobj); + return ret; +} + static int __klp_disable_patch(struct klp_patch *patch) { struct klp_object *obj; @@ -605,182 +781,6 @@ static struct kobj_type klp_ktype_patch = { .default_attrs = klp_patch_attrs, }; -static void klp_kobj_release_object(struct kobject *kobj) -{ -} - -static struct kobj_type klp_ktype_object = { - .release = klp_kobj_release_object, - .sysfs_ops = &kobj_sysfs_ops, -}; - -static void klp_kobj_release_func(struct kobject *kobj) -{ -} - -static struct kobj_type klp_ktype_func = { - .release = klp_kobj_release_func, - .sysfs_ops = &kobj_sysfs_ops, -}; - -/* - * Free all functions' kobjects in the array up to some limit. When limit is - * NULL, all kobjects are freed. - */ -static void klp_free_funcs_limited(struct klp_object *obj, - struct klp_func *limit) -{ - struct klp_func *func; - - for (func = obj->funcs; func->old_name && func != limit; func++) - kobject_put(&func->kobj); -} - -/* Clean up when a patched object is unloaded */ -static void klp_free_object_loaded(struct klp_object *obj) -{ - struct klp_func *func; - - obj->mod = NULL; - - klp_for_each_func(obj, func) - func->old_addr = 0; -} - -/* - * Free all objects' kobjects in the array up to some limit. When limit is - * NULL, all kobjects are freed. - */ -static void klp_free_objects_limited(struct klp_patch *patch, - struct klp_object *limit) -{ - struct klp_object *obj; - - for (obj = patch->objs; obj->funcs && obj != limit; obj++) { - klp_free_funcs_limited(obj, NULL); - kobject_put(&obj->kobj); - } -} - -static void klp_free_patch(struct klp_patch *patch) -{ - klp_free_objects_limited(patch, NULL); - if (!list_empty(&patch->list)) - list_del(&patch->list); -} - -static int klp_init_func(struct klp_object *obj, struct klp_func *func) -{ - if (!func->old_name || !func->new_func) - return -EINVAL; - - INIT_LIST_HEAD(&func->stack_node); - func->patched = false; - func->transition = false; - list_add(&func->func_entry, &obj->func_list); - - /* The format for the sysfs directory is where sympos - * is the nth occurrence of this symbol in kallsyms for the patched - * object. If the user selects 0 for old_sympos, then 1 will be used - * since a unique symbol will be the first occurrence. - */ - return kobject_init_and_add(&func->kobj, &klp_ktype_func, - &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 */ -void __weak arch_klp_init_object_loaded(struct klp_patch *patch, - struct klp_object *obj) -{ -} - -/* parts of the initialization that is done only when the object is loaded */ -static int klp_init_object_loaded(struct klp_patch *patch, - struct klp_object *obj) -{ - struct klp_func *func; - int ret; - - module_disable_ro(patch->mod); - ret = klp_write_object_relocations(patch->mod, obj); - if (ret) { - module_enable_ro(patch->mod, true); - return ret; - } - - arch_klp_init_object_loaded(patch, obj); - module_enable_ro(patch->mod, true); - - klp_for_each_func(obj, func) { - ret = klp_find_object_symbol(obj->name, func->old_name, - func->old_sympos, - &func->old_addr); - if (ret) - return ret; - - ret = kallsyms_lookup_size_offset(func->old_addr, - &func->old_size, NULL); - if (!ret) { - pr_err("kallsyms size lookup failed for '%s'\n", - func->old_name); - return -ENOENT; - } - - ret = kallsyms_lookup_size_offset((unsigned long)func->new_func, - &func->new_size, NULL); - if (!ret) { - pr_err("kallsyms size lookup failed for '%s' replacement\n", - func->old_name); - return -ENOENT; - } - } - - return 0; -} - -static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) -{ - struct klp_func *func; - int ret; - const char *name; - - if (!obj->funcs) - return -EINVAL; - - obj->patched = false; - obj->mod = NULL; - - 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); - if (ret) - return ret; - - list_add(&obj->obj_entry, &patch->obj_list); - INIT_LIST_HEAD(&obj->func_list); - klp_for_each_func_static(obj, func) { - ret = klp_init_func(obj, func); - if (ret) - goto free; - } - - if (klp_is_object_loaded(obj)) { - ret = klp_init_object_loaded(patch, obj); - if (ret) - goto free; - } - - return 0; - -free: - klp_free_funcs_limited(obj, func); - kobject_put(&obj->kobj); - return ret; -} - static int klp_init_patch(struct klp_patch *patch) { struct klp_object *obj; -- 2.6.1