diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c index 8da0f42..7fb2006 100644 --- a/kmod/patch/livepatch-patch-hook.c +++ b/kmod/patch/livepatch-patch-hook.c @@ -35,6 +35,10 @@ #define UTS_UBUNTU_RELEASE_ABI 0 #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) +#define NEED_KLP_RELOCS +#endif + /* * There are quite a few similar structures at play in this file: * - livepatch.h structs prefixed with klp_* @@ -83,7 +87,9 @@ static struct patch_object *patch_alloc_new_object(const char *name) if (!object) return NULL; INIT_LIST_HEAD(&object->funcs); +#ifdef NEED_KLP_RELOCS INIT_LIST_HEAD(&object->relocs); +#endif if (strcmp(name, "vmlinux")) object->name = name; list_add(&object->list, &patch_objects); @@ -123,6 +129,7 @@ static int patch_add_func_to_object(struct kpatch_patch_func *kfunc) return 0; } +#ifdef NEED_KLP_RELOCS static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela) { struct patch_reloc *reloc; @@ -143,11 +150,14 @@ static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela) object->relocs_nr++; return 0; } +#endif static void patch_free_scaffold(void) { struct patch_func *func, *safefunc; - struct patch_reloc *reloc, *safereloc; struct patch_object *object, *safeobject; +#ifdef NEED_KLP_RELOCS + struct patch_reloc *reloc, *safereloc; +#endif list_for_each_entry_safe(object, safeobject, &patch_objects, list) { list_for_each_entry_safe(func, safefunc, @@ -155,11 +165,13 @@ static void patch_free_scaffold(void) { list_del(&func->list); kfree(func); } +#ifdef NEED_KLP_RELOCS list_for_each_entry_safe(reloc, safereloc, &object->relocs, list) { list_del(&reloc->list); kfree(reloc); } +#endif list_del(&object->list); kfree(object); } @@ -173,8 +185,10 @@ static void patch_free_livepatch(struct klp_patch *patch) for (object = patch->objs; object && object->funcs; object++) { if (object->funcs) kfree(object->funcs); +#ifdef NEED_KLP_RELOCS if (object->relocs) kfree(object->relocs); +#endif } if (patch->objs) kfree(patch->objs); @@ -183,19 +197,23 @@ static void patch_free_livepatch(struct klp_patch *patch) } extern struct kpatch_patch_func __kpatch_funcs[], __kpatch_funcs_end[]; +#ifdef NEED_KLP_RELOCS extern struct kpatch_patch_dynrela __kpatch_dynrelas[], __kpatch_dynrelas_end[]; +#endif static int __init patch_init(void) { struct kpatch_patch_func *kfunc; - struct kpatch_patch_dynrela *kdynrela; struct klp_object *lobjects, *lobject; struct klp_func *lfuncs, *lfunc; - struct klp_reloc *lrelocs, *lreloc; struct patch_object *object; struct patch_func *func; - struct patch_reloc *reloc; int ret = 0, i, j; +#ifdef NEED_KLP_RELOCS + struct kpatch_patch_dynrela *kdynrela; + struct patch_reloc *reloc; + struct klp_reloc *lrelocs, *lreloc; +#endif /* organize functions and relocs by object in scaffold */ for (kfunc = __kpatch_funcs; @@ -206,6 +224,7 @@ static int __init patch_init(void) goto out; } +#ifdef NEED_KLP_RELOCS for (kdynrela = __kpatch_dynrelas; kdynrela != __kpatch_dynrelas_end; kdynrela++) { @@ -213,6 +232,7 @@ static int __init patch_init(void) if (ret) goto out; } +#endif /* past this point, only possible return code is -ENOMEM */ ret = -ENOMEM; @@ -254,6 +274,7 @@ static int __init patch_init(void) j++; } +#ifdef NEED_KLP_RELOCS lrelocs = kzalloc(sizeof(struct klp_reloc) * (object->relocs_nr+1), GFP_KERNEL); if (!lrelocs) @@ -270,13 +291,14 @@ static int __init patch_init(void) lreloc->sympos = reloc->kdynrela->sympos; #else lreloc->val = reloc->kdynrela->src; -#endif +#endif /* 4.5.0 */ lreloc->type = reloc->kdynrela->type; lreloc->name = reloc->kdynrela->name; lreloc->addend = reloc->kdynrela->addend; lreloc->external = reloc->kdynrela->external; j++; } +#endif /* 4.7.0 */ i++; }