]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.39/patches.arch/s390-17-perf-09-module-plt.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / s390-17-perf-09-module-plt.patch
diff --git a/src/patches/suse-2.6.27.39/patches.arch/s390-17-perf-09-module-plt.patch b/src/patches/suse-2.6.27.39/patches.arch/s390-17-perf-09-module-plt.patch
new file mode 100644 (file)
index 0000000..a63f52c
--- /dev/null
@@ -0,0 +1,50 @@
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: [S390] module function call optimization
+References: bnc#532063,LTC#55526
+
+commit 504665a91498f43d220b7d0942281067283a35f7
+Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date:   Thu Mar 26 15:24:36 2009 +0100
+
+    [S390] module function call optimization
+    
+    Avoid the detour over the PLT if the branch target of a function call
+    in a module is in the range of the bras (16-bit) or brasl (32-bit)
+    instruction. The PLT is still generated but it is unused.
+    
+    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+Acked-by: John Jolly <jjolly@suse.de>
+
+diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
+index 59b4e79..eed4a00 100644
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+                       info->plt_initialized = 1;
+               }
+               if (r_type == R_390_PLTOFF16 ||
+-                  r_type == R_390_PLTOFF32
+-                  || r_type == R_390_PLTOFF64
+-                      )
++                  r_type == R_390_PLTOFF32 ||
++                  r_type == R_390_PLTOFF64)
+                       val = me->arch.plt_offset - me->arch.got_offset +
+                               info->plt_offset + rela->r_addend;
+-              else
+-                      val =  (Elf_Addr) me->module_core +
+-                              me->arch.plt_offset + info->plt_offset + 
+-                              rela->r_addend - loc;
++              else {
++                      if (!((r_type == R_390_PLT16DBL &&
++                             val - loc + 0xffffUL < 0x1ffffeUL) ||
++                            (r_type == R_390_PLT32DBL &&
++                             val - loc + 0xffffffffULL < 0x1fffffffeULL)))
++                              val = (Elf_Addr) me->module_core +
++                                      me->arch.plt_offset +
++                                      info->plt_offset;
++                      val += rela->r_addend - loc;
++              }
+               if (r_type == R_390_PLT16DBL)
+                       *(unsigned short *) loc = val >> 1;
+               else if (r_type == R_390_PLTOFF16)