All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greentime Hu <green.hu@gmail.com>
To: greentime@andestech.com, linux-kernel@vger.kernel.org,
	arnd@arndb.de, linux-arch@vger.kernel.org, tglx@linutronix.de,
	jason@lakedaemon.net, marc.zyngier@arm.com, robh+dt@kernel.org,
	netdev@vger.kernel.org, deanbo422@gmail.com,
	devicetree@vger.kernel.org, viro@zeniv.linux.org.uk,
	dhowells@redhat.com, will.deacon@arm.com,
	daniel.lezcano@linaro.org, linux-serial@vger.kernel.org,
	geert.uytterhoeven@gmail.com, linus.walleij@linaro.org,
	mark.rutland@arm.com, greg@kroah.com, ren_guo@c-sky.com,
	pombredanne@nexb.com
Cc: green.hu@gmail.com, Vincent Chen <vincentc@andestech.com>
Subject: [PATCH v4 22/36] nds32: Loadable modules
Date: Mon, 18 Dec 2017 14:46:34 +0800	[thread overview]
Message-ID: <15da583d6ce554d676ffa28d1094674998d57e5d.1513577007.git.green.hu@gmail.com> (raw)
In-Reply-To: <cover.1513577007.git.green.hu@gmail.com>
In-Reply-To: <cover.1513577007.git.green.hu@gmail.com>

From: Greentime Hu <greentime@andestech.com>

This patch adds support for loadable modules.

Signed-off-by: Vincent Chen <vincentc@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
---
 arch/nds32/include/asm/module.h |   11 ++
 arch/nds32/kernel/module.c      |  286 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 297 insertions(+)
 create mode 100644 arch/nds32/include/asm/module.h
 create mode 100644 arch/nds32/kernel/module.c

