Hi all,
In v8, addressed Jason's comments:
- Changed kgdb_enable_nmi() weak function to kgdb_arch callbck;
- We no longer register disable_nmi command if arch does not register
KGDB NMI handling (i.e. not filling kgdb_arch.enable_nmi callback);
- The same is for ttyNMI: if architecure does not provide us with
enable_nmi call, we don't need the tty device. Of course, there is no
way to tell wether a specific serial device can be used for NMI
debugging, as it is not serial-device specific, but specific to
whether IRQ can be rerouted to an NMI (for most our cases, pretty
much every IRQ can be rerouted, e.g. a hot-pluggable serial device on
a PCI bus).
- Rebased on the latest and greatest tty-next, just in case.
These patches can be found in the following repo (based on tty-next):
git://git.infradead.org/users/cbou/linux-nmi-kdb.git master
Old changelogs and rationale for these patches can be found here:
v1-v5, rationale: http://lkml.org/lkml/2012/9/10/2
v6: http://lkml.org/lkml/2012/9/10/2
v7: http://lkml.org/lkml/2012/9/13/367
Thanks,
--
arch/arm/Kconfig | 19 ++
arch/arm/common/vic.c | 28 +++
arch/arm/include/asm/hardware/vic.h | 2 +
arch/arm/include/asm/kgdb.h | 8 +
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/entry-armv.S | 167 +------------
arch/arm/kernel/entry-header.S | 170 +++++++++++++
arch/arm/kernel/kgdb_fiq.c | 124 +++++++++
arch/arm/kernel/kgdb_fiq_entry.S | 87 +++++++
arch/arm/mach-versatile/Makefile | 1 +
arch/arm/mach-versatile/kgdb_fiq.c | 31 +++
drivers/tty/serial/Kconfig | 19 ++
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/amba-pl011.c | 73 +++++-
drivers/tty/serial/kgdb_nmi.c | 402 ++++++++++++++++++++++++++++++
drivers/tty/serial/kgdboc.c | 9 +
drivers/tty/serial/serial_core.c | 17 ++
include/linux/kdb.h | 29 ++-
include/linux/kgdb.h | 13 +
include/linux/serial_core.h | 1 +
kernel/debug/debug_core.c | 14 +-
kernel/debug/kdb/kdb_main.c | 31 +++
22 files changed, 1054 insertions(+), 193 deletions(-)
The Virtualization Extensions introduce the requirement for an ARMv7-A
implementation to include SDIV and UDIV. Any implementation of the
Virtualization Extensions must include the SDIV and UDIV instructions
in the Thumb and ARM instruction sets.
In an ARMv7-A implementation that does not include the Virtualization
Extensions, it is IMPLEMENTATION DEFINED whether:
* SDIV and UDIV are not implemented
* SDIV and UDIV are implemented only in the Thumb instruction set
* SDIV and UDIV are implemented in the Thumb and ARM instruction sets.
This patch adds a handler to trap and emulate unimplemented SDIV and
UDIV instructions in ARM and Thumb modes. Also some basic statistic is
exported via /proc/cpu/idiv_emulation
Signed-off-by: Vladimir Murzin <murzin.v(a)gmail.com>
---
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/idiv_emulate.c | 194 ++++++++++++++++++++++++++++++++++++++++
arch/arm/mm/Kconfig | 26 ++++++
3 files changed, 221 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/kernel/idiv_emulate.c
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 7ad2d5c..057a630 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_OF) += devtree.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
+obj-$(CONFIG_IDIV_EMULATE) += idiv_emulate.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
diff --git a/arch/arm/kernel/idiv_emulate.c b/arch/arm/kernel/idiv_emulate.c
new file mode 100644
index 0000000..f021d0e
--- /dev/null
+++ b/arch/arm/kernel/idiv_emulate.c
@@ -0,0 +1,195 @@
+/*
+ * linux/arch/arm/kernel/idiv_emulate.c
+ *
+ * This code is based on swp_emulate.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Implements emulation of the SDIV/UDIV instructions. They are defined for
+ * ARMv7-R and ARMv7-M profiles (in Thumb state only) and are UNDEFINED in the
+ * ARMv7-A profile. SDIV/UDIV are present by default on Cortex-A15.
+ *
+ * This emulation allow using integer divide instructions in case hardware is
+ * not presented
+ *
+ * Syntax of SDIV/UDIV instructions: SDIV/UDIV<c> <Rd>,<Rn>,<Rm>
+ * Where: Rd = the destination register.
+ * Rn = the register that contains the dividend.
+ * Rm = the register that contains the divisor.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/perf_event.h>
+
+#include <asm/opcodes.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+/*
+ * Macros/defines for extracting register numbers from instruction.
+ */
+#define EXTRACT_REG_NUM(instruction, offset) \
+ (((instruction) & (0xf << (offset))) >> (offset))
+
+/*
+ * Offsets for ARM mode
+ */
+#define RD_OFFSET 16
+#define RN_OFFSET 0
+#define RM_OFFSET 8
+
+/*
+ * Offsets for Thumb mode
+ */
+#define RD_T_OFFSET 8
+#define RN_T_OFFSET 16
+#define RM_T_OFFSET 0
+
+#define TYPE_OF_DIV (1 << 21)
+
+static unsigned long sdivcounter;
+static unsigned long udivcounter;
+static pid_t previous_pid;
+
+#ifdef CONFIG_PROC_FS
+static int proc_read_status(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *p = page;
+ int len;
+
+ p += sprintf(p, "Emulated UDIV:\t\t%lu\n", udivcounter);
+ p += sprintf(p, "Emulated SDIV:\t\t%lu\n", sdivcounter);
+ if (previous_pid != 0)
+ p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
+
+ len = (p - page) - off;
+ if (len < 0)
+ len = 0;
+
+ *eof = (len <= count) ? 1 : 0;
+ *start = page + off;
+
+ return len;
+}
+#endif
+
+static u32 emulate_udiv(u32 n, u32 base)
+{
+ udivcounter++;
+
+ return n/base;
+}
+
+static s32 emulate_sdiv(s32 n, s32 base)
+{
+ sdivcounter++;
+
+ return n/base;
+}
+
+static int idiv_handler(struct pt_regs *regs, unsigned int instr)
+{
+ long dividend, divisor, dest, res;
+
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->ARM_pc);
+
+ res = arm_check_condition(instr, regs->ARM_cpsr);
+
+ switch (res) {
+ case ARM_OPCODE_CONDTEST_PASS:
+ break;
+ case ARM_OPCODE_CONDTEST_FAIL:
+ /* Condition failed - return to next instruction */
+ regs->ARM_pc += 4;
+ return 0;
+ case ARM_OPCODE_CONDTEST_UNCOND:
+ if (!thumb_mode(regs))
+ return -EFAULT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (current->pid != previous_pid) {
+ pr_debug("\"%s\" (%ld) uses idiv instruction\n",
+ current->comm, (unsigned long)current->pid);
+ previous_pid = current->pid;
+ }
+
+ if (!thumb_mode(regs)) {
+ dividend = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
+ divisor = regs->uregs[EXTRACT_REG_NUM(instr, RM_OFFSET)];
+ dest = EXTRACT_REG_NUM(instr, RD_OFFSET);
+ } else {
+ dividend = regs->uregs[EXTRACT_REG_NUM(instr, RN_T_OFFSET)];
+ divisor = regs->uregs[EXTRACT_REG_NUM(instr, RM_T_OFFSET)];
+ dest = EXTRACT_REG_NUM(instr, RD_T_OFFSET);
+ }
+
+/*
+ * In an ARMv7-A profile implementation that supports the SDIV and UDIV
+ * instructions, divide-by-zero always returns a zero result.
+ * In fact, integer division emulation provided by gcc lib has already handle
+ * division by zero case sending the signal to the caused process. Emulate this
+ * behavior here as well.
+ */
+ if (!divisor) {
+ siginfo_t info;
+
+ info.si_code = FPE_INTDIV;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+
+ arm_notify_die("Division by zero", regs, &info, 0, 0);
+
+ goto out;
+ }
+
+ if (instr & TYPE_OF_DIV)
+ res = emulate_udiv((u32)dividend, (u32)divisor);
+ else
+ res = emulate_sdiv((s32)dividend, (s32)divisor);
+
+ regs->ARM_pc += 4;
+ regs->uregs[dest] = res;
+
+out:
+ return 0;
+}
+
+static struct undef_hook idiv_hook = {
+ .instr_mask = 0x0310f010,
+ .instr_val = 0x0310f010,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = USR_MODE,
+ .fn = idiv_handler
+};
+
+static int __init idiv_emulation_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *res;
+
+ res = create_proc_entry("cpu/idiv_emulation", S_IRUGO, NULL);
+
+ if (!res)
+ return -ENOMEM;
+
+ res->read_proc = proc_read_status;
+#endif /* CONFIG_PROC_FS */
+
+ pr_notice("Registering SDIV/UDIV emulation handler\n");
+
+ register_undef_hook(&idiv_hook);
+
+ return 0;
+}
+
+late_initcall(idiv_emulation_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101b968..8e2fa94 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -651,6 +651,32 @@ config SWP_EMULATE
If unsure, say Y.
+config IDIV_EMULATE
+ bool "Emulate SDIV/UDIV instructions"
+ depends on !CPU_USE_DOMAINS && CPU_V7
+ select HAVE_PROC_CPU if PROC_FS
+ default y if SMP
+ help
+
+ The Virtualization Extensions introduce the requirement for an
+ ARMv7-A implementation to include SDIV and UDIV. Any
+ implementation of the Virtualization Extensions must include
+ the SDIV and UDIV instructions in the Thumb and ARM
+ instruction sets.
+
+ In an ARMv7-A implementation that does not include the
+ Virtualization Extensions, it is IMPLEMENTATION DEFINED whether:
+ * SDIV and UDIV are not implemented
+ * SDIV and UDIV are implemented only in the Thumb instruction set
+ * SDIV and UDIV are implemented in the Thumb and ARM
+ instruction sets.
+
+ This option allows to handle exeptions due to unimplemented
+ SDIV and UDIV instructions in ARM and Thumb modes.
+
+ If unsure, say Y.
+
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
depends on ARCH_SUPPORTS_BIG_ENDIAN
--
1.7.8.6
Hi all,
Here comes the lucky v7:
- Per Alan Cox's suggestion added hangup method and removed a small
leftover;
- Per Colin Cross' suggestion moved IRQ quiescing logic into
poll_get_char routine. IIUC, Alan is less unhappy about it. As a
result, clear_irq() callback dropped.
These patches can be found in the following repo (based on tty-next):
git://git.infradead.org/users/cbou/linux-nmi-kdb.git master
Old changelogs and rationale for these patches can be found here:
v1-v5, rationale: http://lkml.org/lkml/2012/9/10/2
v6: http://lkml.org/lkml/2012/9/10/2
Thanks,
--
arch/arm/Kconfig | 19 ++
arch/arm/common/vic.c | 28 ++
arch/arm/include/asm/hardware/vic.h | 2 +
arch/arm/include/asm/kgdb.h | 8 +
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/entry-armv.S | 167 +-----------
arch/arm/kernel/entry-header.S | 170 +++++++++++++
arch/arm/kernel/kgdb_fiq.c | 99 ++++++++
arch/arm/kernel/kgdb_fiq_entry.S | 87 +++++++
arch/arm/mach-versatile/Makefile | 1 +
arch/arm/mach-versatile/kgdb_fiq.c | 31 +++
drivers/tty/serial/Kconfig | 19 ++
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/amba-pl011.c | 73 +++++-
drivers/tty/serial/kgdb_nmi.c | 396 +++++++++++++++++++++++++++++
drivers/tty/serial/kgdboc.c | 6 +
drivers/tty/serial/serial_core.c | 17 ++
include/linux/kdb.h | 29 ++-
include/linux/kgdb.h | 33 +++
include/linux/serial_core.h | 1 +
kernel/debug/debug_core.c | 36 ++-
kernel/debug/kdb/kdb_main.c | 29 +++
22 files changed, 1060 insertions(+), 193 deletions(-)
Whoops. Sorry this is late.
=== Highlights ===
* Attended a connect planning meeting
* Sent out first pass of refinied jiffies patch (help kill
CLOCK_TICK_RATE for unified-zImage)
* Sent out half of the -stable backports
* Debugged and fixed a 32bit time regression in 3.6-rc, got it merged in
tip for upstream.
* Arve pinged me on an issue they were seeing with the upstream
alarmtimer code. Implemented a solution and will be sending it out for
discussion shortly.
* Discussed with Mel Gorman on his approach to low-memory notification
* Emailed Colin Cross and AntonV to get a coffee meeting scheduled.
=== Plans ===
* Make first pass at sending SIGBUS on accessing purged volatile pages
* Send out alarmtimer fix for discussion
* Send out vsyscall update patches for discussion
* Finish testing and sending -stable backports
=== Issues ===
* NA
== Deepak Saxena <dsaxena> ==
=== Highlights ===
* Got mostly caught up on all email, minus upstream mailing lists
* Had initial discussions with Jakub on project management
* OPSCOM roadmap card review
=== Plans ===
* Update roadmap cards as per OPSCOM review
* Go through all old blueprints and clean them up
* Create BPs for currently untracked work (single zImage, aarch64)
* Catch up on Linux Plumber's Conf and Kernel Summit presentations
* Write up blueprint process for project status tracking
* Get caught up on linux-arm-kernel list
=== Issues ===
=== Travel/Time Off ===
* Travelling to NYC for 1 week,Sept 22nd - 28th, will be working half time
* Copenhagen Connect
== Status ==
* Started working on common clock support for Exynos4 platforms.
== Next Week ==
* Complete initial implementation of the common clock support for
Exynos4 platforms.
== Misc ==
* Was on leave from Sept-11 to Sept-14.
=== Highlights ===
* Setup kvm development environment.
1) build Cortex A15x1 fast model simulator
2) Successfully ran A15x1 simulator on ubuntu PC
3) Ran A15 kernel via qemu-system-arm within simulator environment
* Research kvm subsystem and qemu (read doc and code)
* Research big.LITTLE tech, read ARM doc on it and some online
technical articles
on switcher and bit.LITTLE MP scheduler, started to read ARM
reference switcher code from:
http://git.linaro.org/gitweb?p=arm/big.LITTLE/switcher.git;a=summary
== Highlights ==
* Lots of work for KDB FIQ/NMI debugger, sent out v5, v6 and v7.
Switched NMI console driver to tty_port infrastructure, discussed the
ways to handle serial interrupts quiescing, made magic sequence
configurable. TTY patches got Alan Cox's ack.
* Looked into timer slack support for cgroups. While it's indeed
somewhat close to deferrable timers, it's still not exactly what we
need. Timer slack let us group wakeups, but there is still no way to
tell that the timer/poll/select itself should not cause wakeups. As
for deferrable timers, there are still no comments.
* Looked into ideas on early OOM detection from the userland. There are
a lot of inspirational thoughts on measuring memory stress levels,
and I definitely need to perform some tests. I'll prepare a detailed
answer to the ideas, but the most interesting part is that the ideas
are based on vmstat monitoring, which is important: if we're going to
use vmstat, we'll eventually get beaten by vmstat downsides:
slow/expensive updates (so the latency if the pre-OOM detection would
be equal to vmstat_update_time). And for Android low memory killer
use case, pre-OOM condition is important, but not the main problem:
the main "problem" is to monitor memory level when there is no stress
at all (but deferrable timers would solve this).
* Rebased and applied pstore/ftrace debugfs rework, this is now in
linux-next. Also reviewed/fixed FDT support for pstore, by Bryan
Freed @ Chromium.org.
Hi all,
This patch set implements a userland-side API for generic deferrable
timers, per linux/timer.h:
* A deferrable timer will work normally when the system is busy, but
* will not cause a CPU to come out of idle just to service it; instead,
* the timer will be serviced when the CPU eventually wakes up with a
* subsequent non-deferrable timer.
These timers are crucial for power saving, i.e. periodic tasks that want
to work in background when the system is under use, but don't want to
cause wakeups themselves.
The deferred timers are somewhat orthogonal to high-res external timers,
since the deferred timer is tied to the system load, not just to some
external decrementer source.
So, currently, the implementation has a HZ precision, and the maximum
interval is jiffies resolution (i.e. with HZ=1000, on 32 bit that would
be around max 49 days). Of course we can implement longer timeouts by
rearming the timer, although it probably wouldn't make much sense in
real world, so we keep it simple and just return E2BIG if we don't like
the interval.
Note that the code is still using time calculation that is done by the
hrtimer routines, so we pretty much reuse everything except for the
timer events themselves (i.e. we use calculation results of
hrtimer_forward_now() and hrtimer_expires_remaining(), but never start
the hrtimer). So the code path is pretty much the same for both hrtimers
and deferrable timers.
We will use the timers to periodically read /proc/vmstat without
forcibly waking up the system; but let's see, maybe there are other use
cases that might be interesting for PM folks.
Thanks!
Anton.
--
fs/timerfd.c | 87 +++++++++++++++++++++++++++++++++++++++++++------
include/linux/jiffies.h | 3 ++
include/linux/ktime.h | 3 +-
include/linux/timerfd.h | 4 ++-
kernel/time.c | 23 +++++++++++++
5 files changed, 108 insertions(+), 12 deletions(-)