aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:37:01 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:37:01 -0700
commit9732b6112343df2872518ec6701c8ef729310a05 (patch)
tree9e3dcc461845038da4730c2062eee546348ca445 /include
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86 (diff)
parentkgdb: always use icache flush for sw breakpoints (diff)
downloadlinux-dev-9732b6112343df2872518ec6701c8ef729310a05.tar.xz
linux-dev-9732b6112343df2872518ec6701c8ef729310a05.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-kgdb
* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-kgdb: kgdb: always use icache flush for sw breakpoints kgdb: fix SMP NMI kgdb_handle_exception exit race kgdb: documentation fixes kgdb: allow static kgdbts boot configuration kgdb: add documentation kgdb: Kconfig fix kgdb: add kgdb internal test suite kgdb: fix several kgdb regressions kgdb: kgdboc pl011 I/O module kgdb: fix optional arch functions and probe_kernel_* kgdb: add x86 HW breakpoints kgdb: print breakpoint removed on exception kgdb: clocksource watchdog kgdb: fix NMI hangs kgdb: fix kgdboc dynamic module configuration kgdb: document parameters x86: kgdb support consoles: polling support, kgdboc kgdb: core uaccess: add probe_kernel_write()
Diffstat (limited to 'include')
-rw-r--r--include/asm-x86/kdebug.h1
-rw-r--r--include/asm-x86/kgdb.h81
-rw-r--r--include/linux/clocksource.h1
-rw-r--r--include/linux/kgdb.h281
-rw-r--r--include/linux/serial_core.h4
-rw-r--r--include/linux/tty_driver.h12
-rw-r--r--include/linux/uaccess.h22
7 files changed, 402 insertions, 0 deletions
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
index 0c4175390dab..96651bb59ba1 100644
--- a/include/asm-x86/kdebug.h
+++ b/include/asm-x86/kdebug.h
@@ -20,6 +20,7 @@ enum die_val {
DIE_CALL,
DIE_NMI_IPI,
DIE_PAGE_FAULT,
+ DIE_NMIUNKNOWN,
};
extern void printk_address(unsigned long address, int reliable);
diff --git a/include/asm-x86/kgdb.h b/include/asm-x86/kgdb.h
new file mode 100644
index 000000000000..484c47554f3b
--- /dev/null
+++ b/include/asm-x86/kgdb.h
@@ -0,0 +1,81 @@
+#ifndef _ASM_KGDB_H_
+#define _ASM_KGDB_H_
+
+/*
+ * Copyright (C) 2001-2004 Amit S. Kale
+ * Copyright (C) 2008 Wind River Systems, Inc.
+ */
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound
+ * buffers at least NUMREGBYTES*2 are needed for register packets
+ * Longer buffer is needed to list all threads
+ */
+#define BUFMAX 1024
+
+/*
+ * Note that this register image is in a different order than
+ * the register image that Linux produces at interrupt time.
+ *
+ * Linux's register image is defined by struct pt_regs in ptrace.h.
+ * Just why GDB uses a different order is a historical mystery.
+ */
+#ifdef CONFIG_X86_32
+enum regnames {
+ GDB_AX, /* 0 */
+ GDB_CX, /* 1 */
+ GDB_DX, /* 2 */
+ GDB_BX, /* 3 */
+ GDB_SP, /* 4 */
+ GDB_BP, /* 5 */
+ GDB_SI, /* 6 */
+ GDB_DI, /* 7 */
+ GDB_PC, /* 8 also known as eip */
+ GDB_PS, /* 9 also known as eflags */
+ GDB_CS, /* 10 */
+ GDB_SS, /* 11 */
+ GDB_DS, /* 12 */
+ GDB_ES, /* 13 */
+ GDB_FS, /* 14 */
+ GDB_GS, /* 15 */
+};
+#else /* ! CONFIG_X86_32 */
+enum regnames {
+ GDB_AX, /* 0 */
+ GDB_DX, /* 1 */
+ GDB_CX, /* 2 */
+ GDB_BX, /* 3 */
+ GDB_SI, /* 4 */
+ GDB_DI, /* 5 */
+ GDB_BP, /* 6 */
+ GDB_SP, /* 7 */
+ GDB_R8, /* 8 */
+ GDB_R9, /* 9 */
+ GDB_R10, /* 10 */
+ GDB_R11, /* 11 */
+ GDB_R12, /* 12 */
+ GDB_R13, /* 13 */
+ GDB_R14, /* 14 */
+ GDB_R15, /* 15 */
+ GDB_PC, /* 16 */
+ GDB_PS, /* 17 */
+};
+#endif /* CONFIG_X86_32 */
+
+/*
+ * Number of bytes of registers:
+ */
+#ifdef CONFIG_X86_32
+# define NUMREGBYTES 64
+#else
+# define NUMREGBYTES ((GDB_PS+1)*8)
+#endif
+
+static inline void arch_kgdb_breakpoint(void)
+{
+ asm(" int $3");
+}
+#define BREAK_INSTR_SIZE 1
+#define CACHE_FLUSH_IS_SAFE 1
+
+#endif /* _ASM_KGDB_H_ */
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 85778a4b1209..35094479ca55 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -216,6 +216,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c,
/* used to install a new clocksource */
extern int clocksource_register(struct clocksource*);
extern void clocksource_unregister(struct clocksource*);
+extern void clocksource_touch_watchdog(void);
extern struct clocksource* clocksource_get_next(void);
extern void clocksource_change_rating(struct clocksource *cs, int rating);
extern void clocksource_resume(void);
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
new file mode 100644
index 000000000000..9757b1a6d9dc
--- /dev/null
+++ b/include/linux/kgdb.h
@@ -0,0 +1,281 @@
+/*
+ * This provides the callbacks and functions that KGDB needs to share between
+ * the core, I/O and arch-specific portions.
+ *
+ * Author: Amit Kale <amitkale@linsyssoft.com> and
+ * Tom Rini <trini@kernel.crashing.org>
+ *
+ * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc.
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _KGDB_H_
+#define _KGDB_H_
+
+#include <linux/serial_8250.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/atomic.h>
+#include <asm/kgdb.h>
+
+struct pt_regs;
+
+/**
+ * kgdb_skipexception - (optional) exit kgdb_handle_exception early
+ * @exception: Exception vector number
+ * @regs: Current &struct pt_regs.
+ *
+ * On some architectures it is required to skip a breakpoint
+ * exception when it occurs after a breakpoint has been removed.
+ * This can be implemented in the architecture specific portion of
+ * for kgdb.
+ */
+extern int kgdb_skipexception(int exception, struct pt_regs *regs);
+
+/**
+ * kgdb_post_primary_code - (optional) Save error vector/code numbers.
+ * @regs: Original pt_regs.
+ * @e_vector: Original error vector.
+ * @err_code: Original error code.
+ *
+ * This is usually needed on architectures which support SMP and
+ * KGDB. This function is called after all the secondary cpus have
+ * been put to a know spin state and the primary CPU has control over
+ * KGDB.
+ */
+extern void kgdb_post_primary_code(struct pt_regs *regs, int e_vector,
+ int err_code);
+
+/**
+ * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook
+ * @regs: Current &struct pt_regs.
+ *
+ * This function will be called if the particular architecture must
+ * disable hardware debugging while it is processing gdb packets or
+ * handling exception.
+ */
+extern void kgdb_disable_hw_debug(struct pt_regs *regs);
+
+struct tasklet_struct;
+struct task_struct;
+struct uart_port;
+
+/**
+ * kgdb_breakpoint - compiled in breakpoint
+ *
+ * This will be impelmented a static inline per architecture. This
+ * function is called by the kgdb core to execute an architecture
+ * specific trap to cause kgdb to enter the exception processing.
+ *
+ */
+void kgdb_breakpoint(void);
+
+extern int kgdb_connected;
+
+extern atomic_t kgdb_setting_breakpoint;
+extern atomic_t kgdb_cpu_doing_single_step;
+
+extern struct task_struct *kgdb_usethread;
+extern struct task_struct *kgdb_contthread;
+
+enum kgdb_bptype {
+ BP_BREAKPOINT = 0,
+ BP_HARDWARE_BREAKPOINT,
+ BP_WRITE_WATCHPOINT,
+ BP_READ_WATCHPOINT,
+ BP_ACCESS_WATCHPOINT
+};
+
+enum kgdb_bpstate {
+ BP_UNDEFINED = 0,
+ BP_REMOVED,
+ BP_SET,
+ BP_ACTIVE
+};
+
+struct kgdb_bkpt {
+ unsigned long bpt_addr;
+ unsigned char saved_instr[BREAK_INSTR_SIZE];
+ enum kgdb_bptype type;
+ enum kgdb_bpstate state;
+};
+
+#ifndef KGDB_MAX_BREAKPOINTS
+# define KGDB_MAX_BREAKPOINTS 1000
+#endif
+
+#define KGDB_HW_BREAKPOINT 1
+
+/*
+ * Functions each KGDB-supporting architecture must provide:
+ */
+
+/**
+ * kgdb_arch_init - Perform any architecture specific initalization.
+ *
+ * This function will handle the initalization of any architecture
+ * specific callbacks.
+ */
+extern int kgdb_arch_init(void);
+
+/**
+ * kgdb_arch_exit - Perform any architecture specific uninitalization.
+ *
+ * This function will handle the uninitalization of any architecture
+ * specific callbacks, for dynamic registration and unregistration.
+ */
+extern void kgdb_arch_exit(void);
+
+/**
+ * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs
+ * @gdb_regs: A pointer to hold the registers in the order GDB wants.
+ * @regs: The &struct pt_regs of the current process.
+ *
+ * Convert the pt_regs in @regs into the format for registers that
+ * GDB expects, stored in @gdb_regs.
+ */
+extern void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs);
+
+/**
+ * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs
+ * @gdb_regs: A pointer to hold the registers in the order GDB wants.
+ * @p: The &struct task_struct of the desired process.
+ *
+ * Convert the register values of the sleeping process in @p to
+ * the format that GDB expects.
+ * This function is called when kgdb does not have access to the
+ * &struct pt_regs and therefore it should fill the gdb registers
+ * @gdb_regs with what has been saved in &struct thread_struct
+ * thread field during switch_to.
+ */
+extern void
+sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p);
+
+/**
+ * gdb_regs_to_pt_regs - Convert GDB regs to ptrace regs.
+ * @gdb_regs: A pointer to hold the registers we've received from GDB.
+ * @regs: A pointer to a &struct pt_regs to hold these values in.
+ *
+ * Convert the GDB regs in @gdb_regs into the pt_regs, and store them
+ * in @regs.
+ */
+extern void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs);
+
+/**
+ * kgdb_arch_handle_exception - Handle architecture specific GDB packets.
+ * @vector: The error vector of the exception that happened.
+ * @signo: The signal number of the exception that happened.
+ * @err_code: The error code of the exception that happened.
+ * @remcom_in_buffer: The buffer of the packet we have read.
+ * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into.
+ * @regs: The &struct pt_regs of the current process.
+ *
+ * This function MUST handle the 'c' and 's' command packets,
+ * as well packets to set / remove a hardware breakpoint, if used.
+ * If there are additional packets which the hardware needs to handle,
+ * they are handled here. The code should return -1 if it wants to
+ * process more packets, and a %0 or %1 if it wants to exit from the
+ * kgdb callback.
+ */
+extern int
+kgdb_arch_handle_exception(int vector, int signo, int err_code,
+ char *remcom_in_buffer,
+ char *remcom_out_buffer,
+ struct pt_regs *regs);
+
+/**
+ * kgdb_roundup_cpus - Get other CPUs into a holding pattern
+ * @flags: Current IRQ state
+ *
+ * On SMP systems, we need to get the attention of the other CPUs
+ * and get them be in a known state. This should do what is needed
+ * to get the other CPUs to call kgdb_wait(). Note that on some arches,
+ * the NMI approach is not used for rounding up all the CPUs. For example,
+ * in case of MIPS, smp_call_function() is used to roundup CPUs. In
+ * this case, we have to make sure that interrupts are enabled before
+ * calling smp_call_function(). The argument to this function is
+ * the flags that will be used when restoring the interrupts. There is
+ * local_irq_save() call before kgdb_roundup_cpus().
+ *
+ * On non-SMP systems, this is not called.
+ */
+extern void kgdb_roundup_cpus(unsigned long flags);
+
+/* Optional functions. */
+extern int kgdb_validate_break_address(unsigned long addr);
+extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr);
+extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle);
+
+/**
+ * struct kgdb_arch - Describe architecture specific values.
+ * @gdb_bpt_instr: The instruction to trigger a breakpoint.
+ * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT.
+ * @set_breakpoint: Allow an architecture to specify how to set a software
+ * breakpoint.
+ * @remove_breakpoint: Allow an architecture to specify how to remove a
+ * software breakpoint.
+ * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware
+ * breakpoint.
+ * @remove_hw_breakpoint: Allow an architecture to specify how to remove a
+ * hardware breakpoint.
+ * @remove_all_hw_break: Allow an architecture to specify how to remove all
+ * hardware breakpoints.
+ * @correct_hw_break: Allow an architecture to specify how to correct the
+ * hardware debug registers.
+ */
+struct kgdb_arch {
+ unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE];
+ unsigned long flags;
+
+ int (*set_breakpoint)(unsigned long, char *);
+ int (*remove_breakpoint)(unsigned long, char *);
+ int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
+ int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
+ void (*remove_all_hw_break)(void);
+ void (*correct_hw_break)(void);
+};
+
+/**
+ * struct kgdb_io - Describe the interface for an I/O driver to talk with KGDB.
+ * @name: Name of the I/O driver.
+ * @read_char: Pointer to a function that will return one char.
+ * @write_char: Pointer to a function that will write one char.
+ * @flush: Pointer to a function that will flush any pending writes.
+ * @init: Pointer to a function that will initialize the device.
+ * @pre_exception: Pointer to a function that will do any prep work for
+ * the I/O driver.
+ * @post_exception: Pointer to a function that will do any cleanup work
+ * for the I/O driver.
+ */
+struct kgdb_io {
+ const char *name;
+ int (*read_char) (void);
+ void (*write_char) (u8);
+ void (*flush) (void);
+ int (*init) (void);
+ void (*pre_exception) (void);
+ void (*post_exception) (void);
+};
+
+extern struct kgdb_arch arch_kgdb_ops;
+
+extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
+extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
+
+extern int kgdb_hex2long(char **ptr, long *long_val);
+extern int kgdb_mem2hex(char *mem, char *buf, int count);
+extern int kgdb_hex2mem(char *buf, char *mem, int count);
+
+extern int kgdb_isremovedbreak(unsigned long addr);
+
+extern int
+kgdb_handle_exception(int ex_vector, int signo, int err_code,
+ struct pt_regs *regs);
+extern int kgdb_nmicallback(int cpu, void *regs);
+
+extern int kgdb_single_step;
+extern atomic_t kgdb_active;
+
+#endif /* _KGDB_H_ */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 289942fc6655..7cb094a82456 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -213,6 +213,10 @@ struct uart_ops {
void (*config_port)(struct uart_port *, int);
int (*verify_port)(struct uart_port *, struct serial_struct *);
int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
+#ifdef CONFIG_CONSOLE_POLL
+ void (*poll_put_char)(struct uart_port *, unsigned char);
+ int (*poll_get_char)(struct uart_port *);
+#endif
};
#define UART_CONFIG_TYPE (1 << 0)
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 85c95cd39bc3..21f69aca4505 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -125,6 +125,7 @@
#include <linux/cdev.h>
struct tty_struct;
+struct tty_driver;
struct tty_operations {
int (*open)(struct tty_struct * tty, struct file * filp);
@@ -157,6 +158,11 @@ struct tty_operations {
int (*tiocmget)(struct tty_struct *tty, struct file *file);
int (*tiocmset)(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
+#ifdef CONFIG_CONSOLE_POLL
+ int (*poll_init)(struct tty_driver *driver, int line, char *options);
+ int (*poll_get_char)(struct tty_driver *driver, int line);
+ void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
+#endif
};
struct tty_driver {
@@ -220,6 +226,11 @@ struct tty_driver {
int (*tiocmget)(struct tty_struct *tty, struct file *file);
int (*tiocmset)(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
+#ifdef CONFIG_CONSOLE_POLL
+ int (*poll_init)(struct tty_driver *driver, int line, char *options);
+ int (*poll_get_char)(struct tty_driver *driver, int line);
+ void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
+#endif
struct list_head tty_drivers;
};
@@ -230,6 +241,7 @@ struct tty_driver *alloc_tty_driver(int lines);
void put_tty_driver(struct tty_driver *driver);
void tty_set_operations(struct tty_driver *driver,
const struct tty_operations *op);
+extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
/* tty driver magic number */
#define TTY_DRIVER_MAGIC 0x5402
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 975c963e5789..fec6decfb983 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -84,4 +84,26 @@ static inline unsigned long __copy_from_user_nocache(void *to,
ret; \
})
+/*
+ * probe_kernel_read(): safely attempt to read from a location
+ * @dst: pointer to the buffer that shall take the data
+ * @src: address to read from
+ * @size: size of the data chunk
+ *
+ * Safely read from address @src to the buffer at @dst. If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+extern long probe_kernel_read(void *dst, void *src, size_t size);
+
+/*
+ * probe_kernel_write(): safely attempt to write to a location
+ * @dst: address to write to
+ * @src: pointer to the data that shall be written
+ * @size: size of the data chunk
+ *
+ * Safely write to address @dst from the buffer at @src. If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+extern long probe_kernel_write(void *dst, void *src, size_t size);
+
#endif /* __LINUX_UACCESS_H__ */