diff --git a/arch/nds32/include/asm/module.h b/arch/nds32/include/asm/module.h
new file mode 100644
index 0000000..16cf9c7
--- /dev/null
+++ b/arch/nds32/include/asm/module.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef _ASM_NDS32_MODULE_H
+#define _ASM_NDS32_MODULE_H
+
+#include <asm-generic/module.h>
+
+#define MODULE_ARCH_VERMAGIC	"NDS32v3"
+
+#endif /* _ASM_NDS32_MODULE_H */
diff --git a/arch/nds32/kernel/module.c b/arch/nds32/kernel/module.c
new file mode 100644
index 0000000..714a6d6
--- /dev/null
+++ b/arch/nds32/kernel/module.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include <linux/module.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+
+#include <asm/pgtable.h>
+
+void *module_alloc(unsigned long size)
+{
+	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+				    GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
+				    __builtin_return_address(0));
+}
+
+void module_free(struct module *module, void *region)
+{
+	vfree(region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr * hdr,
+			      Elf_Shdr * sechdrs,
+			      char *secstrings, struct module *mod)
+{
+	return 0;
+}
+
+void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask,
+		unsigned int val_shift, unsigned int loc_mask,
+		unsigned int partial_in_place, unsigned int swap)
+{
+	unsigned int tmp = 0, tmp2 = 0;
+
+	__asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n"
+			     "\tbeqz\t%3, 1f\n"
+			     "\twsbh\t%0, %1\n"
+			     "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
+	    );
+
+	tmp2 = tmp & loc_mask;
+	if (partial_in_place) {
+		tmp &= (!loc_mask);
+		tmp =
+		    tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
+	} else {
+		tmp = tmp2 | ((val & val_mask) >> val_shift);
+	}
+
+	__asm__ __volatile__("\tbeqz\t%3, 2f\n"
+			     "\twsbh\t%0, %1\n"
+			     "2:\n"
+			     "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp),
+			     "r"(loc), "r"(swap)
+	    );
+}
+
+void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask,
+		unsigned int val_shift, unsigned int loc_mask,
+		unsigned int partial_in_place, unsigned int swap)
+{
+	unsigned int tmp = 0, tmp2 = 0;
+
+	__asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n"
+			     "\tbeqz\t%3, 1f\n"
+			     "\twsbh\t%0, %1\n"
+			     "\trotri\t%0, %1, 16\n"
+			     "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
+	    );
+
+	tmp2 = tmp & loc_mask;
+	if (partial_in_place) {
+		tmp &= (!loc_mask);
+		tmp =
+		    tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
+	} else {
+		tmp = tmp2 | ((val & val_mask) >> val_shift);
+	}
+
+	__asm__ __volatile__("\tbeqz\t%3, 2f\n"
+			     "\twsbh\t%0, %1\n"
+			     "\trotri\t%0, %1, 16\n"
+			     "2:\n"
+			     "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp),
+			     "r"(loc), "r"(swap)
+	    );
+}
+
+static inline int exceed_limit(int offset, unsigned int val_mask,
+			       struct module *module, Elf32_Rela * rel,
+			       unsigned int relindex, unsigned int reloc_order)
+{
+	int abs_off = offset < 0 ? ~offset : offset;
+
+	if (abs_off & (~val_mask)) {
+		pr_err("\n%s: relocation type %d out of range.\n"
+		       "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n",
+		       module->name, ELF32_R_TYPE(rel->r_info));
+		pr_err("section %d reloc %d offset 0x%x relative 0x%x.\n",
+		       relindex, reloc_order, rel->r_offset, offset);
+		return true;
+	}
+	return false;
+}
+
+#ifdef __NDS32_EL__
+#define NEED_SWAP 1
+#else
+#define NEED_SWAP 0
+#endif
+
+int
+apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
+		   unsigned int symindex, unsigned int relindex,
+		   struct module *module)
+{
+	Elf32_Shdr *symsec = sechdrs + symindex;
+	Elf32_Shdr *relsec = sechdrs + relindex;
+	Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
+	Elf32_Rela *rel = (void *)relsec->sh_addr;
+	unsigned int i;
+
+	for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
+		Elf32_Addr *loc;
+		Elf32_Sym *sym;
+		Elf32_Addr v;
+		s32 offset;
+
+		offset = ELF32_R_SYM(rel->r_info);
+		if (offset < 0
+		    || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
+			pr_err("%s: bad relocation\n", module->name);
+			pr_err("section %d reloc %d\n", relindex, i);
+			return -ENOEXEC;
+		}
+
+		sym = ((Elf32_Sym *) symsec->sh_addr) + offset;
+
+		if (rel->r_offset < 0
+		    || rel->r_offset > dstsec->sh_size - sizeof(u16)) {
+			pr_err("%s: out of bounds relocation\n", module->name);
+			pr_err("section %d reloc %d offset 0x%0x size %d\n",
+			       relindex, i, rel->r_offset, dstsec->sh_size);
+			return -ENOEXEC;
+		}
+
+		loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset);
+		v = sym->st_value + rel->r_addend;
+
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_NDS32_NONE:
+		case R_NDS32_INSN16:
+		case R_NDS32_LABEL:
+		case R_NDS32_LONGCALL1:
+		case R_NDS32_LONGCALL2:
+		case R_NDS32_LONGCALL3:
+		case R_NDS32_LONGCALL4:
+		case R_NDS32_LONGJUMP1:
+		case R_NDS32_LONGJUMP2:
+		case R_NDS32_LONGJUMP3:
+		case R_NDS32_9_FIXED_RELA:
+		case R_NDS32_15_FIXED_RELA:
+		case R_NDS32_17_FIXED_RELA:
+		case R_NDS32_25_FIXED_RELA:
+		case R_NDS32_LOADSTORE:
+		case R_NDS32_DWARF2_OP1_RELA:
+		case R_NDS32_DWARF2_OP2_RELA:
+		case R_NDS32_DWARF2_LEB_RELA:
+		case R_NDS32_RELA_NOP_MIX ... R_NDS32_RELA_NOP_MAX:
+			break;
+
+		case R_NDS32_32_RELA:
+			do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0);
+			break;
+
+		case R_NDS32_HI20_RELA:
+			do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0,
+				   NEED_SWAP);
+			break;
+
+		case R_NDS32_LO12S3_RELA:
+			do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0,
+				   NEED_SWAP);
+			break;
+
+		case R_NDS32_LO12S2_RELA:
+			do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0,
+				   NEED_SWAP);
+			break;
+
+		case R_NDS32_LO12S1_RELA:
+			do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0,
+				   NEED_SWAP);
+			break;
+
+		case R_NDS32_LO12S0_RELA:
+		case R_NDS32_LO12S0_ORI_RELA:
+			do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0,
+				   NEED_SWAP);
+			break;
+
+		case R_NDS32_9_PCREL_RELA:
+			if (exceed_limit
+			    ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
+			     relindex, i))
+				return -ENOEXEC;
+			do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
+				   0xffffff00, 0, NEED_SWAP);
+			break;
+
+		case R_NDS32_15_PCREL_RELA:
+			if (exceed_limit
+			    ((v - (Elf32_Addr) loc), 0x00003fff, module, rel,
+			     relindex, i))
+				return -ENOEXEC;
+			do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1,
+				   0xffffc000, 0, NEED_SWAP);
+			break;
+
+		case R_NDS32_17_PCREL_RELA:
+			if (exceed_limit
+			    ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel,
+			     relindex, i))
+				return -ENOEXEC;
+			do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1,
+				   0xffff0000, 0, NEED_SWAP);
+			break;
+
+		case R_NDS32_25_PCREL_RELA:
+			if (exceed_limit
+			    ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel,
+			     relindex, i))
+				return -ENOEXEC;
+			do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1,
+				   0xff000000, 0, NEED_SWAP);
+			break;
+		case R_NDS32_WORD_9_PCREL_RELA:
+			if (exceed_limit
+			    ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
+			     relindex, i))
+				return -ENOEXEC;
+			do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
+				   0xffffff00, 0, NEED_SWAP);
+			break;
+
+		case R_NDS32_SDA15S3_RELA:
+		case R_NDS32_SDA15S2_RELA:
+		case R_NDS32_SDA15S1_RELA:
+		case R_NDS32_SDA15S0_RELA:
+			pr_err("%s: unsupported relocation type %d.\n",
+			       module->name, ELF32_R_TYPE(rel->r_info));
+			pr_err
+			    ("Small data section access doesn't work in the kernel space; "
+			     "please rebuild the kernel module with gcc option -mcmodel=large.\n");
+			pr_err("section %d reloc %d offset 0x%x size %d\n",
+			       relindex, i, rel->r_offset, dstsec->sh_size);
+			break;
+
+		default:
+			pr_err("%s: unsupported relocation type %d.\n",
+			       module->name, ELF32_R_TYPE(rel->r_info));
+			pr_err("section %d reloc %d offset 0x%x size %d\n",
+			       relindex, i, rel->r_offset, dstsec->sh_size);
+		}
+	}
+	return 0;
+}
+
+int
+apply_relocate(Elf32_Shdr * sechdrs, const char *strtab,
+	       unsigned int symindex, unsigned int relsec,
+	       struct module *module)
+{
+	return 0;
+}
+
+int
+module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs,
+		struct module *module)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
-- 
1.7.9.5

  parent reply	other threads:[~2017-12-18  7:13 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-18  6:46 [PATCH v4 00/36] Andes(nds32) Linux Kernel Greentime Hu
2017-12-18  6:46 ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 01/36] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU Greentime Hu
2017-12-20 10:09   ` kbuild test robot
2017-12-20 10:09     ` kbuild test robot
2017-12-20 10:09     ` kbuild test robot
2017-12-22 14:38     ` Greentime Hu
2017-12-22 14:38       ` Greentime Hu
2017-12-20 10:10   ` kbuild test robot
2017-12-20 10:10     ` kbuild test robot
2017-12-20 10:10     ` kbuild test robot
2017-12-22 14:40     ` Greentime Hu
2017-12-22 14:40       ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 02/36] earlycon: add reg-offset to physical address before mapping Greentime Hu
2017-12-18  6:46 ` [PATCH v4 03/36] nds32: Assembly macros and definitions Greentime Hu
2017-12-18  6:46 ` [PATCH v4 04/36] nds32: Kernel booting and initialization Greentime Hu
2017-12-19 22:01   ` Randy Dunlap
2017-12-19 22:01     ` Randy Dunlap
2017-12-20  2:35     ` Greentime Hu
2017-12-20  2:35       ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 05/36] nds32: Exception handling Greentime Hu
2017-12-18  6:46 ` [PATCH v4 06/36] nds32: MMU definitions Greentime Hu
2017-12-18  6:46   ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 07/36] nds32: MMU initialization Greentime Hu
2017-12-18  6:46 ` [PATCH v4 08/36] nds32: MMU fault handling and page table management Greentime Hu
2017-12-18  6:46 ` [PATCH v4 09/36] nds32: Cache and TLB routines Greentime Hu
2017-12-18  6:46 ` [PATCH v4 10/36] nds32: Process management Greentime Hu
2017-12-18  6:46 ` [PATCH v4 11/36] nds32: IRQ handling Greentime Hu
2017-12-18  6:46 ` [PATCH v4 12/36] nds32: Atomic operations Greentime Hu
2017-12-18  6:46 ` [PATCH v4 13/36] nds32: Device specific operations Greentime Hu
2017-12-18 11:26   ` Arnd Bergmann
2017-12-18 11:26     ` Arnd Bergmann
2017-12-18 11:44     ` Greentime Hu
2017-12-18 11:44       ` Greentime Hu
2017-12-18 11:44       ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 14/36] nds32: DMA mapping API Greentime Hu
2017-12-18  6:46 ` [PATCH v4 15/36] nds32: ELF definitions Greentime Hu
2017-12-18  6:46   ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 16/36] nds32: System calls handling Greentime Hu
2017-12-18 11:19   ` Arnd Bergmann
2017-12-18 11:19     ` Arnd Bergmann
2017-12-19  2:10     ` Vincent Chen
2017-12-19  2:10       ` Vincent Chen
2017-12-18  6:46 ` [PATCH v4 17/36] nds32: VDSO support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 18/36] nds32: Signal handling support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 19/36] nds32: Library functions Greentime Hu
2017-12-18  6:46 ` [PATCH v4 20/36] nds32: Debugging support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 21/36] nds32: L2 cache support Greentime Hu
2017-12-18  6:46 ` Greentime Hu [this message]
2017-12-18  6:46 ` [PATCH v4 23/36] nds32: Generic timers support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 24/36] nds32: Device tree support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 25/36] nds32: Miscellaneous header files Greentime Hu
2017-12-18 11:13   ` Arnd Bergmann
2017-12-18 11:13     ` Arnd Bergmann
2017-12-19  5:34     ` Greentime Hu
2017-12-19  5:34       ` Greentime Hu
2017-12-19  5:34       ` Greentime Hu
2017-12-19  9:54       ` Arnd Bergmann
2017-12-19  9:54         ` Arnd Bergmann
2017-12-19  9:54         ` Arnd Bergmann
2017-12-20  2:34         ` Greentime Hu
2017-12-20  2:34           ` Greentime Hu
2017-12-20  2:34           ` Greentime Hu
2017-12-18  6:46 ` [PATCH v4 26/36] nds32: defconfig Greentime Hu
2017-12-18  6:46 ` [PATCH v4 27/36] nds32: Build infrastructure Greentime Hu
2017-12-18  6:46 ` [PATCH v4 28/36] MAINTAINERS: Add nds32 Greentime Hu
2017-12-18  6:46 ` [PATCH v4 29/36] dt-bindings: nds32 CPU Bindings Greentime Hu
2017-12-18  6:46 ` [PATCH v4 30/36] dt-bindings: nds32 SoC Bindings Greentime Hu
2017-12-18  6:46 ` [PATCH v4 31/36] dt-bindings: interrupt-controller: Andestech Internal Vector Interrupt Controller Greentime Hu
2017-12-18  6:46 ` [PATCH v4 32/36] irqchip: Andestech Internal Vector Interrupt Controller driver Greentime Hu
2017-12-18  6:46 ` [PATCH v4 33/36] net: faraday add nds32 support Greentime Hu
2017-12-20  9:54   ` kbuild test robot
2017-12-20  9:54     ` kbuild test robot
2017-12-20  9:54     ` kbuild test robot
2017-12-20  9:58     ` Geert Uytterhoeven
2017-12-20  9:58       ` Geert Uytterhoeven
2017-12-20  9:58       ` Geert Uytterhoeven
2017-12-20 10:34       ` Greentime Hu
2017-12-20 10:34         ` Greentime Hu
2017-12-20 10:34         ` Greentime Hu
2017-12-20 11:03   ` kbuild test robot
2017-12-20 11:03     ` kbuild test robot
2017-12-20 11:03     ` kbuild test robot
2017-12-18  6:46 ` [PATCH v4 34/36] clocksource/drivers/atcpit100: Add andestech atcpit100 timer Greentime Hu
2017-12-18  6:46 ` [PATCH v4 35/36] clocksource/drivers/atcpit100: VDSO support Greentime Hu
2017-12-18  6:46 ` [PATCH v4 36/36] dt-bindings: timer: Add andestech atcpit100 timer binding doc Greentime Hu
2018-02-14 14:56 ` [PATCH v4 00/36] Andes(nds32) Linux Kernel Arnd Bergmann
2018-02-14 14:56   ` Arnd Bergmann
2018-02-14 14:56   ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15da583d6ce554d676ffa28d1094674998d57e5d.1513577007.git.green.hu@gmail.com \
    --to=green.hu@gmail.com \
    --cc=arnd@arndb.de \
    --cc=daniel.lezcano@linaro.org \
    --cc=deanbo422@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dhowells@redhat.com \
    --cc=geert.uytterhoeven@gmail.com \
    --cc=greentime@andestech.com \
    --cc=greg@kroah.com \
    --cc=jason@lakedaemon.net \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=netdev@vger.kernel.org \
    --cc=pombredanne@nexb.com \
    --cc=ren_guo@c-sky.com \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=vincentc@andestech.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.