linux_dsm_epyc7002/arch
Michael Neuling c974809a26 powerpc/vdso: Avoid link stack corruption in __get_datapage()
powerpc has a link register (lr) used for calling functions. We "bl
<func>" to call a function, and "blr" to return back to the call site.

The lr is only a single register, so if we call another function from
inside this function (ie. nested calls), software must save away the
lr on the software stack before calling the new function. Before
returning (ie. before the "blr"), the lr is restored by software from
the software stack.

This makes branch prediction quite difficult for the processor as it
will only know the branch target just before the "blr".

To help with this, modern powerpc processors keep a (non-architected)
hardware stack of lr called a "link stack". When a "bl <func>" is
run, the lr is pushed onto this stack. When a "blr" is called, the
branch predictor pops the lr value from the top of the link stack, and
uses it to predict the branch target. Hence the processor pipeline
knows a lot earlier the branch target.

This works great but there are some cases where you call "bl" but
without a matching "blr". Once such case is when trying to determine
the program counter (which can't be read directly). Here you "bl+4;
mflr" to get the program counter. If you do this, the link stack will
get out of sync with reality, causing the branch predictor to
mis-predict subsequent function returns.

To avoid this, modern micro-architectures have a special case of bl.
Using the form "bcl 20,31,+4", ensures the processor doesn't push to
the link stack.

The 32 and 64 bit variants of __get_datapage() use a "bl; mflr" to
determine the loaded address of the VDSO. The current versions of
these attempt to use this special bl variant.

Unfortunately they use +8 rather than the required +4. Hence the
current code results in the link stack getting out of sync with
reality and hence the resulting performance degradation.

This patch moves it to bcl+4 by moving __kernel_datapage_offset out of
__get_datapage().

With this patch, running a gettimeofday() (which uses
__get_datapage()) microbenchmark we get a decent bump in performance
on POWER7/8.

For the benchmark in tools/testing/selftests/powerpc/benchmarks/gettimeofday.c
  POWER8:
    64bit gets ~4% improvement
    32bit gets ~9% improvement
  POWER7:
    64bit gets ~7% improvement

Signed-off-by: Michael Neuling <mikey@neuling.org>
Reported-by: Aaron Sawdey <sawdey@us.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2015-10-01 16:52:02 +10:00
..
alpha PCI updates for v4.3: 2015-09-25 11:16:53 -07:00
arc genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
arm Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm 2015-09-27 06:48:48 -04:00
arm64 AMD fixes for bugs introduced in the 4.2 merge window, 2015-09-25 10:51:40 -07:00
avr32 genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
blackfin genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
c6x genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
cris CRISv10: delete unused lib/dmacopy.c 2015-09-05 00:56:51 +02:00
frv PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code" 2015-09-15 13:18:04 -05:00
h8300 dma-mapping: consolidate dma_set_mask 2015-09-10 13:29:01 -07:00
hexagon Merge branch 'akpm' (patches from Andrew) 2015-09-10 18:19:42 -07:00
ia64 PCI updates for v4.3: 2015-09-25 11:16:53 -07:00
m32r lib/decompressors: use real out buf size for gunzip with kernel 2015-09-10 13:29:01 -07:00
m68k genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
metag genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
microblaze PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code" 2015-09-15 13:18:04 -05:00
mips PCI updates for v4.3: 2015-09-25 11:16:53 -07:00
mn10300 PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code" 2015-09-15 13:18:04 -05:00
nios2 nios2: add Max10 defconfig 2015-09-08 18:16:02 +08:00
openrisc dma-mapping: consolidate dma_set_mask 2015-09-10 13:29:01 -07:00
parisc parisc: Use platform_device_register_simple("rtc-generic") 2015-09-08 17:53:48 +02:00
powerpc powerpc/vdso: Avoid link stack corruption in __get_datapage() 2015-10-01 16:52:02 +10:00
s390 AMD fixes for bugs introduced in the 4.2 merge window, 2015-09-25 10:51:40 -07:00
score Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2015-09-01 14:04:50 -07:00
sh genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
sparc genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
tile genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
um Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2015-09-01 14:04:50 -07:00
unicore32 genirq: Remove irq argument from irq flow handlers 2015-09-16 15:47:51 +02:00
x86 Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2015-09-27 06:51:42 -04:00
xtensa PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code" 2015-09-15 13:18:04 -05:00
.gitignore
Kconfig kexec: split kexec_load syscall from kexec core code 2015-09-10 13:29:01 -07:00