Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1274584 > unrolled thread
| Started by | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| First post | 2015-11-21 02:30 +0100 |
| Last post | 2015-11-21 21:50 +0100 |
| Articles | 20 on this page of 58 — 8 participants |
Back to article view | Back to linux.kernel
[RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-21 02:30 +0100
[RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Stephen Boyd <sboyd@codeaurora.org> - 2015-11-21 02:30 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-21 11:20 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Steven Rostedt <rostedt@goodmis.org> - 2015-11-23 22:00 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 22:00 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-23 22:10 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 22:20 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-23 22:40 +0100
Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM Stephen Boyd <sboyd@codeaurora.org> - 2015-11-24 02:10 +0100
[RFC/PATCH 1/3] scripts: Allow recordmcount to be used without tracing enabled Stephen Boyd <sboyd@codeaurora.org> - 2015-11-21 02:30 +0100
[RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-21 02:30 +0100
Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions Måns Rullgård <mans@mansr.com> - 2015-11-21 13:00 +0100
Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 22:00 +0100
Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions Måns Rullgård <mans@mansr.com> - 2015-11-23 22:00 +0100
Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 22:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-21 21:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-21 22:10 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-21 23:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 00:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 00:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Peter Maydell <peter.maydell@linaro.org> - 2015-11-22 14:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 20:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-22 20:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-22 20:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 21:00 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-22 21:10 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 21:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-22 21:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-22 22:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Nicolas Pitre <nicolas.pitre@linaro.org> - 2015-11-23 03:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-23 09:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Christopher Covington <cov@codeaurora.org> - 2015-11-23 15:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-23 16:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 21:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-23 22:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-23 22:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-23 23:00 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-24 00:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-24 11:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-24 13:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-24 14:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-25 03:00 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-25 08:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-24 01:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-24 10:00 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-24 11:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 11:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-24 13:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-24 13:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Måns Rullgård <mans@mansr.com> - 2015-11-24 15:10 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 15:10 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 13:30 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 11:50 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Stephen Boyd <sboyd@codeaurora.org> - 2015-11-24 21:10 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 21:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-24 22:20 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-11-24 11:40 +0100
Re: [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions Arnd Bergmann <arnd@arndb.de> - 2015-11-21 21:50 +0100
Page 1 of 3 [1] 2 3 Next page →
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-21 02:30 +0100 |
| Subject | [RFC/PATCH 0/3] ARM: Use udiv/sdiv for __aeabi_{u}idiv library functions |
| Message-ID | <qx5a1-6MK-1@gated-at.bofh.it> |
This is a respin of a patch series from about a year ago[1]. I realized
that we already had most of the code in recordmcount to figure out
where we make calls to particular functions, so recording where
we make calls to the integer division functions should be easy enough
to add support for in the same codepaths. Looking back on the thread
it seems like Mans was thinking along the same lines, although it wasn't
obvious to me back then or even over the last few days when I wrote this.
This series extends recordmcount to record the locations of the calls
to the library functions on ARM builds, and puts those locations into a
table that we use to patch instructions at boot. The first two patches
are the recordmcount changes, while the last patch implements the runtime
patching for modules and kernel code. The module part also hooks into the
relocation patching code we already have.
The RFC tag is because I'm thinking of splitting the recordmcount changes
into a new program based on recordmcount so that we don't drag in a lot
of corner cases and stuff when we don't need to. I suspect it will be
cleaner that way too. Does anyone prefer one way or the other?
Comments/feedback appreciated.
[1] http://lkml.kernel.org/r/1383951632-6090-1-git-send-email-sboyd@codeaurora.org
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Måns Rullgård <mans@mansr.com>
Stephen Boyd (3):
scripts: Allow recordmcount to be used without tracing enabled
recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM
ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions
Makefile | 7 +
arch/arm/Kconfig | 14 ++
arch/arm/kernel/module.c | 44 ++++++
arch/arm/kernel/setup.c | 34 +++++
arch/arm/kernel/vmlinux.lds.S | 13 ++
kernel/trace/Kconfig | 4 +
scripts/Makefile.build | 15 +-
scripts/recordmcount.c | 10 +-
scripts/recordmcount.h | 337 +++++++++++++++++++++++++++++++++---------
scripts/recordmcount.pl | 11 +-
10 files changed, 406 insertions(+), 83 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-21 02:30 +0100 |
| Subject | [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qx5a1-6MK-3@gated-at.bofh.it> |
| In reply to | #1274584 |
The ARM compiler inserts calls to __aeabi_uidiv() and
__aeabi_idiv() when it needs to perform division on signed and
unsigned integers. If a processor has support for the udiv and
sdiv division instructions the calls to these support routines
can be replaced with those instructions. Therefore, record the
location of calls to these library functions into two sections
(one for udiv and one for sdiv) similar to how we trace calls to
mcount. When the kernel boots up it will check to see if the
processor supports the instructions and then patch the call sites
with the instruction.
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Måns Rullgård <mans@mansr.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
scripts/recordmcount.h | 335 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 269 insertions(+), 66 deletions(-)
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index 6e196dba748d..cab91ffc82a6 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -18,11 +18,13 @@
*
* Licensed under the GNU General Public License, version 2 (GPLv2).
*/
+#undef append_section
#undef append_func
#undef is_fake_mcount
#undef fn_is_fake_mcount
#undef MIPS_is_fake_mcount
#undef mcount_adjust
+#undef add_relocation
#undef sift_rel_mcount
#undef nop_mcount
#undef find_secsym_ndx
@@ -30,6 +32,7 @@
#undef has_rel_mcount
#undef tot_relsize
#undef get_mcountsym
+#undef get_arm_sym
#undef get_sym_str_and_relp
#undef do_func
#undef Elf_Addr
@@ -52,7 +55,9 @@
#undef _size
#ifdef RECORD_MCOUNT_64
+# define append_section append_section64
# define append_func append64
+# define add_relocation add_relocation_64
# define sift_rel_mcount sift64_rel_mcount
# define nop_mcount nop_mcount_64
# define find_secsym_ndx find64_secsym_ndx
@@ -62,6 +67,7 @@
# define get_sym_str_and_relp get_sym_str_and_relp_64
# define do_func do64
# define get_mcountsym get_mcountsym_64
+# define get_arm_sym get_arm_sym_64
# define is_fake_mcount is_fake_mcount64
# define fn_is_fake_mcount fn_is_fake_mcount64
# define MIPS_is_fake_mcount MIPS64_is_fake_mcount
@@ -85,7 +91,9 @@
# define _align 7u
# define _size 8
#else
+# define append_section append_section32
# define append_func append32
+# define add_relocation add_relocation_32
# define sift_rel_mcount sift32_rel_mcount
# define nop_mcount nop_mcount_32
# define find_secsym_ndx find32_secsym_ndx
@@ -95,6 +103,7 @@
# define get_sym_str_and_relp get_sym_str_and_relp_32
# define do_func do32
# define get_mcountsym get_mcountsym_32
+# define get_arm_sym get_arm_sym_32
# define is_fake_mcount is_fake_mcount32
# define fn_is_fake_mcount fn_is_fake_mcount32
# define MIPS_is_fake_mcount MIPS32_is_fake_mcount
@@ -174,6 +183,62 @@ static int MIPS_is_fake_mcount(Elf_Rel const *rp)
return is_fake;
}
+static void append_section(uint_t const *const mloc0,
+ uint_t const *const mlocp,
+ Elf_Rel const *const mrel0,
+ Elf_Rel const *const mrelp,
+ char const *name,
+ unsigned int const rel_entsize,
+ unsigned int const symsec_sh_link,
+ uint_t *name_offp,
+ uint_t *tp,
+ unsigned *shnump
+ )
+{
+ Elf_Shdr mcsec;
+ uint_t name_off = *name_offp;
+ uint_t t = *tp;
+ uint_t loc_diff = (void *)mlocp - (void *)mloc0;
+ uint_t rel_diff = (void *)mrelp - (void *)mrel0;
+ unsigned shnum = *shnump;
+
+ mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel")
+ + name_off);
+ mcsec.sh_type = w(SHT_PROGBITS);
+ mcsec.sh_flags = _w(SHF_ALLOC);
+ mcsec.sh_addr = 0;
+ mcsec.sh_offset = _w(t);
+ mcsec.sh_size = _w(loc_diff);
+ mcsec.sh_link = 0;
+ mcsec.sh_info = 0;
+ mcsec.sh_addralign = _w(_size);
+ mcsec.sh_entsize = _w(_size);
+ uwrite(fd_map, &mcsec, sizeof(mcsec));
+ t += loc_diff;
+
+ mcsec.sh_name = w(name_off);
+ mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
+ ? w(SHT_RELA)
+ : w(SHT_REL);
+ mcsec.sh_flags = 0;
+ mcsec.sh_addr = 0;
+ mcsec.sh_offset = _w(t);
+ mcsec.sh_size = _w(rel_diff);
+ mcsec.sh_link = w(symsec_sh_link);
+ mcsec.sh_info = w(shnum);
+ mcsec.sh_addralign = _w(_size);
+ mcsec.sh_entsize = _w(rel_entsize);
+ uwrite(fd_map, &mcsec, sizeof(mcsec));
+ t += rel_diff;
+
+ shnum += 2;
+ name_off += strlen(name) + 1;
+
+ *tp = t;
+ *shnump = shnum;
+ *name_offp = name_off;
+}
+
/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
static void append_func(Elf_Ehdr *const ehdr,
Elf_Shdr *const shstr,
@@ -181,20 +246,50 @@ static void append_func(Elf_Ehdr *const ehdr,
uint_t const *const mlocp,
Elf_Rel const *const mrel0,
Elf_Rel const *const mrelp,
+ uint_t const *const mloc0_u,
+ uint_t const *const mlocp_u,
+ Elf_Rel const *const mrel0_u,
+ Elf_Rel const *const mrelp_u,
+ uint_t const *const mloc0_i,
+ uint_t const *const mlocp_i,
+ Elf_Rel const *const mrel0_i,
+ Elf_Rel const *const mrelp_i,
unsigned int const rel_entsize,
unsigned int const symsec_sh_link)
{
/* Begin constructing output file */
- Elf_Shdr mcsec;
char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
? ".rela__mcount_loc"
: ".rel__mcount_loc";
- unsigned const old_shnum = w2(ehdr->e_shnum);
+ char const *udiv_name = (sizeof(Elf_Rela) == rel_entsize)
+ ? ".rela__udiv_loc"
+ : ".rel__udiv_loc";
+ char const *idiv_name = (sizeof(Elf_Rela) == rel_entsize)
+ ? ".rela__idiv_loc"
+ : ".rel__idiv_loc";
+ unsigned old_shnum = w2(ehdr->e_shnum);
uint_t const old_shoff = _w(ehdr->e_shoff);
uint_t const old_shstr_sh_size = _w(shstr->sh_size);
uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
- uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
uint_t new_e_shoff;
+ uint_t t = _w(shstr->sh_size);
+ uint_t name_off = old_shstr_sh_size;
+ int mc = 0, udiv = 0, idiv = 0;
+ int num_sections;
+
+ if (mlocp != mloc0) {
+ t += 1 + strlen(mc_name);
+ mc = 1;
+ }
+ if (mlocp_u != mloc0_u) {
+ t += 1 + strlen(udiv_name);
+ udiv = 1;
+ }
+ if (mlocp_i != mloc0_i) {
+ t += 1 + strlen(idiv_name);
+ idiv = 1;
+ }
+ num_sections = (mc * 2) + (udiv * 2) + (idiv * 2);
shstr->sh_size = _w(t);
shstr->sh_offset = _w(sb.st_size);
@@ -204,8 +299,13 @@ static void append_func(Elf_Ehdr *const ehdr,
/* body for new shstrtab */
ulseek(fd_map, sb.st_size, SEEK_SET);
- uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size);
- uwrite(fd_map, mc_name, 1 + strlen(mc_name));
+ uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, name_off);
+ if (mc)
+ uwrite(fd_map, mc_name, 1 + strlen(mc_name));
+ if (udiv)
+ uwrite(fd_map, udiv_name, 1 + strlen(udiv_name));
+ if (idiv)
+ uwrite(fd_map, idiv_name, 1 + strlen(idiv_name));
/* old(modified) Elf_Shdr table, word-byte aligned */
ulseek(fd_map, t, SEEK_SET);
@@ -214,39 +314,38 @@ static void append_func(Elf_Ehdr *const ehdr,
sizeof(Elf_Shdr) * old_shnum);
/* new sections __mcount_loc and .rel__mcount_loc */
- t += 2*sizeof(mcsec);
- mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel")
- + old_shstr_sh_size);
- mcsec.sh_type = w(SHT_PROGBITS);
- mcsec.sh_flags = _w(SHF_ALLOC);
- mcsec.sh_addr = 0;
- mcsec.sh_offset = _w(t);
- mcsec.sh_size = _w((void *)mlocp - (void *)mloc0);
- mcsec.sh_link = 0;
- mcsec.sh_info = 0;
- mcsec.sh_addralign = _w(_size);
- mcsec.sh_entsize = _w(_size);
- uwrite(fd_map, &mcsec, sizeof(mcsec));
-
- mcsec.sh_name = w(old_shstr_sh_size);
- mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
- ? w(SHT_RELA)
- : w(SHT_REL);
- mcsec.sh_flags = 0;
- mcsec.sh_addr = 0;
- mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t);
- mcsec.sh_size = _w((void *)mrelp - (void *)mrel0);
- mcsec.sh_link = w(symsec_sh_link);
- mcsec.sh_info = w(old_shnum);
- mcsec.sh_addralign = _w(_size);
- mcsec.sh_entsize = _w(rel_entsize);
- uwrite(fd_map, &mcsec, sizeof(mcsec));
-
- uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0);
- uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0);
+ t += num_sections * sizeof(Elf_Shdr);
+ if (mc)
+ append_section(mloc0, mlocp, mrel0, mrelp, mc_name, rel_entsize,
+ symsec_sh_link, &name_off, &t, &old_shnum);
+
+ /* new sections __udiv_loc and .rel__udiv_loc */
+ if (udiv)
+ append_section(mloc0_u, mlocp_u, mrel0_u, mrelp_u, udiv_name,
+ rel_entsize, symsec_sh_link, &name_off, &t,
+ &old_shnum);
+
+ /* new sections __idiv_loc and .rel__idiv_loc */
+ if (idiv)
+ append_section(mloc0_i, mlocp_i, mrel0_i, mrelp_i, idiv_name,
+ rel_entsize, symsec_sh_link, &name_off, &t,
+ &old_shnum);
+
+ if (mc) {
+ uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0);
+ uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0);
+ }
+ if (udiv) {
+ uwrite(fd_map, mloc0_u, (void *)mlocp_u - (void *)mloc0_u);
+ uwrite(fd_map, mrel0_u, (void *)mrelp_u - (void *)mrel0_u);
+ }
+ if (idiv) {
+ uwrite(fd_map, mloc0_i, (void *)mlocp_i - (void *)mloc0_i);
+ uwrite(fd_map, mrel0_i, (void *)mrelp_i - (void *)mrel0_i);
+ }
ehdr->e_shoff = _w(new_e_shoff);
- ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */
+ ehdr->e_shnum = w2(num_sections + w2(ehdr->e_shnum));
ulseek(fd_map, 0, SEEK_SET);
uwrite(fd_map, ehdr, sizeof(*ehdr));
}
@@ -273,6 +372,20 @@ static unsigned get_mcountsym(Elf_Sym const *const sym0,
return mcountsym;
}
+static unsigned get_arm_sym(Elf_Sym const *const sym0,
+ Elf_Rel const *relp,
+ char const *const str0, const char *find)
+{
+ unsigned sym = 0;
+ Elf_Sym const *const symp = &sym0[Elf_r_sym(relp)];
+ char const *symname = &str0[w(symp->st_name)];
+
+ if (strcmp(find, symname) == 0)
+ sym = Elf_r_sym(relp);
+
+ return sym;
+}
+
static void get_sym_str_and_relp(Elf_Shdr const *const relhdr,
Elf_Ehdr const *const ehdr,
Elf_Sym const **sym0,
@@ -296,28 +409,65 @@ static void get_sym_str_and_relp(Elf_Shdr const *const relhdr,
*relp = rel0;
}
+static void add_relocation(Elf_Rel const *relp, uint_t *mloc0, uint_t **mlocpp,
+ uint_t const recval, unsigned const recsym,
+ Elf_Rel **const mrelpp, unsigned offbase,
+ unsigned rel_entsize, unsigned const reltype)
+{
+ uint_t *mlocp = *mlocpp;
+ Elf_Rel *mrelp = *mrelpp;
+ uint_t const addend = _w(_w(relp->r_offset) - recval + mcount_adjust);
+ mrelp->r_offset = _w(offbase + ((void *)mlocp - (void *)mloc0));
+ Elf_r_info(mrelp, recsym, reltype);
+ if (rel_entsize == sizeof(Elf_Rela)) {
+ ((Elf_Rela *)mrelp)->r_addend = addend;
+ *mlocp++ = 0;
+ } else
+ *mlocp++ = addend;
+
+ *mlocpp = mlocp;
+ *mrelpp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
+}
+
/*
* Look at the relocations in order to find the calls to mcount.
* Accumulate the section offsets that are found, and their relocation info,
* onto the end of the existing arrays.
*/
-static uint_t *sift_rel_mcount(uint_t *mlocp,
- unsigned const offbase,
+static void sift_rel_mcount(uint_t **mlocpp,
+ uint_t *mloc_base,
Elf_Rel **const mrelpp,
+ uint_t **mlocpp_u,
+ uint_t *mloc_base_u,
+ Elf_Rel **const mrelpp_u,
+ uint_t **mlocpp_i,
+ uint_t *mloc_base_i,
+ Elf_Rel **const mrelpp_i,
Elf_Shdr const *const relhdr,
Elf_Ehdr const *const ehdr,
unsigned const recsym,
uint_t const recval,
unsigned const reltype)
{
+ uint_t *mlocp = *mlocpp;
+ unsigned const offbase = (void *)mlocp - (void *)mloc_base;
uint_t *const mloc0 = mlocp;
Elf_Rel *mrelp = *mrelpp;
+ uint_t *mlocp_u = *mlocpp_u;
+ unsigned const offbase_u = (void *)mlocp_u - (void *)mloc_base_u;
+ uint_t *const mloc0_u = mlocp_u;
+ Elf_Rel *mrelp_u = *mrelpp_u;
+ uint_t *mlocp_i = *mlocpp_i;
+ unsigned const offbase_i = (void *)mlocp_i - (void *)mloc_base_i;
+ uint_t *const mloc0_i = mlocp_i;
+ Elf_Rel *mrelp_i = *mrelpp_i;
Elf_Sym const *sym0;
char const *str0;
Elf_Rel const *relp;
unsigned rel_entsize = _w(relhdr->sh_entsize);
unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
- unsigned mcountsym = 0;
+ int arm = w2(ehdr->e_machine) == EM_ARM;
+ unsigned mcountsym = 0, udiv_sym = 0, idiv_sym =0;
unsigned t;
get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
@@ -326,24 +476,53 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
if (trace_mcount && !mcountsym)
mcountsym = get_mcountsym(sym0, relp, str0);
- if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
- uint_t const addend =
- _w(_w(relp->r_offset) - recval + mcount_adjust);
- mrelp->r_offset = _w(offbase
- + ((void *)mlocp - (void *)mloc0));
- Elf_r_info(mrelp, recsym, reltype);
- if (rel_entsize == sizeof(Elf_Rela)) {
- ((Elf_Rela *)mrelp)->r_addend = addend;
- *mlocp++ = 0;
- } else
- *mlocp++ = addend;
-
- mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
+ if (arm && !udiv_sym)
+ udiv_sym = get_arm_sym(sym0, relp, str0,
+ "__aeabi_uidiv");
+ if (arm && !idiv_sym)
+ idiv_sym = get_arm_sym(sym0, relp, str0,
+ "__aeabi_idiv");
+
+ if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp))
+ add_relocation(relp, mloc0, &mlocp, recval, recsym,
+ &mrelp, offbase, rel_entsize, reltype);
+
+ if (udiv_sym == Elf_r_sym(relp)) {
+ switch (relp->r_info & 0xff) {
+ case R_ARM_PC24:
+ case 28:
+ case 29:
+ add_relocation(relp, mloc0_u, &mlocp_u, recval,
+ recsym, &mrelp_u, offbase_u,
+ rel_entsize, reltype);
+ break;
+ default:
+ break;
+ }
}
+
+ if (idiv_sym == Elf_r_sym(relp)) {
+ switch (relp->r_info & 0xff) {
+ case R_ARM_PC24:
+ case 28:
+ case 29:
+ add_relocation(relp, mloc0_i, &mlocp_i, recval,
+ recsym, &mrelp_i, offbase_i,
+ rel_entsize, reltype);
+ break;
+ default:
+ break;
+ }
+ }
+
relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
}
+ *mrelpp_i = mrelp_i;
+ *mrelpp_u = mrelp_u;
*mrelpp = mrelp;
- return mlocp;
+ *mlocpp_i = mlocp_i;
+ *mlocpp_u = mlocp_u;
+ *mlocpp = mlocp;
}
/*
@@ -452,14 +631,14 @@ static char const *
__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
Elf_Shdr const *const shdr0,
char const *const shstrtab,
- char const *const fname)
+ char const *const fname, const char *find)
{
/* .sh_info depends on .sh_type == SHT_REL[,A] */
Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
char const *const txtname = &shstrtab[w(txthdr->sh_name)];
- if (strcmp("__mcount_loc", txtname) == 0) {
- fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
+ if (strcmp(find, txtname) == 0) {
+ fprintf(stderr, "warning: %s already exists: %s\n", find,
fname);
succeed_file();
}
@@ -472,25 +651,25 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
static char const *has_rel_mcount(Elf_Shdr const *const relhdr,
Elf_Shdr const *const shdr0,
char const *const shstrtab,
- char const *const fname)
+ char const *const fname, const char *find)
{
if (w(relhdr->sh_type) != SHT_REL && w(relhdr->sh_type) != SHT_RELA)
return NULL;
- return __has_rel_mcount(relhdr, shdr0, shstrtab, fname);
+ return __has_rel_mcount(relhdr, shdr0, shstrtab, fname, find);
}
static unsigned tot_relsize(Elf_Shdr const *const shdr0,
unsigned nhdr,
const char *const shstrtab,
- const char *const fname)
+ const char *const fname, const char *find)
{
unsigned totrelsz = 0;
Elf_Shdr const *shdrp = shdr0;
char const *txtname;
for (; nhdr; --nhdr, ++shdrp) {
- txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname);
+ txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname, find);
if (txtname && is_mcounted_section_name(txtname))
totrelsz += _w(shdrp->sh_size);
}
@@ -513,7 +692,8 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
unsigned k;
/* Upper bound on space: assume all relevant relocs are for mcount. */
- unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
+ unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname,
+ "__mcount_loc");
Elf_Rel *const mrel0 = umalloc(totrelsz);
Elf_Rel * mrelp = mrel0;
@@ -521,12 +701,28 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
uint_t *const mloc0 = umalloc(totrelsz>>1);
uint_t * mlocp = mloc0;
+ /* Allocate for arm too */
+ Elf_Rel *const mrel0_u = umalloc(totrelsz);
+ Elf_Rel * mrelp_u = mrel0_u;
+
+ /* 2*sizeof(address) <= sizeof(Elf_Rel) */
+ uint_t *const mloc0_u = umalloc(totrelsz>>1);
+ uint_t * mlocp_u = mloc0_u;
+
+ /* Allocate for arm too */
+ Elf_Rel *const mrel0_i = umalloc(totrelsz);
+ Elf_Rel * mrelp_i = mrel0_i;
+
+ /* 2*sizeof(address) <= sizeof(Elf_Rel) */
+ uint_t *const mloc0_i = umalloc(totrelsz>>1);
+ uint_t * mlocp_i = mloc0_i;
+
unsigned rel_entsize = 0;
unsigned symsec_sh_link = 0;
for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
char const *const txtname = has_rel_mcount(relhdr, shdr0,
- shstrtab, fname);
+ shstrtab, fname, "__mcount_loc");
if (txtname && is_mcounted_section_name(txtname)) {
uint_t recval = 0;
unsigned const recsym = find_secsym_ndx(
@@ -535,9 +731,10 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
ehdr);
rel_entsize = _w(relhdr->sh_entsize);
- mlocp = sift_rel_mcount(mlocp,
- (void *)mlocp - (void *)mloc0, &mrelp,
- relhdr, ehdr, recsym, recval, reltype);
+ sift_rel_mcount(&mlocp, mloc0, &mrelp,
+ &mlocp_u, mloc0_u, &mrelp_u, &mlocp_i, mloc0_i,
+ &mrelp_i, relhdr, ehdr, recsym, recval,
+ reltype);
} else if (txtname && (warn_on_notrace_sect || make_nop)) {
/*
* This section is ignored by ftrace, but still
@@ -546,10 +743,16 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
nop_mcount(relhdr, ehdr, txtname);
}
}
- if (mloc0 != mlocp) {
+ if (mloc0 != mlocp || mloc0_u != mlocp_u || mloc0_i != mlocp_i) {
append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
+ mloc0_u, mlocp_u, mrel0_u, mrelp_u,
+ mloc0_i, mlocp_i, mrel0_i, mrelp_i,
rel_entsize, symsec_sh_link);
}
free(mrel0);
free(mloc0);
+ free(mrel0_u);
+ free(mloc0_u);
+ free(mrel0_i);
+ free(mloc0_i);
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@arm.linux.org.uk> |
|---|---|
| Date | 2015-11-21 11:20 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qxdqV-3Ub-1@gated-at.bofh.it> |
| In reply to | #1274585 |
On Fri, Nov 20, 2015 at 05:23:16PM -0800, Stephen Boyd wrote:
> @@ -452,14 +631,14 @@ static char const *
> __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
> Elf_Shdr const *const shdr0,
> char const *const shstrtab,
> - char const *const fname)
> + char const *const fname, const char *find)
> {
> /* .sh_info depends on .sh_type == SHT_REL[,A] */
> Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
> char const *const txtname = &shstrtab[w(txthdr->sh_name)];
>
> - if (strcmp("__mcount_loc", txtname) == 0) {
> - fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
> + if (strcmp(find, txtname) == 0) {
> + fprintf(stderr, "warning: %s already exists: %s\n", find,
Oh, it's this which has been spewing that silly
"warning: __mcount_loc already exists"
message thousands of times in my nightly kernel builds (so much so, that
I've had to filter the thing out of the logs.) Given that this is soo
noisy, I think first we need to get to the bottom of why this program is
soo noisy before we try to make it more functional.
I had assumed that this message was produced by something in the
toolchain, not something in the kernel.
--
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2015-11-23 22:00 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qy6no-6VJ-13@gated-at.bofh.it> |
| In reply to | #1274624 |
On Mon, 23 Nov 2015 12:53:35 -0800 Stephen Boyd <sboyd@codeaurora.org> wrote: > > This comment in recordmcount.pl may tell us something. > > # > # Somehow the make process can execute this script on an > # object twice. If it does, we would duplicate the mcount > # section and it will cause the function tracer self test > # to fail. Check if the mcount section exists, and if it does, > # warn and exit. > # > print STDERR "ERROR: $mcount_section already in $inputfile\n" . > "\tThis may be an indication that your build is corrupted.\n" . > "\tDelete $inputfile and try again. If the same object file\n" . > "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n"; > exit(-1); I believe I hit this by hitting ctrl-C during a build and then starting it again. It's been a while so it could have been something else. -- Steve > > I don't think there's much that can be done here besides making > it silent unless there's some verbose build flag set (-v?), but > it is interesting that you see it spew thousands of times. I've > never seen the error printed, but perhaps I'm not building the > kernel the same way you are. Care to share how you're building > and seeing these error messages? > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-23 22:00 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qy6no-6VJ-15@gated-at.bofh.it> |
| In reply to | #1274624 |
On 11/21, Russell King - ARM Linux wrote:
> On Fri, Nov 20, 2015 at 05:23:16PM -0800, Stephen Boyd wrote:
> > @@ -452,14 +631,14 @@ static char const *
> > __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
> > Elf_Shdr const *const shdr0,
> > char const *const shstrtab,
> > - char const *const fname)
> > + char const *const fname, const char *find)
> > {
> > /* .sh_info depends on .sh_type == SHT_REL[,A] */
> > Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
> > char const *const txtname = &shstrtab[w(txthdr->sh_name)];
> >
> > - if (strcmp("__mcount_loc", txtname) == 0) {
> > - fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
> > + if (strcmp(find, txtname) == 0) {
> > + fprintf(stderr, "warning: %s already exists: %s\n", find,
>
> Oh, it's this which has been spewing that silly
> "warning: __mcount_loc already exists"
>
> message thousands of times in my nightly kernel builds (so much so, that
> I've had to filter the thing out of the logs.) Given that this is soo
> noisy, I think first we need to get to the bottom of why this program is
> soo noisy before we try to make it more functional.
>
This comment in recordmcount.pl may tell us something.
#
# Somehow the make process can execute this script on an
# object twice. If it does, we would duplicate the mcount
# section and it will cause the function tracer self test
# to fail. Check if the mcount section exists, and if it does,
# warn and exit.
#
print STDERR "ERROR: $mcount_section already in $inputfile\n" .
"\tThis may be an indication that your build is corrupted.\n" .
"\tDelete $inputfile and try again. If the same object file\n" .
"\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
exit(-1);
I don't think there's much that can be done here besides making
it silent unless there's some verbose build flag set (-v?), but
it is interesting that you see it spew thousands of times. I've
never seen the error printed, but perhaps I'm not building the
kernel the same way you are. Care to share how you're building
and seeing these error messages?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@arm.linux.org.uk> |
|---|---|
| Date | 2015-11-23 22:10 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qy6x3-7f9-19@gated-at.bofh.it> |
| In reply to | #1275852 |
On Mon, Nov 23, 2015 at 12:53:35PM -0800, Stephen Boyd wrote:
> On 11/21, Russell King - ARM Linux wrote:
> > On Fri, Nov 20, 2015 at 05:23:16PM -0800, Stephen Boyd wrote:
> > > @@ -452,14 +631,14 @@ static char const *
> > > __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
> > > Elf_Shdr const *const shdr0,
> > > char const *const shstrtab,
> > > - char const *const fname)
> > > + char const *const fname, const char *find)
> > > {
> > > /* .sh_info depends on .sh_type == SHT_REL[,A] */
> > > Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
> > > char const *const txtname = &shstrtab[w(txthdr->sh_name)];
> > >
> > > - if (strcmp("__mcount_loc", txtname) == 0) {
> > > - fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
> > > + if (strcmp(find, txtname) == 0) {
> > > + fprintf(stderr, "warning: %s already exists: %s\n", find,
> >
> > Oh, it's this which has been spewing that silly
> > "warning: __mcount_loc already exists"
> >
> > message thousands of times in my nightly kernel builds (so much so, that
> > I've had to filter the thing out of the logs.) Given that this is soo
> > noisy, I think first we need to get to the bottom of why this program is
> > soo noisy before we try to make it more functional.
> >
>
> This comment in recordmcount.pl may tell us something.
>
> #
> # Somehow the make process can execute this script on an
> # object twice. If it does, we would duplicate the mcount
> # section and it will cause the function tracer self test
> # to fail. Check if the mcount section exists, and if it does,
> # warn and exit.
> #
> print STDERR "ERROR: $mcount_section already in $inputfile\n" .
> "\tThis may be an indication that your build is corrupted.\n" .
> "\tDelete $inputfile and try again. If the same object file\n" .
> "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
> exit(-1);
>
> I don't think there's much that can be done here besides making
> it silent unless there's some verbose build flag set (-v?), but
> it is interesting that you see it spew thousands of times. I've
> never seen the error printed, but perhaps I'm not building the
> kernel the same way you are. Care to share how you're building
> and seeing these error messages?
All I get is this:
warning: __mcount_loc already exists: arch/arm/mm/mmap.o
Not the "ERROR: ... already in ..." that the above would give.
Nothing special. It's a seeded allyesconfig built with:
$ make -k -j2 zImage modules dtbs LOADADDR=0x60008000 CONFIG_DEBUG_SECTION_MISMATCH=y O=/path/to/build/dir
The seed being:
CONFIG_MODULES=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_LOG_BUF_SHIFT=19
CONFIG_ZBOOT_ROM_TEXT=0x70000000
CONFIG_ZBOOT_ROM_BSS=0x61000000
CONFIG_CMDLINE="root=/dev/mmcblk0p1 rootdelay=2 ro"
CONFIG_ARCH_VEXPRESS=y
# Must not have XIP support enabled
CONFIG_XIP_KERNEL=n
# Our toolchain has no T2 support
CONFIG_THUMB2_KERNEL=n
# Disable samples - this needs linux/seccomp.h in our host environment
CONFIG_SAMPLES=n
# Disable debug info (stop the kernel getting too large)
CONFIG_DEBUG_INFO=n
# 30 Dec 2013: disable building wanxl firmware: we don't have as68k etc
CONFIG_WANXL_BUILD_FIRMWARE=n
# 14 Jan 2015: disable GCOV
CONFIG_GCOV_KERNEL=n
--
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-23 22:20 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qy6GJ-7im-3@gated-at.bofh.it> |
| In reply to | #1275858 |
On 11/23, Russell King - ARM Linux wrote:
> On Mon, Nov 23, 2015 at 12:53:35PM -0800, Stephen Boyd wrote:
> > On 11/21, Russell King - ARM Linux wrote:
> > > On Fri, Nov 20, 2015 at 05:23:16PM -0800, Stephen Boyd wrote:
> > > > @@ -452,14 +631,14 @@ static char const *
> > > > __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
> > > > Elf_Shdr const *const shdr0,
> > > > char const *const shstrtab,
> > > > - char const *const fname)
> > > > + char const *const fname, const char *find)
> > > > {
> > > > /* .sh_info depends on .sh_type == SHT_REL[,A] */
> > > > Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
> > > > char const *const txtname = &shstrtab[w(txthdr->sh_name)];
> > > >
> > > > - if (strcmp("__mcount_loc", txtname) == 0) {
> > > > - fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
> > > > + if (strcmp(find, txtname) == 0) {
> > > > + fprintf(stderr, "warning: %s already exists: %s\n", find,
> > >
> > > Oh, it's this which has been spewing that silly
> > > "warning: __mcount_loc already exists"
> > >
> > > message thousands of times in my nightly kernel builds (so much so, that
> > > I've had to filter the thing out of the logs.) Given that this is soo
> > > noisy, I think first we need to get to the bottom of why this program is
> > > soo noisy before we try to make it more functional.
> > >
> >
> > This comment in recordmcount.pl may tell us something.
> >
> > #
> > # Somehow the make process can execute this script on an
> > # object twice. If it does, we would duplicate the mcount
> > # section and it will cause the function tracer self test
> > # to fail. Check if the mcount section exists, and if it does,
> > # warn and exit.
> > #
> > print STDERR "ERROR: $mcount_section already in $inputfile\n" .
> > "\tThis may be an indication that your build is corrupted.\n" .
> > "\tDelete $inputfile and try again. If the same object file\n" .
> > "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
> > exit(-1);
> >
> > I don't think there's much that can be done here besides making
> > it silent unless there's some verbose build flag set (-v?), but
> > it is interesting that you see it spew thousands of times. I've
> > never seen the error printed, but perhaps I'm not building the
> > kernel the same way you are. Care to share how you're building
> > and seeing these error messages?
>
> All I get is this:
>
> warning: __mcount_loc already exists: arch/arm/mm/mmap.o
>
> Not the "ERROR: ... already in ..." that the above would give.
That's because I copied from the perl version of recordmcount.
The C version of this tool doesn't have that nice comment.
>
> Nothing special. It's a seeded allyesconfig built with:
>
> $ make -k -j2 zImage modules dtbs LOADADDR=0x60008000 CONFIG_DEBUG_SECTION_MISMATCH=y O=/path/to/build/dir
>
> The seed being:
>
> CONFIG_MODULES=y
> # CONFIG_LOCALVERSION_AUTO is not set
> CONFIG_LOG_BUF_SHIFT=19
> CONFIG_ZBOOT_ROM_TEXT=0x70000000
> CONFIG_ZBOOT_ROM_BSS=0x61000000
> CONFIG_CMDLINE="root=/dev/mmcblk0p1 rootdelay=2 ro"
> CONFIG_ARCH_VEXPRESS=y
> # Must not have XIP support enabled
> CONFIG_XIP_KERNEL=n
> # Our toolchain has no T2 support
> CONFIG_THUMB2_KERNEL=n
> # Disable samples - this needs linux/seccomp.h in our host environment
> CONFIG_SAMPLES=n
> # Disable debug info (stop the kernel getting too large)
> CONFIG_DEBUG_INFO=n
> # 30 Dec 2013: disable building wanxl firmware: we don't have as68k etc
> CONFIG_WANXL_BUILD_FIRMWARE=n
> # 14 Jan 2015: disable GCOV
> CONFIG_GCOV_KERNEL=n
>
Thanks. I don't see the prints on my system even with this config
on top of allyesconfig. Odd.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@arm.linux.org.uk> |
|---|---|
| Date | 2015-11-23 22:40 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qy706-7p3-17@gated-at.bofh.it> |
| In reply to | #1275860 |
On Mon, Nov 23, 2015 at 01:16:01PM -0800, Stephen Boyd wrote: > Thanks. I don't see the prints on my system even with this config > on top of allyesconfig. Odd. Hmm. It could be because I use ccache in hardlink mode to avoid the disk overhead of having two copies and having to duplicate the file contents. If the kernel build thinks it can modify an object file in place, it will lead to this, as it will end up modifying the stored ccache file unless it specifically breaks the hardlink. -- FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-24 02:10 +0100 |
| Subject | Re: [RFC/PATCH 2/3] recordmcount: Record locations of __aeabi_{u}idiv() calls on ARM |
| Message-ID | <qyahj-1bG-1@gated-at.bofh.it> |
| In reply to | #1275871 |
On 11/23, Russell King - ARM Linux wrote: > On Mon, Nov 23, 2015 at 01:16:01PM -0800, Stephen Boyd wrote: > > Thanks. I don't see the prints on my system even with this config > > on top of allyesconfig. Odd. > > Hmm. > > It could be because I use ccache in hardlink mode to avoid the disk > overhead of having two copies and having to duplicate the file > contents. > > If the kernel build thinks it can modify an object file in place, it > will lead to this, as it will end up modifying the stored ccache > file unless it specifically breaks the hardlink. > That sounds very possible. I'd have to get ccache setup with hardlinks to test out your theory. Is it supported to use ccache with hardlinks to build the kernel? The ccache documentation makes it sounds like it will confuse make and isn't a good idea. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-21 02:30 +0100 |
| Subject | [RFC/PATCH 1/3] scripts: Allow recordmcount to be used without tracing enabled |
| Message-ID | <qx5a1-6MK-7@gated-at.bofh.it> |
| In reply to | #1274584 |
In the next patch we're going to modify recordmcount to also
record locations of calls to __aeabi_{u}idiv(). Lay the
groundwork for this by adding a flag to recordmcount that
indicates if we're expected to find calls to mcount or not.
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Måns Rullgård <mans@mansr.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
kernel/trace/Kconfig | 4 ++++
scripts/Makefile.build | 15 +++++----------
scripts/recordmcount.c | 10 +++++++---
scripts/recordmcount.h | 2 +-
scripts/recordmcount.pl | 11 ++++++++---
5 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 8d6363f42169..578b666ed7d9 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -57,6 +57,10 @@ config HAVE_C_RECORDMCOUNT
help
C version of recordmcount available?
+config RUN_RECORDMCOUNT
+ def_bool y
+ depends on DYNAMIC_FTRACE && HAVE_FTRACE_MCOUNT_RECORD
+
config TRACER_MAX_TRACE
bool
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 01df30af4d4a..22f2eb10d434 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -210,7 +210,7 @@ cmd_modversions = \
fi;
endif
-ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ifdef CONFIG_RUN_RECORDMCOUNT
ifdef BUILD_C_RECORDMCOUNT
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
RECORDMCOUNT_FLAGS = -w
@@ -219,26 +219,21 @@ endif
# The empty.o file is created in the make process in order to determine
# the target endianness and word size. It is made before all other C
# files, including recordmcount.
-sub_cmd_record_mcount = \
+cmd_record_mcount = \
if [ $(@) != "scripts/mod/empty.o" ]; then \
- $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
+ $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) $(if $(findstring $(CC_FLAGS_FTRACE),$(_c_flags)),-t,) "$(@)"; \
fi;
recordmcount_source := $(srctree)/scripts/recordmcount.c \
$(srctree)/scripts/recordmcount.h
else
-sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
+cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
"$(if $(CONFIG_64BIT),64,32)" \
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
- "$(if $(part-of-module),1,0)" "$(@)";
+ "$(if $(part-of-module),1,0)" "$(if $(findstring $(CC_FLAGS_FTRACE),$(_c_flags)),1,0)" "$(@)";
recordmcount_source := $(srctree)/scripts/recordmcount.pl
endif
-cmd_record_mcount = \
- if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \
- "$(CC_FLAGS_FTRACE)" ]; then \
- $(sub_cmd_record_mcount) \
- fi;
endif
define rule_cc_o_c
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 698768bdc581..b6b4a5df647a 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -54,6 +54,7 @@ static struct stat sb; /* Remember .st_size, etc. */
static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
static const char *altmcount; /* alternate mcount symbol name */
static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
+static int trace_mcount; /* Record mcount callers */
/* setjmp() return values */
enum {
@@ -453,19 +454,22 @@ main(int argc, char *argv[])
int c;
int i;
- while ((c = getopt(argc, argv, "w")) >= 0) {
+ while ((c = getopt(argc, argv, "wt")) >= 0) {
switch (c) {
case 'w':
warn_on_notrace_sect = 1;
break;
+ case 't':
+ trace_mcount = 1;
+ break;
default:
- fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
+ fprintf(stderr, "usage: recordmcount [-wt] file.o...\n");
return 0;
}
}
if ((argc - optind) < 1) {
- fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
+ fprintf(stderr, "usage: recordmcount [-wt] file.o...\n");
return 0;
}
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index b9897e2be404..6e196dba748d 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -323,7 +323,7 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
for (t = nrel; t; --t) {
- if (!mcountsym)
+ if (trace_mcount && !mcountsym)
mcountsym = get_mcountsym(sym0, relp, str0);
if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 826470d7f000..cff3040ddbdc 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -113,20 +113,25 @@ $P =~ s@.*/@@g;
my $V = '0.1';
-if ($#ARGV != 11) {
- print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
+if ($#ARGV != 12) {
+ print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module is_traced inputfile\n";
print "version: $V\n";
exit(1);
}
my ($arch, $endian, $bits, $objdump, $objcopy, $cc,
- $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
+ $ld, $nm, $rm, $mv, $is_module, $is_traced, $inputfile) = @ARGV;
# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
exit(0);
}
+# We only trace mcount calls
+if ($is_traced eq "0") {
+ exit(0);
+}
+
# Acceptable sections to record.
my %text_sections = (
".text" => 1,
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-21 02:30 +0100 |
| Subject | [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions |
| Message-ID | <qx5a1-6MK-9@gated-at.bofh.it> |
| In reply to | #1274584 |
The ARM compiler inserts calls to __aeabi_uidiv() and
__aeabi_idiv() when it needs to perform division on signed and
unsigned integers. If a processor has support for the udiv and
sdiv division instructions the calls to these support routines
can be replaced with those instructions. Now that recordmcount
records the locations of calls to these library functions in
two sections (one for udiv and one for sdiv), iterate over these
sections early at boot and patch the call sites with the
appropriate division instruction when we determine that the
processor supports the division instructions. Using the division
instructions should be faster and less power intensive than
running the support code.
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Måns Rullgård <mans@mansr.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
Makefile | 7 +++++++
arch/arm/Kconfig | 14 ++++++++++++++
arch/arm/kernel/module.c | 44 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/kernel/setup.c | 34 +++++++++++++++++++++++++++++++++
arch/arm/kernel/vmlinux.lds.S | 13 +++++++++++++
kernel/trace/Kconfig | 2 +-
6 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 69be581e7c7a..9efc8274eba9 100644
--- a/Makefile
+++ b/Makefile
@@ -737,6 +737,13 @@ ifdef CONFIG_DYNAMIC_FTRACE
endif
endif
+ifdef CONFIG_ARM_PATCH_UIDIV
+ ifndef BUILD_C_RECORDMCOUNT
+ BUILD_C_RECORDMCOUNT := y
+ export BUILD_C_RECORDMCOUNT
+ endif
+endif
+
# We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9246bd7cc3cf..9e2d2adcc85b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1640,6 +1640,20 @@ config AEABI
To use this you need GCC version 4.0.0 or later.
+config ARM_PATCH_UIDIV
+ bool "Runtime patch calls to __aeabi_{u}idiv() with udiv/sdiv"
+ depends on CPU_V7 && !XIP_KERNEL && AEABI
+ help
+ Some v7 CPUs have support for the udiv and sdiv instructions
+ that can be used in place of calls to __aeabi_uidiv and __aeabi_idiv
+ functions provided by the ARM runtime ABI.
+
+ Enabling this option allows the kernel to modify itself to replace
+ branches to these library functions with the udiv and sdiv
+ instructions themselves. Typically this will be faster and less
+ power intensive than running the library support code to do
+ integer division.
+
config OABI_COMPAT
bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
depends on AEABI && !THUMB2_KERNEL
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index efdddcb97dd1..064e6ae60e08 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -20,6 +20,7 @@
#include <linux/string.h>
#include <linux/gfp.h>
+#include <asm/hwcap.h>
#include <asm/pgtable.h>
#include <asm/sections.h>
#include <asm/smp_plat.h>
@@ -51,6 +52,43 @@ void *module_alloc(unsigned long size)
}
#endif
+#ifdef CONFIG_ARM_PATCH_UIDIV
+static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
+{
+ extern char __aeabi_uidiv[], __aeabi_idiv[];
+ unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
+ unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
+ unsigned int udiv_insn, sdiv_insn, mask;
+
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ mask = HWCAP_IDIVT;
+ udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
+ sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
+ } else {
+ mask = HWCAP_IDIVA;
+ udiv_insn = __opcode_to_mem_arm(0xe730f110);
+ sdiv_insn = __opcode_to_mem_arm(0xe710f110);
+ }
+
+ if (elf_hwcap & mask) {
+ if (sym->st_value == udiv_addr) {
+ *(u32 *)loc = udiv_insn;
+ return 1;
+ } else if (sym->st_value == sdiv_addr) {
+ *(u32 *)loc = sdiv_insn;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#else
+static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
+{
+ return 0;
+}
+#endif
+
int
apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
unsigned int relindex, struct module *module)
@@ -109,6 +147,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
return -ENOEXEC;
}
+ if (module_patch_aeabi_uidiv(loc, sym))
+ break;
+
offset = __mem_to_opcode_arm(*(u32 *)loc);
offset = (offset & 0x00ffffff) << 2;
if (offset & 0x02000000)
@@ -195,6 +236,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
return -ENOEXEC;
}
+ if (module_patch_aeabi_uidiv(loc, sym))
+ break;
+
upper = __mem_to_opcode_thumb16(*(u16 *)loc);
lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2));
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 20edd349d379..d2a3d165dcae 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -375,6 +375,39 @@ void __init early_print(const char *str, ...)
printk("%s", buf);
}
+#ifdef CONFIG_ARM_PATCH_UIDIV
+static void __init patch_aeabi_uidiv(void)
+{
+ extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
+ extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
+ unsigned long **p;
+ unsigned int udiv_insn, sdiv_insn, mask;
+
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ mask = HWCAP_IDIVT;
+ udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
+ sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
+ } else {
+ mask = HWCAP_IDIVA;
+ udiv_insn = __opcode_to_mem_arm(0xe730f110);
+ sdiv_insn = __opcode_to_mem_arm(0xe710f110);
+ }
+
+ if (elf_hwcap & mask) {
+ for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
+ unsigned long *inst = *p;
+ *inst = udiv_insn;
+ }
+ for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
+ unsigned long *inst = *p;
+ *inst = sdiv_insn;
+ }
+ }
+}
+#else
+static void __init patch_aeabi_uidiv(void) { }
+#endif
+
static void __init cpuid_init_hwcaps(void)
{
int block;
@@ -642,6 +675,7 @@ static void __init setup_processor(void)
elf_hwcap = list->elf_hwcap;
cpuid_init_hwcaps();
+ patch_aeabi_uidiv();
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8b60fde5ce48..bc87a2e04e6f 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -28,6 +28,18 @@
*(.hyp.idmap.text) \
VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;
+#ifdef CONFIG_ARM_PATCH_UIDIV
+#define UIDIV_REC . = ALIGN(8); \
+ VMLINUX_SYMBOL(__start_udiv_loc) = .; \
+ *(__udiv_loc) \
+ VMLINUX_SYMBOL(__stop_udiv_loc) = .; \
+ VMLINUX_SYMBOL(__start_idiv_loc) = .; \
+ *(__idiv_loc) \
+ VMLINUX_SYMBOL(__stop_idiv_loc) = .;
+#else
+#define UIDIV_REC
+#endif
+
#ifdef CONFIG_HOTPLUG_CPU
#define ARM_CPU_DISCARD(x)
#define ARM_CPU_KEEP(x) x
@@ -210,6 +222,7 @@ SECTIONS
.init.data : {
#ifndef CONFIG_XIP_KERNEL
INIT_DATA
+ UIDIV_REC
#endif
INIT_SETUP(16)
INIT_CALLS
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 578b666ed7d9..22b229515416 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -59,7 +59,7 @@ config HAVE_C_RECORDMCOUNT
config RUN_RECORDMCOUNT
def_bool y
- depends on DYNAMIC_FTRACE && HAVE_FTRACE_MCOUNT_RECORD
+ depends on (DYNAMIC_FTRACE && HAVE_FTRACE_MCOUNT_RECORD) || ARM_PATCH_UIDIV
config TRACER_MAX_TRACE
bool
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Måns Rullgård <mans@mansr.com> |
|---|---|
| Date | 2015-11-21 13:00 +0100 |
| Subject | Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions |
| Message-ID | <qxeZI-4Mi-5@gated-at.bofh.it> |
| In reply to | #1274587 |
Stephen Boyd <sboyd@codeaurora.org> writes:
> +static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
> +{
> + extern char __aeabi_uidiv[], __aeabi_idiv[];
> + unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
> + unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
> + unsigned int udiv_insn, sdiv_insn, mask;
> +
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> + mask = HWCAP_IDIVT;
> + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> + } else {
> + mask = HWCAP_IDIVA;
> + udiv_insn = __opcode_to_mem_arm(0xe730f110);
> + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> + }
> +
> + if (elf_hwcap & mask) {
> + if (sym->st_value == udiv_addr) {
> + *(u32 *)loc = udiv_insn;
> + return 1;
> + } else if (sym->st_value == sdiv_addr) {
> + *(u32 *)loc = sdiv_insn;
> + return 1;
> + }
> + }
> +
> + return 0;
> +}
[...]
> +static void __init patch_aeabi_uidiv(void)
> +{
> + extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
> + extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
> + unsigned long **p;
> + unsigned int udiv_insn, sdiv_insn, mask;
> +
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> + mask = HWCAP_IDIVT;
> + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> + } else {
> + mask = HWCAP_IDIVA;
> + udiv_insn = __opcode_to_mem_arm(0xe730f110);
> + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> + }
> +
> + if (elf_hwcap & mask) {
> + for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
> + unsigned long *inst = *p;
> + *inst = udiv_insn;
> + }
> + for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
> + unsigned long *inst = *p;
> + *inst = sdiv_insn;
> + }
> + }
> +}
These functions are rather similar. Perhaps they could be combined
somehow.
--
Måns Rullgård
mans@mansr.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-23 22:00 +0100 |
| Subject | Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions |
| Message-ID | <qy6no-6VJ-19@gated-at.bofh.it> |
| In reply to | #1274635 |
On 11/21, Måns Rullgård wrote:
> Stephen Boyd <sboyd@codeaurora.org> writes:
>
> > +static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
> > +{
> > + extern char __aeabi_uidiv[], __aeabi_idiv[];
> > + unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
> > + unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
> > + unsigned int udiv_insn, sdiv_insn, mask;
> > +
> > + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> > + mask = HWCAP_IDIVT;
> > + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> > + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> > + } else {
> > + mask = HWCAP_IDIVA;
> > + udiv_insn = __opcode_to_mem_arm(0xe730f110);
> > + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> > + }
> > +
> > + if (elf_hwcap & mask) {
> > + if (sym->st_value == udiv_addr) {
> > + *(u32 *)loc = udiv_insn;
> > + return 1;
> > + } else if (sym->st_value == sdiv_addr) {
> > + *(u32 *)loc = sdiv_insn;
> > + return 1;
> > + }
> > + }
> > +
> > + return 0;
> > +}
>
> [...]
>
> > +static void __init patch_aeabi_uidiv(void)
> > +{
> > + extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
> > + extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
> > + unsigned long **p;
> > + unsigned int udiv_insn, sdiv_insn, mask;
> > +
> > + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> > + mask = HWCAP_IDIVT;
> > + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> > + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> > + } else {
> > + mask = HWCAP_IDIVA;
> > + udiv_insn = __opcode_to_mem_arm(0xe730f110);
> > + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> > + }
> > +
> > + if (elf_hwcap & mask) {
> > + for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
> > + unsigned long *inst = *p;
> > + *inst = udiv_insn;
> > + }
> > + for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
> > + unsigned long *inst = *p;
> > + *inst = sdiv_insn;
> > + }
> > + }
> > +}
>
> These functions are rather similar. Perhaps they could be combined
> somehow.
>
Yes. I have this patch on top, just haven't folded it in because
it doesn't reduce the lines of code.
----8<----
From: Stephen Boyd <sboyd@codeaurora.org>
Subject: [PATCH] consolidate with module code
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
arch/arm/include/asm/setup.h | 3 +++
arch/arm/kernel/module.c | 16 +++++--------
arch/arm/kernel/setup.c | 54 +++++++++++++++++++++++++++-----------------
3 files changed, 42 insertions(+), 31 deletions(-)
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index e0adb9f1bf94..3f251cdb94ef 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -25,4 +25,7 @@ extern int arm_add_memory(u64 start, u64 size);
extern void early_print(const char *str, ...);
extern void dump_machine_table(void);
+extern void patch_uidiv(void *addr, size_t size);
+extern void patch_idiv(void *addr, size_t size);
+
#endif
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 064e6ae60e08..684a68f1085b 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -22,6 +22,7 @@
#include <asm/hwcap.h>
#include <asm/pgtable.h>
+#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/smp_plat.h>
#include <asm/unwind.h>
@@ -58,24 +59,19 @@ static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
extern char __aeabi_uidiv[], __aeabi_idiv[];
unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
- unsigned int udiv_insn, sdiv_insn, mask;
+ unsigned int mask;
- if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
mask = HWCAP_IDIVT;
- udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
- sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
- } else {
+ else
mask = HWCAP_IDIVA;
- udiv_insn = __opcode_to_mem_arm(0xe730f110);
- sdiv_insn = __opcode_to_mem_arm(0xe710f110);
- }
if (elf_hwcap & mask) {
if (sym->st_value == udiv_addr) {
- *(u32 *)loc = udiv_insn;
+ patch_uidiv(&loc, sizeof(loc));
return 1;
} else if (sym->st_value == sdiv_addr) {
- *(u32 *)loc = sdiv_insn;
+ patch_idiv(&loc, sizeof(loc));
return 1;
}
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d2a3d165dcae..cb86012c47d1 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -376,33 +376,45 @@ void __init early_print(const char *str, ...)
}
#ifdef CONFIG_ARM_PATCH_UIDIV
+static void __init_or_module patch(u32 **addr, size_t count, u32 insn)
+{
+ for (; count != 0; count -= 4)
+ **addr++ = insn;
+}
+
+void __init_or_module patch_uidiv(void *addr, size_t size)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
+ patch(addr, size, __opcode_to_mem_thumb32(0xfbb0f0f1));
+ else
+ patch(addr, size, __opcode_to_mem_arm(0xe730f110));
+
+}
+
+void __init_or_module patch_idiv(void *addr, size_t size)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
+ patch(addr, size, __opcode_to_mem_thumb32(0xfb90f0f1));
+ else
+ patch(addr, size, __opcode_to_mem_arm(0xe710f110));
+}
+
static void __init patch_aeabi_uidiv(void)
{
- extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
- extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
- unsigned long **p;
- unsigned int udiv_insn, sdiv_insn, mask;
+ extern char __start_udiv_loc[], __stop_udiv_loc[];
+ extern char __start_idiv_loc[], __stop_idiv_loc[];
+ unsigned int mask;
- if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
mask = HWCAP_IDIVT;
- udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
- sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
- } else {
+ else
mask = HWCAP_IDIVA;
- udiv_insn = __opcode_to_mem_arm(0xe730f110);
- sdiv_insn = __opcode_to_mem_arm(0xe710f110);
- }
- if (elf_hwcap & mask) {
- for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
- unsigned long *inst = *p;
- *inst = udiv_insn;
- }
- for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
- unsigned long *inst = *p;
- *inst = sdiv_insn;
- }
- }
+ if (!(elf_hwcap & mask))
+ return;
+
+ patch_uidiv(__start_udiv_loc, __stop_udiv_loc - __start_udiv_loc);
+ patch_idiv(__start_idiv_loc, __stop_idiv_loc - __start_idiv_loc);
}
#else
static void __init patch_aeabi_uidiv(void) { }
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Måns Rullgård <mans@mansr.com> |
|---|---|
| Date | 2015-11-23 22:00 +0100 |
| Subject | Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions |
| Message-ID | <qy6np-6VJ-27@gated-at.bofh.it> |
| In reply to | #1275851 |
Stephen Boyd <sboyd@codeaurora.org> writes:
> On 11/21, Måns Rullgård wrote:
>> Stephen Boyd <sboyd@codeaurora.org> writes:
>>
>> > +static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
>> > +{
>> > + extern char __aeabi_uidiv[], __aeabi_idiv[];
>> > + unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
>> > + unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
>> > + unsigned int udiv_insn, sdiv_insn, mask;
>> > +
>> > + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
>> > + mask = HWCAP_IDIVT;
>> > + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
>> > + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
>> > + } else {
>> > + mask = HWCAP_IDIVA;
>> > + udiv_insn = __opcode_to_mem_arm(0xe730f110);
>> > + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
>> > + }
>> > +
>> > + if (elf_hwcap & mask) {
>> > + if (sym->st_value == udiv_addr) {
>> > + *(u32 *)loc = udiv_insn;
>> > + return 1;
>> > + } else if (sym->st_value == sdiv_addr) {
>> > + *(u32 *)loc = sdiv_insn;
>> > + return 1;
>> > + }
>> > + }
>> > +
>> > + return 0;
>> > +}
>>
>> [...]
>>
>> > +static void __init patch_aeabi_uidiv(void)
>> > +{
>> > + extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
>> > + extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
>> > + unsigned long **p;
>> > + unsigned int udiv_insn, sdiv_insn, mask;
>> > +
>> > + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
>> > + mask = HWCAP_IDIVT;
>> > + udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
>> > + sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
>> > + } else {
>> > + mask = HWCAP_IDIVA;
>> > + udiv_insn = __opcode_to_mem_arm(0xe730f110);
>> > + sdiv_insn = __opcode_to_mem_arm(0xe710f110);
>> > + }
>> > +
>> > + if (elf_hwcap & mask) {
>> > + for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
>> > + unsigned long *inst = *p;
>> > + *inst = udiv_insn;
>> > + }
>> > + for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
>> > + unsigned long *inst = *p;
>> > + *inst = sdiv_insn;
>> > + }
>> > + }
>> > +}
>>
>> These functions are rather similar. Perhaps they could be combined
>> somehow.
>>
>
> Yes. I have this patch on top, just haven't folded it in because
> it doesn't reduce the lines of code.
I don't see any reason to split it anyhow. The end result isn't any
harder to understand than the intermediate.
> ----8<----
> From: Stephen Boyd <sboyd@codeaurora.org>
> Subject: [PATCH] consolidate with module code
>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
> arch/arm/include/asm/setup.h | 3 +++
> arch/arm/kernel/module.c | 16 +++++--------
> arch/arm/kernel/setup.c | 54 +++++++++++++++++++++++++++-----------------
> 3 files changed, 42 insertions(+), 31 deletions(-)
>
> diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
> index e0adb9f1bf94..3f251cdb94ef 100644
> --- a/arch/arm/include/asm/setup.h
> +++ b/arch/arm/include/asm/setup.h
> @@ -25,4 +25,7 @@ extern int arm_add_memory(u64 start, u64 size);
> extern void early_print(const char *str, ...);
> extern void dump_machine_table(void);
>
> +extern void patch_uidiv(void *addr, size_t size);
> +extern void patch_idiv(void *addr, size_t size);
Why not call things sdiv and udiv like the actual instructions?
> #endif
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index 064e6ae60e08..684a68f1085b 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -22,6 +22,7 @@
>
> #include <asm/hwcap.h>
> #include <asm/pgtable.h>
> +#include <asm/setup.h>
> #include <asm/sections.h>
> #include <asm/smp_plat.h>
> #include <asm/unwind.h>
> @@ -58,24 +59,19 @@ static int module_patch_aeabi_uidiv(unsigned long loc, const Elf32_Sym *sym)
> extern char __aeabi_uidiv[], __aeabi_idiv[];
> unsigned long udiv_addr = (unsigned long)__aeabi_uidiv;
> unsigned long sdiv_addr = (unsigned long)__aeabi_idiv;
> - unsigned int udiv_insn, sdiv_insn, mask;
> + unsigned int mask;
>
> - if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
> mask = HWCAP_IDIVT;
> - udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> - sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> - } else {
> + else
> mask = HWCAP_IDIVA;
> - udiv_insn = __opcode_to_mem_arm(0xe730f110);
> - sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> - }
>
> if (elf_hwcap & mask) {
> if (sym->st_value == udiv_addr) {
> - *(u32 *)loc = udiv_insn;
> + patch_uidiv(&loc, sizeof(loc));
> return 1;
> } else if (sym->st_value == sdiv_addr) {
> - *(u32 *)loc = sdiv_insn;
> + patch_idiv(&loc, sizeof(loc));
> return 1;
> }
> }
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index d2a3d165dcae..cb86012c47d1 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -376,33 +376,45 @@ void __init early_print(const char *str, ...)
> }
>
> #ifdef CONFIG_ARM_PATCH_UIDIV
> +static void __init_or_module patch(u32 **addr, size_t count, u32 insn)
> +{
> + for (; count != 0; count -= 4)
> + **addr++ = insn;
> +}
> +
> +void __init_or_module patch_uidiv(void *addr, size_t size)
> +{
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
> + patch(addr, size, __opcode_to_mem_thumb32(0xfbb0f0f1));
> + else
> + patch(addr, size, __opcode_to_mem_arm(0xe730f110));
> +
> +}
> +
> +void __init_or_module patch_idiv(void *addr, size_t size)
> +{
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
> + patch(addr, size, __opcode_to_mem_thumb32(0xfb90f0f1));
> + else
> + patch(addr, size, __opcode_to_mem_arm(0xe710f110));
> +}
> +
> static void __init patch_aeabi_uidiv(void)
> {
> - extern unsigned long *__start_udiv_loc[], *__stop_udiv_loc[];
> - extern unsigned long *__start_idiv_loc[], *__stop_idiv_loc[];
> - unsigned long **p;
> - unsigned int udiv_insn, sdiv_insn, mask;
> + extern char __start_udiv_loc[], __stop_udiv_loc[];
> + extern char __start_idiv_loc[], __stop_idiv_loc[];
> + unsigned int mask;
>
> - if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> + if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
> mask = HWCAP_IDIVT;
> - udiv_insn = __opcode_to_mem_thumb32(0xfbb0f0f1);
> - sdiv_insn = __opcode_to_mem_thumb32(0xfb90f0f1);
> - } else {
> + else
> mask = HWCAP_IDIVA;
> - udiv_insn = __opcode_to_mem_arm(0xe730f110);
> - sdiv_insn = __opcode_to_mem_arm(0xe710f110);
> - }
>
> - if (elf_hwcap & mask) {
> - for (p = __start_udiv_loc; p < __stop_udiv_loc; p++) {
> - unsigned long *inst = *p;
> - *inst = udiv_insn;
> - }
> - for (p = __start_idiv_loc; p < __stop_idiv_loc; p++) {
> - unsigned long *inst = *p;
> - *inst = sdiv_insn;
> - }
> - }
> + if (!(elf_hwcap & mask))
> + return;
> +
> + patch_uidiv(__start_udiv_loc, __stop_udiv_loc - __start_udiv_loc);
> + patch_idiv(__start_idiv_loc, __stop_idiv_loc - __start_idiv_loc);
> }
> #else
> static void __init patch_aeabi_uidiv(void) { }
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
--
Måns Rullgård
mans@mansr.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2015-11-23 22:20 +0100 |
| Subject | Re: [RFC/PATCH 3/3] ARM: Replace calls to __aeabi_{u}idiv with udiv/sdiv instructions |
| Message-ID | <qy6GJ-7im-1@gated-at.bofh.it> |
| In reply to | #1275854 |
On 11/23, Måns Rullgård wrote: > Stephen Boyd <sboyd@codeaurora.org> writes: > > > On 11/21, Måns Rullgård wrote: > >> > >> These functions are rather similar. Perhaps they could be combined > >> somehow. > >> > > > > Yes. I have this patch on top, just haven't folded it in because > > it doesn't reduce the lines of code. > > I don't see any reason to split it anyhow. The end result isn't any > harder to understand than the intermediate. Yep. > > > ----8<---- > > From: Stephen Boyd <sboyd@codeaurora.org> > > Subject: [PATCH] consolidate with module code > > > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> > > --- > > arch/arm/include/asm/setup.h | 3 +++ > > arch/arm/kernel/module.c | 16 +++++-------- > > arch/arm/kernel/setup.c | 54 +++++++++++++++++++++++++++----------------- > > 3 files changed, 42 insertions(+), 31 deletions(-) > > > > diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h > > index e0adb9f1bf94..3f251cdb94ef 100644 > > --- a/arch/arm/include/asm/setup.h > > +++ b/arch/arm/include/asm/setup.h > > @@ -25,4 +25,7 @@ extern int arm_add_memory(u64 start, u64 size); > > extern void early_print(const char *str, ...); > > extern void dump_machine_table(void); > > > > +extern void patch_uidiv(void *addr, size_t size); > > +extern void patch_idiv(void *addr, size_t size); > > Why not call things sdiv and udiv like the actual instructions? > Sure. I'll fold this into v2. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Måns Rullgård <mans@mansr.com> |
|---|---|
| Date | 2015-11-21 21:50 +0100 |
| Message-ID | <qxngC-1ZX-3@gated-at.bofh.it> |
| In reply to | #1274584 |
On 21 November 2015 20:39:58 GMT+00:00, Arnd Bergmann <arnd@arndb.de> wrote: >On Friday 20 November 2015 17:23:14 Stephen Boyd wrote: >> This is a respin of a patch series from about a year ago[1]. I >realized >> that we already had most of the code in recordmcount to figure out >> where we make calls to particular functions, so recording where >> we make calls to the integer division functions should be easy enough >> to add support for in the same codepaths. Looking back on the thread >> it seems like Mans was thinking along the same lines, although it >wasn't >> obvious to me back then or even over the last few days when I wrote >this. > >Shouldn't we start by allowing to build the kernel for -march=armv7ve >on platforms that allow it? That would seem like a simpler change >and likely generate better code for most people, except when you >actually >care about running the same binary kernel on older platforms. > >I tried to get a complete list of CPU cores with idiv, lpae and >virtualization support at some point, but I don't remember the >details for all Qualcomm and Marvell cores any more, to create the >complete configuration matrix. IIRC, all CPUs that support >virtualization also do lpae (they have to) and all CPUs that >do lpae also do idiv, but the opposite is not true. > > Arnd The ARM ARM says anything with virt has idiv, lpae doesn't matter. ARMv7-R also has idiv. I've no idea if anyone runs Linux on those though. -- Måns Rullgård -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2015-11-21 22:10 +0100 |
| Message-ID | <qxnzY-2lX-9@gated-at.bofh.it> |
| In reply to | #1274750 |
On Saturday 21 November 2015 20:45:38 Måns Rullgård wrote: > On 21 November 2015 20:39:58 GMT+00:00, Arnd Bergmann <arnd@arndb.de> wrote: > >On Friday 20 November 2015 17:23:14 Stephen Boyd wrote: > >> This is a respin of a patch series from about a year ago[1]. I > >realized > >> that we already had most of the code in recordmcount to figure out > >> where we make calls to particular functions, so recording where > >> we make calls to the integer division functions should be easy enough > >> to add support for in the same codepaths. Looking back on the thread > >> it seems like Mans was thinking along the same lines, although it > >wasn't > >> obvious to me back then or even over the last few days when I wrote > >this. > > > >Shouldn't we start by allowing to build the kernel for -march=armv7ve > >on platforms that allow it? That would seem like a simpler change > >and likely generate better code for most people, except when you > >actually > >care about running the same binary kernel on older platforms. > > > >I tried to get a complete list of CPU cores with idiv, lpae and > >virtualization support at some point, but I don't remember the > >details for all Qualcomm and Marvell cores any more, to create the > >complete configuration matrix. IIRC, all CPUs that support > >virtualization also do lpae (they have to) and all CPUs that > >do lpae also do idiv, but the opposite is not true. > > > > The ARM ARM says anything with virt has idiv, lpae doesn't matter. Ok, and anything with virt also has lpae by definition. The question is whether we care about using idiv on cores that do not have lpae, or that have neither lpae nor virt. We have a related problem at the moment where we don't handle configuration of lpae correctly in Kconfig: you can simply turn that on for any ARMv7-only kernel, but it breaks running on Cortex-A8, Cortex-A9 and at least some subset of PJ4/Scorpion/Krait (not sure which). If we add a way to configure idiv support, we should do it right and handle lpae correctly too. If we are lucky, each CPU we support either has both or neither, and then we just need one additional Kconfig option. We don't need another option for virt, because KVM support can be handled in a way that it doesn't break on cores with lpae but without virt (it requires lpae). > ARMv7-R also has idiv. I've no idea if anyone runs Linux on those though. Not mainline at least. There were patches at some point, but they never got merged. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Måns Rullgård <mans@mansr.com> |
|---|---|
| Date | 2015-11-21 23:20 +0100 |
| Message-ID | <qxoFI-34f-9@gated-at.bofh.it> |
| In reply to | #1274754 |
Arnd Bergmann <arnd@arndb.de> writes: > On Saturday 21 November 2015 20:45:38 Måns Rullgård wrote: >> On 21 November 2015 20:39:58 GMT+00:00, Arnd Bergmann <arnd@arndb.de> wrote: >> >On Friday 20 November 2015 17:23:14 Stephen Boyd wrote: >> >> This is a respin of a patch series from about a year ago[1]. I >> >realized >> >> that we already had most of the code in recordmcount to figure out >> >> where we make calls to particular functions, so recording where >> >> we make calls to the integer division functions should be easy enough >> >> to add support for in the same codepaths. Looking back on the thread >> >> it seems like Mans was thinking along the same lines, although it >> >wasn't >> >> obvious to me back then or even over the last few days when I wrote >> >this. >> > >> >Shouldn't we start by allowing to build the kernel for -march=armv7ve >> >on platforms that allow it? That would seem like a simpler change >> >and likely generate better code for most people, except when you >> >actually >> >care about running the same binary kernel on older platforms. >> > >> >I tried to get a complete list of CPU cores with idiv, lpae and >> >virtualization support at some point, but I don't remember the >> >details for all Qualcomm and Marvell cores any more, to create the >> >complete configuration matrix. IIRC, all CPUs that support >> >virtualization also do lpae (they have to) and all CPUs that >> >do lpae also do idiv, but the opposite is not true. >> > >> >> The ARM ARM says anything with virt has idiv, lpae doesn't matter. > > Ok, and anything with virt also has lpae by definition. The question is > whether we care about using idiv on cores that do not have lpae, or that > have neither lpae nor virt. The question is, are there any such cores? GCC doesn't know of any, but then it's missing most non-ARM designs. -- Måns Rullgård mans@mansr.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2015-11-22 00:20 +0100 |
| Message-ID | <qxpBL-3JL-1@gated-at.bofh.it> |
| In reply to | #1274766 |
On Saturday 21 November 2015 22:11:36 Måns Rullgård wrote: > Arnd Bergmann <arnd@arndb.de> writes: > > On Saturday 21 November 2015 20:45:38 Måns Rullgård wrote: > >> On 21 November 2015 20:39:58 GMT+00:00, Arnd Bergmann <arnd@arndb.de> wrote: > >> > >> The ARM ARM says anything with virt has idiv, lpae doesn't matter. > > > > Ok, and anything with virt also has lpae by definition. The question is > > whether we care about using idiv on cores that do not have lpae, or that > > have neither lpae nor virt. > > The question is, are there any such cores? GCC doesn't know of any, but > then it's missing most non-ARM designs. Exactly. Stephen should be able to find out about the Qualcomm cores, and http://comments.gmane.org/gmane.linux.ports.arm.kernel/426289 has some information about the others: * Brahma-B15 supports all three. * Dove (PJ4) reports idiv only in thumb mode, which I'm tempted to ignore for the kernel, as it supports neither lpae nor idiva. * Armada 370/XP (PJ4B) reports support for idiva and idivt, but according to https://groups.google.com/a/dartlang.org/forum/#!topic/reviews/9wvsJvq0YYY that may be a lie. * According to the same source, Krait fails to report idiva and idivt, but supports both anyway. However, I found reports on the web where /proc/cpuinfo correctly contains the flags on the same SoC (APQ8064) that was mentioned there, so maybe they were just running an old kernel. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2015-11-22 00:30 +0100 |
| Message-ID | <qxpLr-3NP-7@gated-at.bofh.it> |
| In reply to | #1274768 |
On Sunday 22 November 2015 00:14:14 Arnd Bergmann wrote:
> On Saturday 21 November 2015 22:11:36 Måns Rullgård wrote:
> > Arnd Bergmann <arnd@arndb.de> writes:
> > > On Saturday 21 November 2015 20:45:38 Måns Rullgård wrote:
> > >> On 21 November 2015 20:39:58 GMT+00:00, Arnd Bergmann <arnd@arndb.de> wrote:
> > >>
> > >> The ARM ARM says anything with virt has idiv, lpae doesn't matter.
> > >
> > > Ok, and anything with virt also has lpae by definition. The question is
> > > whether we care about using idiv on cores that do not have lpae, or that
> > > have neither lpae nor virt.
> >
> > The question is, are there any such cores? GCC doesn't know of any, but
> > then it's missing most non-ARM designs.
>
> Exactly. Stephen should be able to find out about the Qualcomm cores,
> and http://comments.gmane.org/gmane.linux.ports.arm.kernel/426289 has
> some information about the others:
> * Brahma-B15 supports all three.
> * Dove (PJ4) reports idiv only in thumb mode, which I'm tempted to ignore
> for the kernel, as it supports neither lpae nor idiva.
> * Armada 370/XP (PJ4B) reports support for idiva and idivt, but according to
> https://groups.google.com/a/dartlang.org/forum/#!topic/reviews/9wvsJvq0YYY
> that may be a lie.
> * According to the same source, Krait fails to report idiva and idivt,
> but supports both anyway. However, I found reports on the web where
> /proc/cpuinfo correctly contains the flags on the same SoC (APQ8064)
> that was mentioned there, so maybe they were just running an old
> kernel.
This has some more information:
commit 120ecfafabec382c4feb79ff159ef42a39b6d33b
Author: Stepan Moskovchenko <stepanm@codeaurora.org>
Date: Mon Mar 18 19:44:16 2013 +0100
ARM: 7678/1: Work around faulty ISAR0 register in some Krait CPUs
Some early versions of the Krait CPU design incorrectly indicate
that they only support the UDIV and SDIV instructions in Thumb
mode when they actually support them in ARM and Thumb mode. It
seems that these CPUs follow the DDI0406B ARM ARM which has two
possible values for the divide instructions field, instead of the
DDI0406C document which has three possible values.
Work around this problem by checking the MIDR against Krait CPUs
with this faulty ISAR0 register and force the hwcaps to indicate
support in both modes.
[sboyd: Rewrote commit text to reflect real reasoning now that
we autodetect udiv/sdiv]
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
so Krait clearly supports them, and this also explains why some
machines misreport it depending on the CPU version and kernel
release running on it.
Regarding PJ4, it's still unclear whether that has the same
problem and it only reports idivt when it actually supports idiva,
or whether the lack of idiva support on PJ4 is instead the reason
why the ARM ARM was updated to have separate flags.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | linux.kernel
csiph-web