Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion arch/riscv/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,38 @@ static const struct relocation_handlers reloc_handlers[] = {
/* 192-255 nonstandard ABI extensions */
};

static void
cleanup_accumulated_relocations(struct hlist_head **relocation_hashtable,
struct list_head *used_buckets_list)
{
/*
* Clean up accumulated relocations without applying them.
*/
struct used_bucket *bucket_iter;
struct used_bucket *bucket_iter_tmp;
struct relocation_head *rel_head_iter;
struct hlist_node *rel_head_iter_tmp;
struct relocation_entry *rel_entry_iter;
struct relocation_entry *rel_entry_iter_tmp;

list_for_each_entry_safe(bucket_iter, bucket_iter_tmp,
used_buckets_list, head) {
hlist_for_each_entry_safe(rel_head_iter, rel_head_iter_tmp,
bucket_iter->bucket, node) {
list_for_each_entry_safe(rel_entry_iter,
rel_entry_iter_tmp,
&rel_head_iter->rel_entry,
head) {
kfree(rel_entry_iter);
}
kfree(rel_head_iter);
}
kfree(bucket_iter);
}

kvfree(*relocation_hashtable);
}

static void
process_accumulated_relocations(struct module *me,
struct hlist_head **relocation_hashtable,
Expand Down Expand Up @@ -803,6 +835,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
continue;
pr_warn("%s: Unknown symbol %s\n",
me->name, strtab + sym->st_name);
cleanup_accumulated_relocations(&relocation_hashtable,
&used_buckets_list);
return -ENOENT;
}

Expand All @@ -816,6 +850,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
if (!handler) {
pr_err("%s: Unknown relocation type %u\n",
me->name, type);
cleanup_accumulated_relocations(&relocation_hashtable,
&used_buckets_list);
return -EINVAL;
}

Expand Down Expand Up @@ -869,6 +905,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
pr_err(
"%s: Can not find HI20 relocation information\n",
me->name);
cleanup_accumulated_relocations(&relocation_hashtable,
&used_buckets_list);
return -EINVAL;
}

Expand All @@ -883,8 +921,12 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
&used_buckets_list);
else
res = handler(me, location, v);
if (res)

if (res) {
cleanup_accumulated_relocations(&relocation_hashtable,
&used_buckets_list);
return res;
}
}

process_accumulated_relocations(me, &relocation_hashtable,
Expand Down