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       |   59 ++++++++++++++++++++++++++++++++++++-----
 drivers/video/console/fbcon.c |    8 +++++
 2 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 93b18f9..b5d7e71 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -18,6 +18,8 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/input.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
 
 #define MAX_CONFIG_LEN         40
 
@@ -204,13 +206,50 @@ static int param_set_kgdboc_var(const char *kmessage, 
struct kernel_param *kp)
        return configure_kgdboc();
 }
 
+#ifdef CONFIG_VT
+static int dbg_orig_vc_mode;
+static int saved_fg_con;
+static int saved_last_con;
+static int saved_want_con;
+
+static void kgdboc_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);
+}
+
+static void kgdboc_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;
+}
+#else
+#define kgdboc_pre_vt_hook()
+#define kgdboc_post_vt_hook()
+#endif /* CONFIG_VT */
+
+static int dbg_restore_graphics;
+
 static void kgdboc_pre_exp_handler(void)
 {
-       if (kgdboc_use_kms && dbg_kms_console_core &&
-           dbg_kms_console_core->activate_console)
-               if 
(dbg_kms_console_core->activate_console(dbg_kms_console_core))
+       if (!dbg_restore_graphics && kgdboc_use_kms && dbg_kms_console_core &&
+           dbg_kms_console_core->activate_console) {
+               if 
(dbg_kms_console_core->activate_console(dbg_kms_console_core)) {
                        printk(KERN_ERR "kgdboc: kernel mode switch error\n");
-
+               } else {
+                       dbg_restore_graphics = 1;
+                       kgdboc_pre_vt_hook();
+               }
+       }
        /* Increment the module count when the debugger is active */
        if (!kgdb_connected)
                try_module_get(THIS_MODULE);
@@ -222,9 +261,15 @@ static void kgdboc_post_exp_handler(void)
        if (!kgdb_connected)
                module_put(THIS_MODULE);
        if (kgdboc_use_kms && dbg_kms_console_core &&
-           dbg_kms_console_core->restore_console)
-               if (dbg_kms_console_core->restore_console(dbg_kms_console_core))
-                       printk(KERN_ERR "kgdboc: graphics restore failed\n");
+           dbg_kms_console_core->restore_console) {
+               if (dbg_restore_graphics) {
+                       if 
(dbg_kms_console_core->restore_console(dbg_kms_console_core))
+                               printk(KERN_ERR "kgdboc: graphics restore 
failed\n");
+                       dbg_restore_graphics = 0;
+                       kgdboc_post_vt_hook();
+               }
+       }
+
 #ifdef CONFIG_KDB_KEYBOARD
        /* If using the kdb keyboard driver release all the keys. */
        if (kgdboc_use_kbd)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3681c6a..138a25c 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,13 @@ static int fbcon_blank(struct vc_data *vc, int blank, 
int mode_switch)
                }
        }
 
+#ifdef CONFIG_KGDB_KDB
+               if (atomic_read(&kgdb_active) != -1) {
+                       if (info->fbops->fb_blank)
+                               info->fbops->fb_blank(blank, info);
+                       return 0;
+               }
+#endif
        if (!fbcon_is_inactive(vc, info)) {
                if (ops->blank_state != blank) {
                        ops->blank_state = blank;
-- 
1.6.4.rc1


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to