Patch set 2 of 3 - The kdb / kgdb merge
This patch set stacks on top of the kgdb / kdb patches and focuses on
further extending kdb to accommodate atomic kernel mode setting (kms).
At the moment only the Intel i915 class video devices are supported,
but the API is generic and would allow for other kms based drivers to
enable atomic mode setting.
The final patch in the series would be omitted from any pull request
as it is still a work in progress, showing the remaining points that do
not have a safe mechanism to work atomically to change the display
context in order to view the kernel debugger shell. At least it
provides a nice proof of concept.
You can find the development branch for this here:
http://git.kernel.org/?p=linux/kernel/git/jwessel/linux-2.6-kgdb.git;a=shortlog;h=kms-merge
Thanks,
Jason.
---
Jason Wessel (6):
kgdboc,debug_core: Add call backs to allow kernel mode switching
kms,kdb: Force unblank a console device
i915: when kgdb is active display compression should be off
drm_fb_helper: Preserve capability to use atomic kms
kgdb,docs: Update the kgdb docs to include kms
RFC,HACK,EXPERIMENTAL,drm,i915 - atomic mutex HACKS
Jesse Barnes (1):
drm: add KGDB/KDB support Add support for KDB entry/exit.
Documentation/DocBook/kgdb.tmpl | 82 ++++++++++++++++++++++---
Documentation/kernel-parameters.txt | 9 ++-
drivers/gpu/drm/drm_fb_helper.c | 93 +++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_display.c | 114 ++++++++++++++++++++++++++++++++--
drivers/serial/kgdboc.c | 27 ++++++++
drivers/video/console/fbcon.c | 7 ++
include/drm/drm_crtc_helper.h | 2 +
include/drm/drm_fb_helper.h | 4 +
include/linux/kgdb.h | 38 +++++++++++
kernel/debug/Makefile | 1 +
kernel/debug/debug_core.c | 23 +++++++
kernel/debug/kms_hooks.c | 62 ++++++++++++++++++
12 files changed, 438 insertions(+), 24 deletions(-)
create mode 100644 kernel/debug/kms_hooks.c
From: Jesse Barnes <[email protected]>
---
drivers/gpu/drm/drm_fb_helper.c | 79 ++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 93 ++++++++++++++++++++++++++++++++++
include/drm/drm_crtc_helper.h | 2 +
include/drm/drm_fb_helper.h | 4 ++
4 files changed, 178 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0f9e905..ea06bf3 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -29,6 +29,7 @@
*/
#include <linux/sysrq.h>
#include <linux/fb.h>
+#include <linux/kgdb.h>
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_fb_helper.h"
@@ -233,6 +234,80 @@ int drm_fb_helper_parse_command_line(struct drm_device *dev)
return 0;
}
+#define to_fb_helper(ops) (container_of((ops), struct drm_fb_helper, kdb_ops))
+
+static int drm_fb_kdb_enter(struct dbg_kms_ops *ops)
+{
+ struct drm_fb_helper *helper = to_fb_helper(ops);
+ struct drm_crtc_helper_funcs *funcs;
+ int i;
+
+ if (list_empty(&kernel_fb_helper_list))
+ return false;
+
+ list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
+ for (i = 0; i < helper->crtc_count; i++) {
+ struct drm_mode_set *mode_set =
+ &helper->crtc_info[i].mode_set;
+
+ if (!mode_set->crtc->enabled)
+ continue;
+
+ funcs = mode_set->crtc->helper_private;
+ funcs->mode_set_base_atomic(mode_set->crtc,
+ mode_set->fb,
+ mode_set->x,
+ mode_set->y);
+
+ }
+ }
+
+ return 0;
+}
+
+/* Find the real fb for a given fb helper CRTC */
+static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *c;
+
+ list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
+ if (crtc->base.id == c->base.id)
+ return c->fb;
+ }
+
+ return NULL;
+}
+
+static int drm_fb_kdb_exit(struct dbg_kms_ops *ops)
+{
+ struct drm_fb_helper *helper = to_fb_helper(ops);
+ struct drm_crtc *crtc;
+ struct drm_crtc_helper_funcs *funcs;
+ struct drm_framebuffer *fb;
+ int i;
+
+ for (i = 0; i < helper->crtc_count; i++) {
+ struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
+ crtc = mode_set->crtc;
+ funcs = crtc->helper_private;
+ fb = drm_mode_config_fb(crtc);
+
+ if (!crtc->enabled)
+ continue;
+
+ if (!fb) {
+ DRM_ERROR("no fb to restore??\n");
+ continue;
+ }
+
+ funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
+ crtc->y);
+ }
+
+ return 0;
+}
+
bool drm_fb_helper_force_kernel_mode(void)
{
int i = 0;
@@ -923,6 +998,9 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
/* Switch back to kernel console on panic */
/* multi card linked list maybe */
if (list_empty(&kernel_fb_helper_list)) {
+ fb_helper->kdb_ops.activate_console = drm_fb_kdb_enter;
+ fb_helper->kdb_ops.restore_console = drm_fb_kdb_exit;
+ dbg_kms_ops_register(&fb_helper->kdb_ops);
printk(KERN_INFO "registered panic notifier\n");
atomic_notifier_chain_register(&panic_notifier_list,
&paniced);
@@ -937,6 +1015,7 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
{
list_del(&helper->kernel_fb_list);
if (list_empty(&kernel_fb_helper_list)) {
+ dbg_kms_ops_unregister(&helper->kdb_ops);
printk(KERN_INFO "unregistered panic notifier\n");
atomic_notifier_chain_unregister(&panic_notifier_list,
&paniced);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b27202d..088b8bd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1278,6 +1278,98 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
return 0;
}
+/* Assume fb object is pinned & idle & fenced and just update base pointers */
+static int
+intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ int x, int y)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj_priv;
+ struct drm_gem_object *obj;
+ int plane = intel_crtc->plane;
+ unsigned long Start, Offset;
+ int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
+ int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
+ int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
+ int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
+ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+ u32 dspcntr;
+
+ switch (plane) {
+ case 0:
+ case 1:
+ break;
+ default:
+ DRM_ERROR("Can't update plane %d in SAREA\n", plane);
+ return -EINVAL;
+ }
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+ obj_priv = obj->driver_private;
+
+ dspcntr = I915_READ(dspcntr_reg);
+ /* Mask out pixel format bits in case we change it */
+ dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+ switch (fb->bits_per_pixel) {
+ case 8:
+ dspcntr |= DISPPLANE_8BPP;
+ break;
+ case 16:
+ if (fb->depth == 15)
+ dspcntr |= DISPPLANE_15_16BPP;
+ else
+ dspcntr |= DISPPLANE_16BPP;
+ break;
+ case 24:
+ case 32:
+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+ break;
+ default:
+ DRM_ERROR("Unknown color depth\n");
+ return -EINVAL;
+ }
+ if (IS_I965G(dev)) {
+ if (obj_priv->tiling_mode != I915_TILING_NONE)
+ dspcntr |= DISPPLANE_TILED;
+ else
+ dspcntr &= ~DISPPLANE_TILED;
+ }
+
+ if (IS_IRONLAKE(dev))
+ /* must disable */
+ dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
+ I915_WRITE(dspcntr_reg, dspcntr);
+
+ Start = obj_priv->gtt_offset;
+ Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+ I915_WRITE(dspstride, fb->pitch);
+ if (IS_I965G(dev)) {
+ I915_WRITE(dspbase, Offset);
+ I915_READ(dspbase);
+ I915_WRITE(dspsurf, Start);
+ I915_READ(dspsurf);
+ I915_WRITE(dsptileoff, (y << 16) | x);
+ } else {
+ I915_WRITE(dspbase, Start + Offset);
+ I915_READ(dspbase);
+ }
+
+ if ((IS_I965G(dev) || plane == 0))
+ intel_update_fbc(crtc, &crtc->mode);
+
+ intel_wait_for_vblank(dev);
+ intel_increase_pllclock(crtc, true);
+
+ return 0;
+}
+
static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
@@ -4257,6 +4349,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_fixup = intel_crtc_mode_fixup,
.mode_set = intel_crtc_mode_set,
.mode_set_base = intel_pipe_set_base,
+ .mode_set_base_atomic = intel_pipe_set_base_atomic,
.prepare = intel_crtc_prepare,
.commit = intel_crtc_commit,
.load_lut = intel_crtc_load_lut,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index b29e201..4c12319 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -61,6 +61,8 @@ struct drm_crtc_helper_funcs {
/* Move the crtc on the current fb to the given position *optional* */
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);
+ int (*mode_set_base_atomic)(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int x, int y);
/* reload the current crtc LUT */
void (*load_lut)(struct drm_crtc *crtc);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 58c892a..1f2ab94 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -30,6 +30,8 @@
#ifndef DRM_FB_HELPER_H
#define DRM_FB_HELPER_H
+#include <linux/kgdb.h>
+
struct drm_fb_helper_crtc {
uint32_t crtc_id;
struct drm_mode_set mode_set;
@@ -63,8 +65,10 @@ struct drm_fb_helper_connector {
struct drm_fb_helper {
struct drm_framebuffer *fb;
+ struct drm_framebuffer *saved_fb;
struct drm_device *dev;
struct drm_display_mode *mode;
+ struct dbg_kms_ops kdb_ops;
int crtc_count;
struct drm_fb_helper_crtc *crtc_info;
struct drm_fb_helper_funcs *funcs;
--
1.6.4.rc1
Update the kgdb docs to include information about kernel mode setting support.
Signed-off-by: Jason Wessel <[email protected]>
---
Documentation/DocBook/kgdb.tmpl | 82 +++++++++++++++++++++++++++++++----
Documentation/kernel-parameters.txt | 9 +++-
2 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
index cc81879..498267b 100644
--- a/Documentation/DocBook/kgdb.tmpl
+++ b/Documentation/DocBook/kgdb.tmpl
@@ -200,12 +200,29 @@
only make use of <constant>kgdbwait</constant> and early debugging
if you build kgdboc into the kernel as a builtins.
</para>
+ <para>Optionally you can elect to activate kms (Kernel Mode
+ Setting) integration. When you use kms with kgdboc and you have a
+ video driver that has atomic mode setting hooks, it is possible to
+ enter the debugger on the graphics console. When the kernel
+ execution is resumed, the graphics previous graphics mode will get
+ restored. This integration can serve as a useful tool to aid in
+ dianosing crashes or doing analysis of memory with kdb while
+ allowing the full graphics console applications to run.
+ </para>
<sect2 id="kgdbocArgs">
<title>kgdboc arguments</title>
- <para>Usage: <constant>kgdboc=[kbd][[,]serial_device][,baud]</constant></para>
- <para>You can configure kgdboc to use the keyboard, and or a serial device
- depending on if you are using kdb and or kgdb, in one of the
- following scenarios.
+ <para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
+ <para>Abreviations:
+ <itemizedlist>
+ <listitem><para>kms = Kernel Mode Setting</para></listitem>
+ <listitem><para>kbd = Keyboard</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>You can configure kgdboc to use the keyboard, and or a serial
+ device depending on if you are using kdb and or kgdb, in one of the
+ following scenarios. The order listed above must be observed if
+ you use any of the optional configurations together. Using kms +
+ only gdb is generally not a usful combination.
<orderedlist>
<listitem><para>kdb and kgdb over only a serial port</para>
<para><constant>kgdboc=<serial_device>[,baud]</constant></para>
@@ -218,6 +235,12 @@
<listitem><para>kdb with a keyboard</para>
<para><constant>kgdboc=kbd</constant></para>
</listitem>
+ <listitem><para>kdb with kernel modesetting</para>
+ <para><constant>kgdboc=kms,kbd</constant></para>
+ </listitem>
+ <listitem><para>kdb with kernel modesetting and kgdb over a serial port</para>
+ <para><constant>kgdboc=kbd,kbd,ttyS0,115200</constant></para>
+ </listitem>
</orderedlist>
</para>
<para>You can configure kgdboc via sysfs or a module or kernel boot line
@@ -613,6 +636,8 @@ Task Addr Pid Parent [*] cpu State Thread Command
<listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
<listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
<listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
+ <listitem><para>The structures and call back API for atomic kernel mode setting.</para>
+ <para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
</itemizedlist>
</para>
</listitem>
@@ -721,6 +746,8 @@ Task Addr Pid Parent [*] cpu State Thread Command
</sect1>
<sect1 id="kgdbocDesign">
<title>kgdboc internals</title>
+ <sect2>
+ <title>kgdboc and uarts</title>
<para>
The kgdboc driver is actually a very thin driver that relies on the
underlying low level to the hardware driver having "polling hooks"
@@ -729,10 +756,7 @@ Task Addr Pid Parent [*] cpu State Thread Command
low level uart hook for doing polled mode reading and writing of a
single character while in an atomic context. When kgdb makes an I/O
request to the debugger, kgdboc invokes a call back in the serial
- core which in turn uses the call back in the uart driver. It is
- certainly possible to extend kgdboc to work with non-uart based
- consoles in the future.
- </para>
+ core which in turn uses the call back in the uart driver.</para>
<para>
When using kgdboc with a uart, the uart driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
#ifdef CONFIG_CONSOLE_POLL
@@ -746,9 +770,49 @@ Task Addr Pid Parent [*] cpu State Thread Command
that they can be called from an atomic context and have to restore
the state of the uart chip on return such that the system can return
to normal when the debugger detaches. You need to be very careful
- with any kind of lock you consider, because failing here is most
+ with any kind of lock you consider, because failing here is most likely
going to mean pressing the reset button.
</para>
+ </sect2>
+ <sect2 id="kgdbocKbd">
+ <title>kgdboc and keyboards</title>
+ <para>The kgdboc driver contains logic to configure communications
+ with an attached keyboard. The keyboard infrastructure is only
+ compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
+ kernel configuration.</para>
+ <para>The core polled keyboard driver driver for PS/2 type keyboards
+ is in drivers/char/kdb_keyboard.c. This driver is hooked into the
+ debug core when kgdboc populates the callback in the arrary
+ called <constant>kdb_poll_funcs[]</constant>. The
+ kdb_get_kbd_char() is the top level function which polls hardware
+ for single character input.
+ </para>
+ </sect2>
+ <sect2 id="kgdbocKms">
+ <title>kgdboc and kms</title>
+ <para>The kgdboc driver contains logic to request the grpahics
+ display to switch to a text context if you are using
+ kgdboc=kms,... and you have a video driver which has a framebuffer
+ console and atomic kernel mode setting support. Every time kernel
+ debugger is entered it calls kgdboc_pre_exp_handler() which in turn
+ calls dbg_kms_ops->activate_console(). On resuming kernel
+ execution, the kernel debugger calls kgdboc_post_exp_handler() which
+ in turn calls dbg_kms_ops->restore_console().</para>
+ <para>Any video driver that wants to be compatible with the kernel
+ debugger and the atomic kms callbacks must implement the
+ mode_set_base_atomic operation. The following is an example from
+ drivers/gpu/drm/i915/intel_display.c:
+ <informalexample>
+ <programlisting>
+static const struct drm_crtc_helper_funcs intel_helper_funcs = {
+[...]
+ .mode_set_base_atomic = intel_pipe_set_base_atomic,
+[...]
+};
+ </programlisting>
+ </informalexample>
+ </para>
+ </sect2>
</sect1>
</chapter>
<chapter id="credits">
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index af8b8e8..b340445 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1106,9 +1106,12 @@ and is between 256 and 4096 characters. It is defined in the file
kgdboc= [KGDB,HW] kgdb over consoles.
Requires a tty driver that supports console polling,
or a supported polling keyboard driver (non-usb).
- Serial only format: <serial_device>[,baud]
- keyboard only format: kbd
- keyboard and serial format: kbd,<serial_device>[,baud]
+ Serial only format: <serial_device>[,baud]
+ keyboard only format: kbd
+ keyboard and serial format: kbd,<serial_device>[,baud]
+ Optional Kernal mode setting:
+ kms, kbd format: kms,kbd
+ kms, kbd and serial format: kms,kbd,<ser_dev>[,baud]
kgdbwait [KGDB] Stop kernel execution and enter the
kernel debugger at the earliest opportunity if
--
1.6.4.rc1
If the HW compression is left on, the call backs from the HW will
crash the kernel. The only time this code is called is when kernel
mode setting is in use with kgdb and the kdb shell.
The atomic display pipe handler callback will reset everything when
kgdb restores kernel to the run state.
CC: David Airlie <[email protected]>
Acked-by: Jesse Barnes <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 088b8bd..21e9597 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1210,6 +1210,10 @@ static void intel_update_fbc(struct drm_crtc *crtc,
goto out_disable;
}
+ /* If the kernel debugger is active, always disable compression */
+ if (in_dbg_master())
+ goto out_disable;
+
if (dev_priv->display.fbc_enabled(crtc)) {
/* We can re-enable it in this case, but need to update pitch */
if (fb->pitch > dev_priv->cfb_pitch)
--
1.6.4.rc1
Commit 5349ef3127c77075ff70b2014f17ae0fbcaaf199 changed logic of when
a pixclock was valid vs invalid.
The atomic kernel mode setting used by the kernel debugger relied upon
the drm_fb_helper_check_var() to always return -EINVAL. Until a
better solution exists, this behavior will be restored.
CC: David Airlie <[email protected]>
CC: Jesse Barnes <[email protected]>
CC: Clemens Ladisch <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/gpu/drm/drm_fb_helper.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index ea06bf3..35ede53 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -677,7 +677,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
struct drm_framebuffer *fb = fb_helper->fb;
int depth;
- if (var->pixclock != 0)
+ if (var->pixclock != 0 || in_dbg_master())
return -EINVAL;
/* Need to resize the fb object !!! */
--
1.6.4.rc1
Here are some hacks to work around mutex crashes in the drm / i915
code.
For now, this is the only way to make the kms / kgdb path safe on an
SMP system.
Helper macros were added to allow kms code to declare debugger safe
mutexes which can be used so long as the debugger restores the state
before resuming.
NOTE: This patch is not scheduled to goto the mainline, but to point
out the remaing problems that exist and demonstrate KMS / KDB working
together.
CC: Jesse Barnes <[email protected]>
CC: David Airlie <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/gpu/drm/drm_fb_helper.c | 12 ++++++------
drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++++-----
include/linux/kgdb.h | 8 ++++++++
3 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 35ede53..713e101 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -396,9 +396,9 @@ static void drm_fb_helper_on(struct fb_info *info)
!crtc->enabled)
continue;
- mutex_lock(&dev->mode_config.mutex);
+ dbg_safe_mutex_lock(&dev->mode_config.mutex);
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
- mutex_unlock(&dev->mode_config.mutex);
+ dbg_safe_mutex_unlock(&dev->mode_config.mutex);
/* Found a CRTC on this fb, now find encoders */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -406,9 +406,9 @@ static void drm_fb_helper_on(struct fb_info *info)
struct drm_encoder_helper_funcs *encoder_funcs;
encoder_funcs = encoder->helper_private;
- mutex_lock(&dev->mode_config.mutex);
+ dbg_safe_mutex_lock(&dev->mode_config.mutex);
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
- mutex_unlock(&dev->mode_config.mutex);
+ dbg_safe_mutex_unlock(&dev->mode_config.mutex);
}
}
}
@@ -819,9 +819,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
modeset->y = var->yoffset;
if (modeset->num_connectors) {
- mutex_lock(&dev->mode_config.mutex);
+ dbg_safe_mutex_lock(&dev->mode_config.mutex);
ret = crtc->funcs->set_config(modeset);
- mutex_unlock(&dev->mode_config.mutex);
+ dbg_safe_mutex_unlock(&dev->mode_config.mutex);
if (!ret) {
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 21e9597..700d4b1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -991,6 +991,13 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
void
intel_wait_for_vblank(struct drm_device *dev)
{
+ if (in_dbg_master()) {
+ /* When in the kernel debugger we cannot sleep */
+ preempt_disable();
+ mdelay(20);
+ preempt_enable();
+ return;
+ }
/* Wait for 20ms, i.e. one cycle at 50hz. */
msleep(20);
}
@@ -1415,17 +1422,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
obj = intel_fb->obj;
obj_priv = obj->driver_private;
- mutex_lock(&dev->struct_mutex);
+ dbg_safe_mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev, obj);
if (ret != 0) {
- mutex_unlock(&dev->struct_mutex);
+ dbg_safe_mutex_unlock(&dev->struct_mutex);
return ret;
}
ret = i915_gem_object_set_to_display_plane(obj);
if (ret != 0) {
i915_gem_object_unpin(obj);
- mutex_unlock(&dev->struct_mutex);
+ dbg_safe_mutex_unlock(&dev->struct_mutex);
return ret;
}
@@ -1452,7 +1459,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
default:
DRM_ERROR("Unknown color depth\n");
i915_gem_object_unpin(obj);
- mutex_unlock(&dev->struct_mutex);
+ dbg_safe_mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
if (IS_I965G(dev)) {
@@ -1496,7 +1503,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
}
intel_increase_pllclock(crtc, true);
- mutex_unlock(&dev->struct_mutex);
+ dbg_safe_mutex_unlock(&dev->struct_mutex);
if (!dev->primary->master)
return 0;
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 81bb298..2d9b738 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -306,6 +306,12 @@ struct dbg_kms_ops {
extern struct dbg_kms_ops *dbg_kms_ops;
extern int dbg_kms_ops_register(struct dbg_kms_ops *ops);
extern int dbg_kms_ops_unregister(struct dbg_kms_ops *ops);
+#define dbg_safe_mutex_lock(x) \
+ if (!in_dbg_master()) \
+ mutex_lock(x)
+#define dbg_safe_mutex_unlock(x) \
+ if (!in_dbg_master()) \
+ mutex_unlock(x)
#else /* ! CONFIG_KGDB */
#define in_dbg_master() (0)
@@ -317,5 +323,7 @@ static inline int dbg_kms_ops_unregister(struct dbg_kms_ops *ops)
{
return 0;
}
+#define dbg_safe_mutex_lock(x) mutex_lock(x)
+#define dbg_safe_mutex_unlock(x) mutex_unlock(x)
#endif /* ! CONFIG_KGDB */
#endif /* _KGDB_H_ */
--
1.6.4.rc1
Hooks for the kgdb core for registration of the drm layer to provide a
call backs so as to perform kernel mode switching, for use with kdb.
[[email protected]: add ops arg to kgdb console active & restore hooks]
CC: Jesse Barnes <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/serial/kgdboc.c | 16 ++++++++++++++++
include/linux/kgdb.h | 22 ++++++++++++++++++++++
kernel/debug/debug_core.c | 23 +++++++++++++++++++++++
3 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 201cdf5..bc1fec1 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -32,6 +32,7 @@ static struct kparam_string kps = {
.maxlen = MAX_CONFIG_LEN,
};
+static int kgdboc_use_kms; /* 1 if we use kernel mode switching */
static struct tty_driver *kgdb_tty_driver;
static int kgdb_tty_line;
@@ -116,6 +117,12 @@ static int configure_kgdboc(void)
kgdboc_io_ops.is_console = 0;
kgdb_tty_driver = NULL;
+ kgdboc_use_kms = 0;
+ if (strncmp(cptr, "kms,", 4) == 0) {
+ cptr += 4;
+ kgdboc_use_kms = 1;
+ }
+
if (kgdboc_register_kbd(&cptr))
goto do_register;
@@ -215,6 +222,11 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
static void kgdboc_pre_exp_handler(void)
{
+ if (kgdboc_use_kms && dbg_kms_ops &&
+ dbg_kms_ops->activate_console)
+ if (dbg_kms_ops->activate_console(dbg_kms_ops))
+ printk(KERN_ERR "kgdboc: kernel mode switch error\n");
+
/* Increment the module count when the debugger is active */
if (!kgdb_connected)
try_module_get(THIS_MODULE);
@@ -225,6 +237,10 @@ static void kgdboc_post_exp_handler(void)
/* decrement the module count when the debugger detaches */
if (!kgdb_connected)
module_put(THIS_MODULE);
+ if (kgdboc_use_kms && dbg_kms_ops &&
+ dbg_kms_ops->restore_console)
+ if (dbg_kms_ops->restore_console(dbg_kms_ops))
+ printk(KERN_ERR "kgdboc: graphics restore failed\n");
kgdboc_clear_kbd();
}
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 6c784ab..9cd6baa 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -283,9 +283,31 @@ extern int kgdb_nmicallback(int cpu, void *regs);
extern int kgdb_single_step;
extern atomic_t kgdb_active;
+#endif /* CONFIG_KGDB */
+
+/* Common to all that include kgdb.h */
+struct dbg_kms_ops {
+ int (*activate_console) (struct dbg_kms_ops *ops);
+ int (*restore_console) (struct dbg_kms_ops *ops);
+};
+
+#ifdef CONFIG_KGDB
#define in_dbg_master() \
(raw_smp_processor_id() == atomic_read(&kgdb_active))
+
+extern struct dbg_kms_ops *dbg_kms_ops;
+extern int dbg_kms_ops_register(struct dbg_kms_ops *ops);
+extern int dbg_kms_ops_unregister(struct dbg_kms_ops *ops);
#else /* ! CONFIG_KGDB */
#define in_dbg_master() (0)
+
+static inline int dbg_kms_ops_register(struct dbg_kms_ops *ops)
+{
+ return 0;
+}
+static inline int dbg_kms_ops_unregister(struct dbg_kms_ops *ops)
+{
+ return 0;
+}
#endif /* ! CONFIG_KGDB */
#endif /* _KGDB_H_ */
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index f7ebb7f..bcd6286 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -793,6 +793,29 @@ static void kgdb_register_callbacks(void)
}
}
+struct dbg_kms_ops *dbg_kms_ops;
+EXPORT_SYMBOL_GPL(dbg_kms_ops);
+
+int dbg_kms_ops_register(struct dbg_kms_ops *ops)
+{
+ if (dbg_kms_ops) {
+ printk(KERN_ERR "dbg_core: KMS ops already in use\n");
+ return -1;
+ }
+ dbg_kms_ops = ops;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dbg_kms_ops_register);
+
+int dbg_kms_ops_unregister(struct dbg_kms_ops *ops)
+{
+ if (dbg_kms_ops != ops)
+ printk(KERN_ERR "dbg_core: KMS ops do not match\n");
+ dbg_kms_ops = NULL;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dbg_kms_ops_unregister);
+
static void kgdb_unregister_callbacks(void)
{
/*
--
1.6.4.rc1
The kgdboc pre exception handler must atomically save the state of the
existing VC console and activate it, if it is blanked.
Before restoring the kernel to a running state, the kgdboc post
exception handler will restore the state of the VC variables that got
changed while atomic.
CC: David Airlie <[email protected]>
CC: Jesse Barnes <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/serial/kgdboc.c | 25 ++++++++++++----
drivers/video/console/fbcon.c | 7 ++++
include/linux/kgdb.h | 8 +++++
kernel/debug/Makefile | 1 +
kernel/debug/kms_hooks.c | 62 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 96 insertions(+), 7 deletions(-)
create mode 100644 kernel/debug/kms_hooks.c
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index bc1fec1..246b7c3 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -220,13 +220,19 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
return configure_kgdboc();
}
+static int dbg_restore_graphics;
+
static void kgdboc_pre_exp_handler(void)
{
- if (kgdboc_use_kms && dbg_kms_ops &&
- dbg_kms_ops->activate_console)
- if (dbg_kms_ops->activate_console(dbg_kms_ops))
+ if (!dbg_restore_graphics && kgdboc_use_kms && dbg_kms_ops &&
+ dbg_kms_ops->activate_console) {
+ if (dbg_kms_ops->activate_console(dbg_kms_ops)) {
printk(KERN_ERR "kgdboc: kernel mode switch error\n");
-
+ } else {
+ dbg_restore_graphics = 1;
+ dbg_pre_vt_hook();
+ }
+ }
/* Increment the module count when the debugger is active */
if (!kgdb_connected)
try_module_get(THIS_MODULE);
@@ -238,9 +244,14 @@ static void kgdboc_post_exp_handler(void)
if (!kgdb_connected)
module_put(THIS_MODULE);
if (kgdboc_use_kms && dbg_kms_ops &&
- dbg_kms_ops->restore_console)
- if (dbg_kms_ops->restore_console(dbg_kms_ops))
- printk(KERN_ERR "kgdboc: graphics restore failed\n");
+ dbg_kms_ops->restore_console) {
+ if (dbg_restore_graphics) {
+ if (dbg_kms_ops->restore_console(dbg_kms_ops))
+ printk(KERN_ERR "kgdboc: graphics restore failed\n");
+ dbg_restore_graphics = 0;
+ dbg_post_vt_hook();
+ }
+ }
kgdboc_clear_kbd();
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3681c6a..6f2ed5a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -75,6 +75,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/crc32.h> /* For counting font checksums */
+#include <linux/kgdb.h>
#include <asm/fb.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -2318,6 +2319,12 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
}
}
+ if (in_dbg_master()) {
+ if (info->fbops->fb_blank)
+ info->fbops->fb_blank(blank, info);
+ return 0;
+ }
+
if (!fbcon_is_inactive(vc, info)) {
if (ops->blank_state != blank) {
ops->blank_state = blank;
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 9cd6baa..81bb298 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -286,6 +286,14 @@ extern atomic_t kgdb_active;
#endif /* CONFIG_KGDB */
/* Common to all that include kgdb.h */
+#ifdef CONFIG_VT
+extern void dbg_pre_vt_hook(void);
+extern void dbg_post_vt_hook(void);
+#else /* ! CONFIG_VT */
+#define dbg_pre_vt_hook()
+#define dbg_post_vt_hook()
+#endif /* CONFIG_VT */
+
struct dbg_kms_ops {
int (*activate_console) (struct dbg_kms_ops *ops);
int (*restore_console) (struct dbg_kms_ops *ops);
diff --git a/kernel/debug/Makefile b/kernel/debug/Makefile
index c72de00..fe342c0 100644
--- a/kernel/debug/Makefile
+++ b/kernel/debug/Makefile
@@ -3,5 +3,6 @@
#
obj-$(CONFIG_KGDB) += debug_core.o gdbstub.o
+obj-$(CONFIG_VT) += kms_hooks.o
obj-$(CONFIG_KGDB_KDB) += kdb/
diff --git a/kernel/debug/kms_hooks.c b/kernel/debug/kms_hooks.c
new file mode 100644
index 0000000..c56b7ce
--- /dev/null
+++ b/kernel/debug/kms_hooks.c
@@ -0,0 +1,62 @@
+/*
+ * Created by: Jason Wessel <[email protected]>
+ *
+ * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_VT
+#include <linux/kgdb.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/kdb.h>
+#include "kdb/kdb_private.h"
+
+static int dbg_orig_vc_mode;
+static int saved_fg_con;
+static int saved_last_con;
+static int saved_want_con;
+
+void dbg_pre_vt_hook(void)
+{
+ struct vc_data *vc = vc_cons[fg_console].d;
+ saved_fg_con = fg_console;
+ saved_last_con = last_console;
+ saved_want_con = want_console;
+ dbg_orig_vc_mode = vc->vc_mode;
+ vc->vc_mode = KD_TEXT;
+ console_blanked = 0;
+ vc->vc_sw->con_blank(vc, 0, 1);
+ vc->vc_sw->con_set_palette(vc, color_table);
+#ifdef CONFIG_KGDB_KDB
+ /* Set the initial LINES variable if it is not already set */
+ if (vc->vc_rows < 999) {
+ int linecount;
+ char lns[4];
+ const char *setargs[3] = {
+ "set",
+ "LINES",
+ lns,
+ };
+ if (kdbgetintenv(setargs[0], &linecount)) {
+ snprintf(lns, 4, "%i", vc->vc_rows);
+ kdb_set(2, setargs);
+ }
+ }
+#endif /* CONFIG_KGDB_KDB */
+}
+EXPORT_SYMBOL_GPL(dbg_pre_vt_hook);
+
+void dbg_post_vt_hook(void)
+{
+ fg_console = saved_fg_con;
+ last_console = saved_last_con;
+ want_console = saved_want_con;
+ vc_cons[fg_console].d->vc_mode = dbg_orig_vc_mode;
+}
+EXPORT_SYMBOL_GPL(dbg_post_vt_hook);
+#endif /* CONFIG_VT */
--
1.6.4.rc1
On 02/12/10 14:36, Jason Wessel wrote:
> Update the kgdb docs to include information about kernel mode setting support.
>
> Signed-off-by: Jason Wessel <[email protected]>
> ---
> Documentation/DocBook/kgdb.tmpl | 82 +++++++++++++++++++++++++++++++----
> Documentation/kernel-parameters.txt | 9 +++-
> 2 files changed, 79 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
> index cc81879..498267b 100644
> --- a/Documentation/DocBook/kgdb.tmpl
> +++ b/Documentation/DocBook/kgdb.tmpl
> @@ -200,12 +200,29 @@
> only make use of <constant>kgdbwait</constant> and early debugging
> if you build kgdboc into the kernel as a builtins.
> </para>
> + <para>Optionally you can elect to activate kms (Kernel Mode
> + Setting) integration. When you use kms with kgdboc and you have a
> + video driver that has atomic mode setting hooks, it is possible to
> + enter the debugger on the graphics console. When the kernel
> + execution is resumed, the graphics previous graphics mode will get
drop first "graphics" above ... mode will be
> + restored. This integration can serve as a useful tool to aid in
> + dianosing crashes or doing analysis of memory with kdb while
diagnosing
> + allowing the full graphics console applications to run.
> + </para>
> <sect2 id="kgdbocArgs">
> <title>kgdboc arguments</title>
> - <para>Usage: <constant>kgdboc=[kbd][[,]serial_device][,baud]</constant></para>
> - <para>You can configure kgdboc to use the keyboard, and or a serial device
> - depending on if you are using kdb and or kgdb, in one of the
> - following scenarios.
> + <para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
> + <para>Abreviations:
> + <itemizedlist>
> + <listitem><para>kms = Kernel Mode Setting</para></listitem>
> + <listitem><para>kbd = Keyboard</para></listitem>
> + </itemizedlist>
> + </para>
> + <para>You can configure kgdboc to use the keyboard, and or a serial
> + device depending on if you are using kdb and or kgdb, in one of the
> + following scenarios. The order listed above must be observed if
> + you use any of the optional configurations together. Using kms +
> + only gdb is generally not a usful combination.
useful
> <orderedlist>
> <listitem><para>kdb and kgdb over only a serial port</para>
> <para><constant>kgdboc=<serial_device>[,baud]</constant></para>
> @@ -218,6 +235,12 @@
> <listitem><para>kdb with a keyboard</para>
> <para><constant>kgdboc=kbd</constant></para>
> </listitem>
> + <listitem><para>kdb with kernel modesetting</para>
> + <para><constant>kgdboc=kms,kbd</constant></para>
> + </listitem>
> + <listitem><para>kdb with kernel modesetting and kgdb over a serial port</para>
> + <para><constant>kgdboc=kbd,kbd,ttyS0,115200</constant></para>
> + </listitem>
> </orderedlist>
> </para>
> <para>You can configure kgdboc via sysfs or a module or kernel boot line
> @@ -613,6 +636,8 @@ Task Addr Pid Parent [*] cpu State Thread Command
> <listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
> <listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
> <listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
> + <listitem><para>The structures and call back API for atomic kernel mode setting.</para>
callback
> + <para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
> </itemizedlist>
> </para>
> </listitem>
> @@ -721,6 +746,8 @@ Task Addr Pid Parent [*] cpu State Thread Command
> </sect1>
> <sect1 id="kgdbocDesign">
> <title>kgdboc internals</title>
> + <sect2>
> + <title>kgdboc and uarts</title>
> <para>
> The kgdboc driver is actually a very thin driver that relies on the
> underlying low level to the hardware driver having "polling hooks"
> @@ -729,10 +756,7 @@ Task Addr Pid Parent [*] cpu State Thread Command
> low level uart hook for doing polled mode reading and writing of a
I prefer UART, but, oh well.
> single character while in an atomic context. When kgdb makes an I/O
> request to the debugger, kgdboc invokes a call back in the serial
> - core which in turn uses the call back in the uart driver. It is
callback in the UART
> - certainly possible to extend kgdboc to work with non-uart based
non-UART-based
> - consoles in the future.
> - </para>
> + core which in turn uses the call back in the uart driver.</para>
callback
> <para>
> When using kgdboc with a uart, the uart driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
> #ifdef CONFIG_CONSOLE_POLL
> @@ -746,9 +770,49 @@ Task Addr Pid Parent [*] cpu State Thread Command
> that they can be called from an atomic context and have to restore
> the state of the uart chip on return such that the system can return
> to normal when the debugger detaches. You need to be very careful
> - with any kind of lock you consider, because failing here is most
> + with any kind of lock you consider, because failing here is most likely
> going to mean pressing the reset button.
> </para>
> + </sect2>
> + <sect2 id="kgdbocKbd">
> + <title>kgdboc and keyboards</title>
> + <para>The kgdboc driver contains logic to configure communications
> + with an attached keyboard. The keyboard infrastructure is only
> + compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
> + kernel configuration.</para>
> + <para>The core polled keyboard driver driver for PS/2 type keyboards
> + is in drivers/char/kdb_keyboard.c. This driver is hooked into the
> + debug core when kgdboc populates the callback in the arrary
array
> + called <constant>kdb_poll_funcs[]</constant>. The
> + kdb_get_kbd_char() is the top level function which polls hardware
top-level
> + for single character input.
> + </para>
> + </sect2>
> + <sect2 id="kgdbocKms">
> + <title>kgdboc and kms</title>
> + <para>The kgdboc driver contains logic to request the grpahics
graphics
> + display to switch to a text context if you are using
> + kgdboc=kms,... and you have a video driver which has a framebuffer
> + console and atomic kernel mode setting support. Every time kernel
> + debugger is entered it calls kgdboc_pre_exp_handler() which in turn
> + calls dbg_kms_ops->activate_console(). On resuming kernel
> + execution, the kernel debugger calls kgdboc_post_exp_handler() which
> + in turn calls dbg_kms_ops->restore_console().</para>
> + <para>Any video driver that wants to be compatible with the kernel
> + debugger and the atomic kms callbacks must implement the
> + mode_set_base_atomic operation. The following is an example from
> + drivers/gpu/drm/i915/intel_display.c:
> + <informalexample>
> + <programlisting>
> +static const struct drm_crtc_helper_funcs intel_helper_funcs = {
> +[...]
> + .mode_set_base_atomic = intel_pipe_set_base_atomic,
> +[...]
> +};
> + </programlisting>
> + </informalexample>
> + </para>
> + </sect2>
> </sect1>
> </chapter>
> <chapter id="credits">
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index af8b8e8..b340445 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1106,9 +1106,12 @@ and is between 256 and 4096 characters. It is defined in the file
> kgdboc= [KGDB,HW] kgdb over consoles.
> Requires a tty driver that supports console polling,
> or a supported polling keyboard driver (non-usb).
> - Serial only format: <serial_device>[,baud]
> - keyboard only format: kbd
> - keyboard and serial format: kbd,<serial_device>[,baud]
> + Serial only format: <serial_device>[,baud]
> + keyboard only format: kbd
> + keyboard and serial format: kbd,<serial_device>[,baud]
> + Optional Kernal mode setting:
Kernel
> + kms, kbd format: kms,kbd
> + kms, kbd and serial format: kms,kbd,<ser_dev>[,baud]
>
> kgdbwait [KGDB] Stop kernel execution and enter the
> kernel debugger at the earliest opportunity if
--
~Randy
Randy Dunlap wrote:
> On 02/12/10 14:36, Jason Wessel wrote:
>
>> Update the kgdb docs to include information about kernel mode setting support.
>>
>>
Randy, Thanks again.
All these changes are folded into the kms docs patch.
Jason.
On Fri, 12 Feb 2010 16:36:22 -0600
Jason Wessel <[email protected]> wrote:
> Hooks for the kgdb core for registration of the drm layer to provide a
> call backs so as to perform kernel mode switching, for use with kdb.
>
> [[email protected]: add ops arg to kgdb console active &
> restore hooks]
>
> CC: Jesse Barnes <[email protected]>
> Signed-off-by: Jason Wessel <[email protected]>
> ---
You can add my s-o-b:
Signed-off-by: Jesse Barnes <[email protected]>
--
Jesse Barnes, Intel Open Source Technology Center
On Fri, 12 Feb 2010 16:36:24 -0600
Jason Wessel <[email protected]> wrote:
> The kgdboc pre exception handler must atomically save the state of the
> existing VC console and activate it, if it is blanked.
>
> Before restoring the kernel to a running state, the kgdboc post
> exception handler will restore the state of the VC variables that got
> changed while atomic.
>
> CC: David Airlie <[email protected]>
> CC: Jesse Barnes <[email protected]>
> Signed-off-by: Jason Wessel <[email protected]>
> ---
Ugg VT. But still,
Acked-by: Jesse Barnes <[email protected]>
--
Jesse Barnes, Intel Open Source Technology Center