Currently core file of aarch32 process prstatus note has empty
registers set. As result aarch32 core files create by V8 kernel are
not very useful.
It happens because compat_gpr_get and compat_gpr_set functions can
copy registers values to/from either kbuf or ubuf. ELF core file
collection function fill_thread_core_info calls compat_gpr_get
with kbuf set and ubuf set to 0. But current compat_gpr_get and
compat_gpr_set function handle copy to/from only ubuf case.
Fix is to handle kbuf and ubuf as two separate cases in similar
way as other functions like user_regset_copyout, user_regset_copyin do.
Signed-off-by: Victor Kamensky <victor.kamensky(a)linaro.org>
Acked-by: Will Deacon <will.deacon(a)arm.com>
Cc: stable(a)vger.kernel.org
Cc: Catalin Marinas <catalin.marinas(a)arm.com>
---
arch/arm64/kernel/ptrace.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 6a8928b..9c9c2b9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -650,11 +650,16 @@ static int compat_gpr_get(struct task_struct *target,
reg = task_pt_regs(target)->regs[idx];
}
- ret = copy_to_user(ubuf, ®, sizeof(reg));
- if (ret)
- break;
-
- ubuf += sizeof(reg);
+ if (kbuf) {
+ memcpy(kbuf, ®, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_to_user(ubuf, ®, sizeof(reg));
+ if (ret)
+ break;
+
+ ubuf += sizeof(reg);
+ }
}
return ret;
@@ -684,11 +689,16 @@ static int compat_gpr_set(struct task_struct *target,
unsigned int idx = start + i;
compat_ulong_t reg;
- ret = copy_from_user(®, ubuf, sizeof(reg));
- if (ret)
- return ret;
+ if (kbuf) {
+ memcpy(®, kbuf, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_from_user(®, ubuf, sizeof(reg));
+ if (ret)
+ return ret;
- ubuf += sizeof(reg);
+ ubuf += sizeof(reg);
+ }
switch (idx) {
case 15:
--
1.8.1.4
Implement and enable context tracking for arm64 (which is
a prerequisite for FULL_NOHZ support). This patchset
builds upon earlier work by Kevin Hilman and is based on
Will Deacon's tree.
Changes v5 to v6:
* Don't save far_el1 in x26 in el0_dbg path (not needed)
* TIF_NOHZ processes go through the slow path (so no register
save/restore is needed in ct_user_enter)
Changes v4 to v5:
* Improvement to code restoring far_el1 (suggested by Christopher Covington)
* Improvement to register save/restore in ct_user_enter
Changes v3 to v4:
* Rename parameter of ct_user_exit from save to restore
* Rebased patch to Will Deacon's tree (branch remotes/origin/aarch64
of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git)
Changes v2 to v3:
* Save/restore necessary registers in ct_user_enter and ct_user_exit
* Annotate "error paths" out of el0_sync with ct_user_exit
Changes v1 to v2:
* Save far_el1 in x26 temporarily
Larry Bassel (2):
arm64: adjust el0_sync so that a function can be called
arm64: enable context tracking
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/thread_info.h | 4 +++
arch/arm64/kernel/entry.S | 58 +++++++++++++++++++++++++++++++-----
3 files changed, 56 insertions(+), 7 deletions(-)
--
1.8.3.2
Hi Catalin, Will,
I've run into situation when core of aarch32 (V7) process created
by V8 kernel has empty registers set saved in prstatus notes. As
result core file are broken. Below are details on the issues. Proposed
patch follows this cover letter.
Test Case For Problem
---------------------
V8 kernel runs with v7 rootfs. Below output for BE system but LE has
the same issue. hello test case compiled as v7 code. Notice that
all registers in core file are zeros.
root@genericarmv7ab:~# cat hello.c
#include <stdio.h>
int main (void)
{
printf("Hello, world\n");
*(int *) 0 = 0;
}
root@genericarmv7ab:~# ./hello
Hello, world
hello[825]: unhandled level 3 translation fault (11) at 0x00000000, esr 0x92000047
pgd = ffffffc07cb02000
[00000000] *pgd=00000000fcad2003, *pmd=00000000fcad9003, *pte=0000000000000000
CPU: 0 PID: 825 Comm: hello Not tainted 3.15.0-rc5+ #1
task: ffffffc07dbf0000 ti: ffffffc07c978000 task.ti: ffffffc07c978000
PC is at 0x8434
LR is at 0xf74e03c4
pc : [<0000000000008434>] lr : [<00000000f74e03c4>] pstate: 600f0210
sp : 00000000ff9ce128
x12: 000000000000000d
x11: 00000000ff9ce12c x10: 00000000f75d2000
x9 : 0000000000000000 x8 : 0000000000000000
x7 : 0000000000000000 x6 : 00000000000082f4
x5 : 0000000000000000 x4 : 00000000ff9ce148
x3 : 0000000000000000 x2 : 0000000000000000
x1 : 0000000000000000 x0 : 000000000000000d
Segmentation fault (core dumped)
root@genericarmv7ab:~# gdb hello
GNU gdb (Linaro GDB) 7.6.1-2013.10
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "armeb-oe-linux-gnueabi".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/root/hello...done.
(gdb) target core core
[New LWP 825]
Program terminated with signal 11, Segmentation fault.
#0 0x00000000 in ?? ()
(gdb) info reg
r0 0x0 0
r1 0x0 0
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x0 0x0
lr 0x0 0
pc 0x0 0x0
cpsr 0x0 0
(gdb)
If one look at core file notes it can see that all registers in
PRSTATUS note are zeros:
[root@kamensky-w530 root]# eu-readelf --notes ~kamensky/v8v7-core/v8_v7_le_core
Note segment of 984 bytes at offset 0x1f4:
Owner Data size Type
CORE 148 PRSTATUS
info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
sigpend: <>
sighold: <>
pid: 1358, ppid: 1351, pgrp: 1358, sid: 1349
utime: 0.000000, stime: 0.020000, cutime: 0.000000, cstime: 0.000000
orig_r0: 0, fpvalid: 0
r0: 0 r1: 0 r2: 0
r3: 0 r4: 0 r5: 0
r6: 0 r7: 0 r8: 0
r9: 0 r10: 0 r11: 0
r12: 0 sp: 0x00000000 lr: 0x00000000
pc: 0x00000000 spsr: 0x00000000
Writing prstatus code under debugger
------------------------------------
Here is backtrace of code that writes PRSTATUS note. compat_gpr_get
called to fill in registers value. Note kbuf has valid address,
ubuf is 0.
#0 compat_gpr_get( target = (struct task_struct*) 0xFFFFFFC07CB39400, regset = (const struct user_regset*) 0xFFFFFFC0003D5290, pos = 0, count = 72, kbuf = (void*) 0xFFFFFFC07CFE4158, ubuf = (void*) 0x0 ) at ptrace.c:622
#1 fill_note( data = (void*) 0xFFFFFFC07CFE4110, sz = 148, type = 1, name = 0xFFFFFFC0004C4670 "CORE", note = (struct memelfnote*) 0xFFFFFFC07CFE41A8 ) at binfmt_elf.c:1279
#2 fill_thread_core_info( view = (const struct user_regset_view*) 0xFFFFFFC0003D5300, view = (const struct user_regset_view*) 0xFFFFFFC0003D5300, total = (size_t*) 0xFFFFFFC07C8B3B18, signr = <Value currently has no location>, t = (struct elf_thread_core_info*) 0xFFFFFFC07CFE4100 ) at binfmt_elf.c:1541
#3 elf_core_dump( cprm = (struct coredump_params*) 0xFFFFFFC07C8B3C38 ) at binfmt_elf.c:2123
#4 write_note_info( cprm = (struct coredump_params*) 0xFFFFFFC07C8B3C38, info = (struct elf_note_info*) 0xFFFFFFFFFFFFFFF8 ) at binfmt_elf.c:1698
#5 do_coredump( siginfo = <Value optimised away by compiler> ) at coredump.c:667
#6 get_signal_to_deliver( info = (siginfo_t*) 0xFFFFFFC07C8B3DF0, return_ka = (struct k_sigaction*) 0xFFFFFFC07C8B3E70, regs = <Value optimised away by compiler>, cookie = <Value optimised away by compiler> ) at signal.c:2372
#7 do_signal( regs = (struct pt_regs*) 0xFFFFFFC07C8B3ED0 ) at signal.c:377
#8 do_notify_resume( regs = <Value optimised away by compiler>, thread_flags = <Value optimised away by compiler> ) at signal.c:413
#9 [/wd1/linaro/linux-build/_le_64_linus_062/vmlinux EL1N:0xFFFFFFC00008428C ]
p ubuf
$30 = (void*) 0x0
p kbuf
$31 = (void*) 0xFFFFFFC07CFE4158
Fix
---
In compat_gpr_get and compat_gpr_set functions
handle kbuf and ubuf as two separate cases as other similar functions do,
i.e user_regset_copyout, user_regset_copyin functions
Tests
-----
Tested core files or single threaded and multithread aarch32 processes.
Able to see registers value, execute backtrace command, etc.
Thanks,
Victor
Victor Kamensky (1):
arm64: ptrace: fix empty registers set in prstatus of aarch32 process
core
arch/arm64/kernel/ptrace.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
--
1.8.1.4
3.11.10.11 -stable review patch. If anyone has any objections, please let me know.
------------------
From: Viresh Kumar <viresh.kumar(a)linaro.org>
commit 84ea7fe37908254c3bd90910921f6e1045c1747a upstream.
switch_hrtimer_base() calls hrtimer_check_target() which ensures that
we do not migrate a timer to a remote cpu if the timer expires before
the current programmed expiry time on that remote cpu.
But __hrtimer_start_range_ns() calls switch_hrtimer_base() before the
new expiry time is set. So the sanity check in hrtimer_check_target()
is operating on stale or even uninitialized data.
Update expiry time before calling switch_hrtimer_base().
[ tglx: Rewrote changelog once again ]
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
Cc: linaro-kernel(a)lists.linaro.org
Cc: linaro-networking(a)linaro.org
Cc: fweisbec(a)gmail.com
Cc: arvind.chauhan(a)arm.com
Link: http://lkml.kernel.org/r/81999e148745fc51bbcd0615823fbab9b2e87e23.139988225…
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Luis Henriques <luis.henriques(a)canonical.com>
---
kernel/hrtimer.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6de65d8a70e2..aa149222cd8e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1002,11 +1002,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
/* Remove an active timer from the queue: */
ret = remove_hrtimer(timer, base);
- /* Switch the timer base, if necessary: */
- new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
-
if (mode & HRTIMER_MODE_REL) {
- tim = ktime_add_safe(tim, new_base->get_time());
+ tim = ktime_add_safe(tim, base->get_time());
/*
* CONFIG_TIME_LOW_RES is a temporary way for architectures
* to signal that they simply return xtime in
@@ -1021,6 +1018,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
hrtimer_set_expires_range_ns(timer, tim, delta_ns);
+ /* Switch the timer base, if necessary: */
+ new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
+
timer_stats_hrtimer_set_start_info(timer);
leftmost = enqueue_hrtimer(timer, new_base);
--
1.9.1
Hi,
This is my third attempt to migrate clockevent drivers to use set_dev_mode(). I
have tried to fix all issues raised by Frederic/Kevin on V2.
Please let me know if I missed something. Though patches 2-7 look big, it should
be fairly easy to review them now, so do try that :)
---------
A clockevent device should be stopped, or its events should be masked, if next
event is expected at KTIME_MAX, i.e. no events are required for very long time.
This would normally happen with NO_HZ (both NO_HZ_IDLE and NO_HZ_FULL) when
tick-sched timer is removed and we don't have any more timers scheduled for
long.
If we don't STOP clockevent device, we are guaranteed to receive at least one
spurious interrupt, as hrtimer_force_reprogram() isn't reprogramming the event
device (on expires == KTIME_MAX). Depending on particular implementation of
clockevent device, this can be a spurious interrupt at tick-rate.. (When driver
is emulating ONESHOT over PERIODIC mode. This was observed on at-least one
implementation: arm_arch_timer.c).
A simple (yet hacky) solution to get this fixed could be: update
hrtimer_force_reprogram() to always reprogram clockevent device and update
clockevent drivers to STOP generating events (or delay it to max time), when
'expires' is set to KTIME_MAX. But the drawback here is that every clockevent
driver has to be hacked for this particular case and its very easy for new ones
to miss this.
However, Thomas suggested to add an optional mode: ONESHOT_STOPPED
(lkml.org/lkml/2014/5/9/508) to solve this problem.
clockevents core would need to reconfigure mode later, when event is required
again, for platforms that implement ONESHOT_STOPPED mode and so it must know
which platforms implement it and which don't. This requires ->set_mode()
callback to have capability to return 'success' or 'failure'. Currently its
return type is 'void'.
To change return type of set_mode(), Thomas suggested to implement another
callback: ->set_dev_mode(), with return type 'int'. We can then convert
clockevent drivers to use this interface instead of existing ->set_mode() and
then finally remove ->set_mode()'s support.
This patchset first adds another callback with return capability,
set_dev_mode(), then it migrates all drivers one by one and finally removes
earlier callback set_mode() when nobody is using it.
NOTE: Following issue is still unresolved as this patchset isn't making it
worse. But it should be fixed before addition of ONESHOT_STOPPED mode.
Few clockevent drivers have disabled clock events as soon as we enter their
->set_dev_mode() callbacks and so they stay disabled for unsupported modes as
well.
All clockevent drivers are handling modes in ->set_dev_mode() with help of a
'switch' block. For the currently available modes none of them would ever get
down to the 'default case' of switch block.
And so we would never hit the BUG where we failed to change mode and still
disabled clock events.
But as soon as any new mode would be introduced in clockevents core, some of
these might behave unexpectedly. Like, core may expect events to be enabled as
call to ->set_dev_mode() returned failure and may not try enabling events again.
V2->V3:
- s/WARN_ON/WARN_ON_ONCE
- improved logs
- V2 had code belonging to problem mentioned in "NOTE" above, its dropped now
and would be addressed separately.
Viresh Kumar (8):
clockevents: add ->set_dev_mode() to struct clock_event_device
clockevents: arm: migrate to ->set_dev_mode()
clockevents: mips: migrate to ->set_dev_mode()
clockevents: sparc: migrate to ->set_dev_mode()
clockevents: x86: migrate to ->set_dev_mode()
clockevents: drivers/: migrate to ->set_dev_mode()
clockevents: misc: migrate to ->set_dev_mode()
clockevents: remove ->set_mode() from struct clock_event_device
arch/alpha/kernel/time.c | 32 ++++++++++++++++++----
arch/arc/kernel/time.c | 11 +++++---
arch/arm/common/timer-sp.c | 9 ++++---
arch/arm/kernel/smp_twd.c | 10 ++++---
arch/arm/mach-at91/at91rm9200_time.c | 7 +++--
arch/arm/mach-at91/at91sam926x_time.c | 11 ++++----
arch/arm/mach-clps711x/common.c | 9 ++++---
arch/arm/mach-cns3xxx/core.c | 10 ++++---
arch/arm/mach-davinci/time.c | 7 +++--
arch/arm/mach-footbridge/dc21285-timer.c | 7 +++--
arch/arm/mach-gemini/time.c | 7 ++---
arch/arm/mach-imx/epit.c | 11 ++++----
arch/arm/mach-imx/time.c | 11 ++++----
arch/arm/mach-integrator/integrator_ap.c | 8 +++---
arch/arm/mach-ixp4xx/common.c | 8 +++---
arch/arm/mach-ks8695/time.c | 22 ++++++++++-----
arch/arm/mach-lpc32xx/timer.c | 11 ++++----
arch/arm/mach-mmp/time.c | 12 +++++----
arch/arm/mach-netx/time.c | 11 ++++----
arch/arm/mach-omap1/time.c | 7 +++--
arch/arm/mach-omap1/timer32k.c | 7 +++--
arch/arm/mach-omap2/timer.c | 7 +++--
arch/arm/mach-pxa/time.c | 8 +++---
arch/arm/mach-sa1100/time.c | 8 +++---
arch/arm/mach-spear/time.c | 10 +++----
arch/arm/mach-w90x900/time.c | 7 +++--
arch/arm/plat-iop/time.c | 8 +++---
arch/arm/plat-orion/time.c | 20 ++++++++++----
arch/avr32/kernel/time.c | 7 ++---
arch/blackfin/kernel/time-ts.c | 14 +++++++---
arch/c6x/platforms/timer64.c | 7 +++--
arch/hexagon/kernel/time.c | 11 +++++---
arch/m68k/platform/coldfire/pit.c | 7 +++--
arch/microblaze/kernel/timer.c | 7 +++--
arch/mips/alchemy/common/time.c | 14 ++++++++--
arch/mips/include/asm/cevt-r4k.h | 2 +-
arch/mips/jazz/irq.c | 14 ++++++++--
arch/mips/jz4740/time.c | 9 ++++---
arch/mips/kernel/cevt-bcm1480.c | 11 +++++---
arch/mips/kernel/cevt-ds1287.c | 12 ++++++---
arch/mips/kernel/cevt-gic.c | 14 ++++++++--
arch/mips/kernel/cevt-gt641xx.c | 12 ++++++---
arch/mips/kernel/cevt-r4k.c | 14 ++++++++--
arch/mips/kernel/cevt-sb1250.c | 11 +++++---
arch/mips/kernel/cevt-smtc.c | 2 +-
arch/mips/kernel/cevt-txx9.c | 7 +++--
arch/mips/loongson/common/cs5536/cs5536_mfgpt.c | 12 ++++-----
arch/mips/ralink/cevt-rt3352.c | 13 +++++----
arch/mips/sgi-ip27/ip27-timer.c | 14 ++++++++--
arch/mips/sni/time.c | 9 ++++---
arch/mn10300/kernel/cevt-mn10300.c | 14 ++++++++--
arch/openrisc/kernel/time.c | 11 ++++----
arch/powerpc/kernel/time.c | 16 ++++++++---
arch/s390/kernel/time.c | 14 ++++++++--
arch/score/kernel/time.c | 8 +++---
arch/sh/kernel/localtimer.c | 15 +++++++++--
arch/sparc/kernel/time_32.c | 18 ++++++++-----
arch/sparc/kernel/time_64.c | 11 ++++----
arch/tile/kernel/time.c | 16 ++++++++---
arch/um/kernel/time.c | 7 +++--
arch/unicore32/kernel/time.c | 8 +++---
arch/x86/kernel/apic/apic.c | 10 ++++---
arch/x86/kernel/hpet.c | 19 +++++++------
arch/x86/lguest/boot.c | 9 ++++---
arch/x86/platform/uv/uv_time.c | 10 ++++---
arch/x86/xen/time.c | 23 +++++++---------
arch/xtensa/kernel/time.c | 9 ++++---
drivers/clocksource/arm_arch_timer.c | 36 ++++++++++++++-----------
drivers/clocksource/arm_global_timer.c | 9 ++++---
drivers/clocksource/bcm2835_timer.c | 8 +++---
drivers/clocksource/bcm_kona_timer.c | 10 ++++---
drivers/clocksource/cadence_ttc_timer.c | 7 +++--
drivers/clocksource/cs5535-clockevt.c | 17 +++++++++---
drivers/clocksource/dummy_timer.c | 15 +++++++++--
drivers/clocksource/dw_apb_timer.c | 7 +++--
drivers/clocksource/em_sti.c | 11 +++++---
drivers/clocksource/exynos_mct.c | 16 +++++++----
drivers/clocksource/i8253.c | 8 ++++--
drivers/clocksource/metag_generic.c | 11 ++++----
drivers/clocksource/moxart_timer.c | 8 +++---
drivers/clocksource/mxs_timer.c | 10 +++----
drivers/clocksource/nomadik-mtu.c | 7 +++--
drivers/clocksource/qcom-timer.c | 11 ++++----
drivers/clocksource/samsung_pwm_timer.c | 7 +++--
drivers/clocksource/sh_cmt.c | 9 ++++---
drivers/clocksource/sh_mtu2.c | 9 ++++---
drivers/clocksource/sh_tmu.c | 9 ++++---
drivers/clocksource/sun4i_timer.c | 9 ++++---
drivers/clocksource/tcb_clksrc.c | 11 +++++---
drivers/clocksource/tegra20_timer.c | 7 +++--
drivers/clocksource/time-armada-370-xp.c | 20 +++++++++-----
drivers/clocksource/time-efm32.c | 7 +++--
drivers/clocksource/time-orion.c | 17 +++++++++---
drivers/clocksource/timer-keystone.c | 9 ++++---
drivers/clocksource/timer-marco.c | 10 ++++---
drivers/clocksource/timer-prima2.c | 10 +++----
drivers/clocksource/timer-sun5i.c | 10 ++++---
drivers/clocksource/timer-u300.c | 7 +++--
drivers/clocksource/vf_pit_timer.c | 12 ++++++---
drivers/clocksource/vt8500_timer.c | 8 +++---
drivers/clocksource/zevio-timer.c | 9 +++----
include/linux/clockchips.h | 4 +--
kernel/time/clockevents.c | 7 +++--
kernel/time/tick-broadcast-hrtimer.c | 11 +++++---
kernel/time/timer_list.c | 2 +-
105 files changed, 756 insertions(+), 376 deletions(-)
--
2.0.0.rc2