Commit 9779714c8af09d57527f18d9aa2207dcc27a8687

Authored by Linus Torvalds

Merge branch 'kms-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb

* 'kms-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb:
  kgdb,docs: Update the kgdb docs to include kms
  drm_fb_helper: Preserve capability to use atomic kms
  i915: when kgdb is active display compression should be off
  drm/i915: use new fb debug hooks
  drm: add KGDB/KDB support
  fb: add hooks to handle KDB enter/exit
  kgdboc: Add call backs to allow kernel mode switching
  vt,console,kdb: automatically set kdb LINES variable
  vt,console,kdb: implement atomic console enter/leave functions

Showing 15 changed files Side-by-side Diff

Documentation/DocBook/kgdb.tmpl
... ... @@ -199,10 +199,33 @@
199 199 may be configured as a kernel built-in or a kernel loadable module.
200 200 You can only make use of <constant>kgdbwait</constant> and early
201 201 debugging if you build kgdboc into the kernel as a built-in.
  202 + <para>Optionally you can elect to activate kms (Kernel Mode
  203 + Setting) integration. When you use kms with kgdboc and you have a
  204 + video driver that has atomic mode setting hooks, it is possible to
  205 + enter the debugger on the graphics console. When the kernel
  206 + execution is resumed, the previous graphics mode will be restored.
  207 + This integration can serve as a useful tool to aid in diagnosing
  208 + crashes or doing analysis of memory with kdb while allowing the
  209 + full graphics console applications to run.
202 210 </para>
  211 + </para>
203 212 <sect2 id="kgdbocArgs">
204 213 <title>kgdboc arguments</title>
205   - <para>Usage: <constant>kgdboc=[kbd][[,]serial_device][,baud]</constant></para>
  214 + <para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
  215 + <para>The order listed above must be observed if you use any of the
  216 + optional configurations together.
  217 + </para>
  218 + <para>Abbreviations:
  219 + <itemizedlist>
  220 + <listitem><para>kms = Kernel Mode Setting</para></listitem>
  221 + <listitem><para>kbd = Keyboard</para></listitem>
  222 + </itemizedlist>
  223 + </para>
  224 + <para>You can configure kgdboc to use the keyboard, and or a serial
  225 + device depending on if you are using kdb and or kgdb, in one of the
  226 + following scenarios. The order listed above must be observed if
  227 + you use any of the optional configurations together. Using kms +
  228 + only gdb is generally not a useful combination.</para>
206 229 <sect3 id="kgdbocArgs1">
207 230 <title>Using loadable module or built-in</title>
208 231 <para>
... ... @@ -212,7 +235,7 @@
212 235 <listitem>
213 236 <para>As a kernel loadable module:</para>
214 237 <para>Use the command: <constant>modprobe kgdboc kgdboc=&lt;tty-device&gt;,[baud]</constant></para>
215   - <para>Here are two examples of how you might formate the kgdboc
  238 + <para>Here are two examples of how you might format the kgdboc
216 239 string. The first is for an x86 target using the first serial port.
217 240 The second example is for the ARM Versatile AB using the second
218 241 serial port.
... ... @@ -240,6 +263,9 @@
240 263 </sect3>
241 264 <sect3 id="kgdbocArgs3">
242 265 <title>More examples</title>
  266 + <para>You can configure kgdboc to use the keyboard, and or a serial
  267 + device depending on if you are using kdb and or kgdb, in one of the
  268 + following scenarios.</para>
243 269 <para>You can configure kgdboc to use the keyboard, and or a serial device
244 270 depending on if you are using kdb and or kgdb, in one of the
245 271 following scenarios.
... ... @@ -255,6 +281,12 @@
255 281 <listitem><para>kdb with a keyboard</para>
256 282 <para><constant>kgdboc=kbd</constant></para>
257 283 </listitem>
  284 + <listitem><para>kdb with kernel mode setting</para>
  285 + <para><constant>kgdboc=kms,kbd</constant></para>
  286 + </listitem>
  287 + <listitem><para>kdb with kernel mode setting and kgdb over a serial port</para>
  288 + <para><constant>kgdboc=kms,kbd,ttyS0,115200</constant></para>
  289 + </listitem>
258 290 </orderedlist>
259 291 </para>
260 292 </sect3>
... ... @@ -637,6 +669,8 @@
637 669 <listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
638 670 <listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
639 671 <listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
  672 + <listitem><para>The structures and callback API for atomic kernel mode setting.</para>
  673 + <para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
640 674 </itemizedlist>
641 675 </para>
642 676 </listitem>
... ... @@ -747,6 +781,8 @@
747 781 </sect1>
748 782 <sect1 id="kgdbocDesign">
749 783 <title>kgdboc internals</title>
  784 + <sect2>
  785 + <title>kgdboc and uarts</title>
750 786 <para>
751 787 The kgdboc driver is actually a very thin driver that relies on the
752 788 underlying low level to the hardware driver having "polling hooks"
... ... @@ -754,11 +790,8 @@
754 790 implementation of kgdboc it the serial_core was changed to expose a
755 791 low level UART hook for doing polled mode reading and writing of a
756 792 single character while in an atomic context. When kgdb makes an I/O
757   - request to the debugger, kgdboc invokes a call back in the serial
758   - core which in turn uses the call back in the UART driver. It is
759   - certainly possible to extend kgdboc to work with non-UART based
760   - consoles in the future.
761   - </para>
  793 + request to the debugger, kgdboc invokes a callback in the serial
  794 + core which in turn uses the callback in the UART driver.</para>
762 795 <para>
763 796 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>
764 797 #ifdef CONFIG_CONSOLE_POLL
765 798  
... ... @@ -772,9 +805,68 @@
772 805 that they can be called from an atomic context and have to restore
773 806 the state of the UART chip on return such that the system can return
774 807 to normal when the debugger detaches. You need to be very careful
775   - with any kind of lock you consider, because failing here is most
  808 + with any kind of lock you consider, because failing here is most likely
776 809 going to mean pressing the reset button.
777 810 </para>
  811 + </sect2>
  812 + <sect2 id="kgdbocKbd">
  813 + <title>kgdboc and keyboards</title>
  814 + <para>The kgdboc driver contains logic to configure communications
  815 + with an attached keyboard. The keyboard infrastructure is only
  816 + compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
  817 + kernel configuration.</para>
  818 + <para>The core polled keyboard driver driver for PS/2 type keyboards
  819 + is in drivers/char/kdb_keyboard.c. This driver is hooked into the
  820 + debug core when kgdboc populates the callback in the array
  821 + called <constant>kdb_poll_funcs[]</constant>. The
  822 + kdb_get_kbd_char() is the top-level function which polls hardware
  823 + for single character input.
  824 + </para>
  825 + </sect2>
  826 + <sect2 id="kgdbocKms">
  827 + <title>kgdboc and kms</title>
  828 + <para>The kgdboc driver contains logic to request the graphics
  829 + display to switch to a text context when you are using
  830 + "kgdboc=kms,kbd", provided that you have a video driver which has a
  831 + frame buffer console and atomic kernel mode setting support.</para>
  832 + <para>
  833 + Every time the kernel
  834 + debugger is entered it calls kgdboc_pre_exp_handler() which in turn
  835 + calls con_debug_enter() in the virtual console layer. On resuming kernel
  836 + execution, the kernel debugger calls kgdboc_post_exp_handler() which
  837 + in turn calls con_debug_leave().</para>
  838 + <para>Any video driver that wants to be compatible with the kernel
  839 + debugger and the atomic kms callbacks must implement the
  840 + mode_set_base_atomic, fb_debug_enter and fb_debug_leave operations.
  841 + For the fb_debug_enter and fb_debug_leave the option exists to use
  842 + the generic drm fb helper functions or implement something custom for
  843 + the hardware. The following example shows the initialization of the
  844 + .mode_set_base_atomic operation in
  845 + drivers/gpu/drm/i915/intel_display.c:
  846 + <informalexample>
  847 + <programlisting>
  848 +static const struct drm_crtc_helper_funcs intel_helper_funcs = {
  849 +[...]
  850 + .mode_set_base_atomic = intel_pipe_set_base_atomic,
  851 +[...]
  852 +};
  853 + </programlisting>
  854 + </informalexample>
  855 + </para>
  856 + <para>Here is an example of how the i915 driver initializes the fb_debug_enter and fb_debug_leave functions to use the generic drm helpers in
  857 + drivers/gpu/drm/i915/intel_fb.c:
  858 + <informalexample>
  859 + <programlisting>
  860 +static struct fb_ops intelfb_ops = {
  861 +[...]
  862 + .fb_debug_enter = drm_fb_helper_debug_enter,
  863 + .fb_debug_leave = drm_fb_helper_debug_leave,
  864 +[...]
  865 +};
  866 + </programlisting>
  867 + </informalexample>
  868 + </para>
  869 + </sect2>
778 870 </sect1>
779 871 </chapter>
780 872 <chapter id="credits">
Documentation/kernel-parameters.txt
... ... @@ -1145,9 +1145,12 @@
1145 1145 kgdboc= [KGDB,HW] kgdb over consoles.
1146 1146 Requires a tty driver that supports console polling,
1147 1147 or a supported polling keyboard driver (non-usb).
1148   - Serial only format: <serial_device>[,baud]
1149   - keyboard only format: kbd
1150   - keyboard and serial format: kbd,<serial_device>[,baud]
  1148 + Serial only format: <serial_device>[,baud]
  1149 + keyboard only format: kbd
  1150 + keyboard and serial format: kbd,<serial_device>[,baud]
  1151 + Optional Kernel mode setting:
  1152 + kms, kbd format: kms,kbd
  1153 + kms, kbd and serial format: kms,kbd,<ser_dev>[,baud]
1151 1154  
1152 1155 kgdbwait [KGDB] Stop kernel execution and enter the
1153 1156 kernel debugger at the earliest opportunity.
... ... @@ -104,6 +104,7 @@
104 104 #include <linux/io.h>
105 105 #include <asm/system.h>
106 106 #include <linux/uaccess.h>
  107 +#include <linux/kdb.h>
107 108  
108 109 #define MAX_NR_CON_DRIVER 16
109 110  
110 111  
... ... @@ -187,10 +188,15 @@
187 188 * fg_console is the current virtual console,
188 189 * last_console is the last used one,
189 190 * want_console is the console we want to switch to,
  191 + * saved_* variants are for save/restore around kernel debugger enter/leave
190 192 */
191 193 int fg_console;
192 194 int last_console;
193 195 int want_console = -1;
  196 +int saved_fg_console;
  197 +int saved_last_console;
  198 +int saved_want_console;
  199 +int saved_vc_mode;
194 200  
195 201 /*
196 202 * For each existing display, we have a pointer to console currently visible
... ... @@ -3412,6 +3418,78 @@
3412 3418 return bound;
3413 3419 }
3414 3420 EXPORT_SYMBOL(con_is_bound);
  3421 +
  3422 +/**
  3423 + * con_debug_enter - prepare the console for the kernel debugger
  3424 + * @sw: console driver
  3425 + *
  3426 + * Called when the console is taken over by the kernel debugger, this
  3427 + * function needs to save the current console state, then put the console
  3428 + * into a state suitable for the kernel debugger.
  3429 + *
  3430 + * RETURNS:
  3431 + * Zero on success, nonzero if a failure occurred when trying to prepare
  3432 + * the console for the debugger.
  3433 + */
  3434 +int con_debug_enter(struct vc_data *vc)
  3435 +{
  3436 + int ret = 0;
  3437 +
  3438 + saved_fg_console = fg_console;
  3439 + saved_last_console = last_console;
  3440 + saved_want_console = want_console;
  3441 + saved_vc_mode = vc->vc_mode;
  3442 + vc->vc_mode = KD_TEXT;
  3443 + console_blanked = 0;
  3444 + if (vc->vc_sw->con_debug_enter)
  3445 + ret = vc->vc_sw->con_debug_enter(vc);
  3446 +#ifdef CONFIG_KGDB_KDB
  3447 + /* Set the initial LINES variable if it is not already set */
  3448 + if (vc->vc_rows < 999) {
  3449 + int linecount;
  3450 + char lns[4];
  3451 + const char *setargs[3] = {
  3452 + "set",
  3453 + "LINES",
  3454 + lns,
  3455 + };
  3456 + if (kdbgetintenv(setargs[0], &linecount)) {
  3457 + snprintf(lns, 4, "%i", vc->vc_rows);
  3458 + kdb_set(2, setargs);
  3459 + }
  3460 + }
  3461 +#endif /* CONFIG_KGDB_KDB */
  3462 + return ret;
  3463 +}
  3464 +EXPORT_SYMBOL_GPL(con_debug_enter);
  3465 +
  3466 +/**
  3467 + * con_debug_leave - restore console state
  3468 + * @sw: console driver
  3469 + *
  3470 + * Restore the console state to what it was before the kernel debugger
  3471 + * was invoked.
  3472 + *
  3473 + * RETURNS:
  3474 + * Zero on success, nonzero if a failure occurred when trying to restore
  3475 + * the console.
  3476 + */
  3477 +int con_debug_leave(void)
  3478 +{
  3479 + struct vc_data *vc;
  3480 + int ret = 0;
  3481 +
  3482 + fg_console = saved_fg_console;
  3483 + last_console = saved_last_console;
  3484 + want_console = saved_want_console;
  3485 + vc_cons[fg_console].d->vc_mode = saved_vc_mode;
  3486 +
  3487 + vc = vc_cons[fg_console].d;
  3488 + if (vc->vc_sw->con_debug_leave)
  3489 + ret = vc->vc_sw->con_debug_leave(vc);
  3490 + return ret;
  3491 +}
  3492 +EXPORT_SYMBOL_GPL(con_debug_leave);
3415 3493  
3416 3494 /**
3417 3495 * register_con_driver - register console driver to console layer
drivers/gpu/drm/drm_fb_helper.c
... ... @@ -241,6 +241,80 @@
241 241 return 0;
242 242 }
243 243  
  244 +int drm_fb_helper_debug_enter(struct fb_info *info)
  245 +{
  246 + struct drm_fb_helper *helper = info->par;
  247 + struct drm_crtc_helper_funcs *funcs;
  248 + int i;
  249 +
  250 + if (list_empty(&kernel_fb_helper_list))
  251 + return false;
  252 +
  253 + list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
  254 + for (i = 0; i < helper->crtc_count; i++) {
  255 + struct drm_mode_set *mode_set =
  256 + &helper->crtc_info[i].mode_set;
  257 +
  258 + if (!mode_set->crtc->enabled)
  259 + continue;
  260 +
  261 + funcs = mode_set->crtc->helper_private;
  262 + funcs->mode_set_base_atomic(mode_set->crtc,
  263 + mode_set->fb,
  264 + mode_set->x,
  265 + mode_set->y);
  266 +
  267 + }
  268 + }
  269 +
  270 + return 0;
  271 +}
  272 +EXPORT_SYMBOL(drm_fb_helper_debug_enter);
  273 +
  274 +/* Find the real fb for a given fb helper CRTC */
  275 +static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
  276 +{
  277 + struct drm_device *dev = crtc->dev;
  278 + struct drm_crtc *c;
  279 +
  280 + list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
  281 + if (crtc->base.id == c->base.id)
  282 + return c->fb;
  283 + }
  284 +
  285 + return NULL;
  286 +}
  287 +
  288 +int drm_fb_helper_debug_leave(struct fb_info *info)
  289 +{
  290 + struct drm_fb_helper *helper = info->par;
  291 + struct drm_crtc *crtc;
  292 + struct drm_crtc_helper_funcs *funcs;
  293 + struct drm_framebuffer *fb;
  294 + int i;
  295 +
  296 + for (i = 0; i < helper->crtc_count; i++) {
  297 + struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
  298 + crtc = mode_set->crtc;
  299 + funcs = crtc->helper_private;
  300 + fb = drm_mode_config_fb(crtc);
  301 +
  302 + if (!crtc->enabled)
  303 + continue;
  304 +
  305 + if (!fb) {
  306 + DRM_ERROR("no fb to restore??\n");
  307 + continue;
  308 + }
  309 +
  310 + funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
  311 + crtc->y);
  312 + }
  313 +
  314 + return 0;
  315 +}
  316 +EXPORT_SYMBOL(drm_fb_helper_debug_leave);
  317 +
244 318 bool drm_fb_helper_force_kernel_mode(void)
245 319 {
246 320 int i = 0;
... ... @@ -611,7 +685,7 @@
611 685 struct drm_framebuffer *fb = fb_helper->fb;
612 686 int depth;
613 687  
614   - if (var->pixclock != 0)
  688 + if (var->pixclock != 0 || in_dbg_master())
615 689 return -EINVAL;
616 690  
617 691 /* Need to resize the fb object !!! */
drivers/gpu/drm/i915/intel_display.c
... ... @@ -975,7 +975,10 @@
975 975 intel_wait_for_vblank(struct drm_device *dev)
976 976 {
977 977 /* Wait for 20ms, i.e. one cycle at 50hz. */
978   - msleep(20);
  978 + if (in_dbg_master())
  979 + mdelay(20); /* The kernel debugger cannot call msleep() */
  980 + else
  981 + msleep(20);
979 982 }
980 983  
981 984 /* Parameters have changed, update FBC info */
... ... @@ -1248,6 +1251,10 @@
1248 1251 goto out_disable;
1249 1252 }
1250 1253  
  1254 + /* If the kernel debugger is active, always disable compression */
  1255 + if (in_dbg_master())
  1256 + goto out_disable;
  1257 +
1251 1258 if (intel_fbc_enabled(dev)) {
1252 1259 /* We can re-enable it in this case, but need to update pitch */
1253 1260 if ((fb->pitch > dev_priv->cfb_pitch) ||
1254 1261  
... ... @@ -1314,7 +1321,99 @@
1314 1321 return 0;
1315 1322 }
1316 1323  
  1324 +/* Assume fb object is pinned & idle & fenced and just update base pointers */
1317 1325 static int
  1326 +intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
  1327 + int x, int y)
  1328 +{
  1329 + struct drm_device *dev = crtc->dev;
  1330 + struct drm_i915_private *dev_priv = dev->dev_private;
  1331 + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1332 + struct intel_framebuffer *intel_fb;
  1333 + struct drm_i915_gem_object *obj_priv;
  1334 + struct drm_gem_object *obj;
  1335 + int plane = intel_crtc->plane;
  1336 + unsigned long Start, Offset;
  1337 + int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
  1338 + int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
  1339 + int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
  1340 + int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
  1341 + int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
  1342 + u32 dspcntr;
  1343 +
  1344 + switch (plane) {
  1345 + case 0:
  1346 + case 1:
  1347 + break;
  1348 + default:
  1349 + DRM_ERROR("Can't update plane %d in SAREA\n", plane);
  1350 + return -EINVAL;
  1351 + }
  1352 +
  1353 + intel_fb = to_intel_framebuffer(fb);
  1354 + obj = intel_fb->obj;
  1355 + obj_priv = to_intel_bo(obj);
  1356 +
  1357 + dspcntr = I915_READ(dspcntr_reg);
  1358 + /* Mask out pixel format bits in case we change it */
  1359 + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
  1360 + switch (fb->bits_per_pixel) {
  1361 + case 8:
  1362 + dspcntr |= DISPPLANE_8BPP;
  1363 + break;
  1364 + case 16:
  1365 + if (fb->depth == 15)
  1366 + dspcntr |= DISPPLANE_15_16BPP;
  1367 + else
  1368 + dspcntr |= DISPPLANE_16BPP;
  1369 + break;
  1370 + case 24:
  1371 + case 32:
  1372 + dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
  1373 + break;
  1374 + default:
  1375 + DRM_ERROR("Unknown color depth\n");
  1376 + return -EINVAL;
  1377 + }
  1378 + if (IS_I965G(dev)) {
  1379 + if (obj_priv->tiling_mode != I915_TILING_NONE)
  1380 + dspcntr |= DISPPLANE_TILED;
  1381 + else
  1382 + dspcntr &= ~DISPPLANE_TILED;
  1383 + }
  1384 +
  1385 + if (IS_IRONLAKE(dev))
  1386 + /* must disable */
  1387 + dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
  1388 +
  1389 + I915_WRITE(dspcntr_reg, dspcntr);
  1390 +
  1391 + Start = obj_priv->gtt_offset;
  1392 + Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
  1393 +
  1394 + DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
  1395 + I915_WRITE(dspstride, fb->pitch);
  1396 + if (IS_I965G(dev)) {
  1397 + I915_WRITE(dspbase, Offset);
  1398 + I915_READ(dspbase);
  1399 + I915_WRITE(dspsurf, Start);
  1400 + I915_READ(dspsurf);
  1401 + I915_WRITE(dsptileoff, (y << 16) | x);
  1402 + } else {
  1403 + I915_WRITE(dspbase, Start + Offset);
  1404 + I915_READ(dspbase);
  1405 + }
  1406 +
  1407 + if ((IS_I965G(dev) || plane == 0))
  1408 + intel_update_fbc(crtc, &crtc->mode);
  1409 +
  1410 + intel_wait_for_vblank(dev);
  1411 + intel_increase_pllclock(crtc, true);
  1412 +
  1413 + return 0;
  1414 +}
  1415 +
  1416 +static int
1318 1417 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1319 1418 struct drm_framebuffer *old_fb)
1320 1419 {
... ... @@ -4814,6 +4913,7 @@
4814 4913 .mode_fixup = intel_crtc_mode_fixup,
4815 4914 .mode_set = intel_crtc_mode_set,
4816 4915 .mode_set_base = intel_pipe_set_base,
  4916 + .mode_set_base_atomic = intel_pipe_set_base_atomic,
4817 4917 .prepare = intel_crtc_prepare,
4818 4918 .commit = intel_crtc_commit,
4819 4919 .load_lut = intel_crtc_load_lut,
drivers/gpu/drm/i915/intel_fb.c
... ... @@ -61,6 +61,8 @@
61 61 .fb_pan_display = drm_fb_helper_pan_display,
62 62 .fb_blank = drm_fb_helper_blank,
63 63 .fb_setcmap = drm_fb_helper_setcmap,
  64 + .fb_debug_enter = drm_fb_helper_debug_enter,
  65 + .fb_debug_leave = drm_fb_helper_debug_leave,
64 66 };
65 67  
66 68 static int intelfb_create(struct intel_fbdev *ifbdev,
drivers/serial/kgdboc.c
... ... @@ -17,6 +17,7 @@
17 17 #include <linux/kdb.h>
18 18 #include <linux/tty.h>
19 19 #include <linux/console.h>
  20 +#include <linux/vt_kern.h>
20 21  
21 22 #define MAX_CONFIG_LEN 40
22 23  
... ... @@ -31,6 +32,7 @@
31 32 .maxlen = MAX_CONFIG_LEN,
32 33 };
33 34  
  35 +static int kgdboc_use_kms; /* 1 if we use kernel mode switching */
34 36 static struct tty_driver *kgdb_tty_driver;
35 37 static int kgdb_tty_line;
36 38  
... ... @@ -104,6 +106,12 @@
104 106 kgdboc_io_ops.is_console = 0;
105 107 kgdb_tty_driver = NULL;
106 108  
  109 + kgdboc_use_kms = 0;
  110 + if (strncmp(cptr, "kms,", 4) == 0) {
  111 + cptr += 4;
  112 + kgdboc_use_kms = 1;
  113 + }
  114 +
107 115 if (kgdboc_register_kbd(&cptr))
108 116 goto do_register;
109 117  
110 118  
... ... @@ -201,8 +209,14 @@
201 209 return configure_kgdboc();
202 210 }
203 211  
  212 +static int dbg_restore_graphics;
  213 +
204 214 static void kgdboc_pre_exp_handler(void)
205 215 {
  216 + if (!dbg_restore_graphics && kgdboc_use_kms) {
  217 + dbg_restore_graphics = 1;
  218 + con_debug_enter(vc_cons[fg_console].d);
  219 + }
206 220 /* Increment the module count when the debugger is active */
207 221 if (!kgdb_connected)
208 222 try_module_get(THIS_MODULE);
... ... @@ -213,6 +227,10 @@
213 227 /* decrement the module count when the debugger detaches */
214 228 if (!kgdb_connected)
215 229 module_put(THIS_MODULE);
  230 + if (kgdboc_use_kms && dbg_restore_graphics) {
  231 + dbg_restore_graphics = 0;
  232 + con_debug_leave();
  233 + }
216 234 }
217 235  
218 236 static struct kgdb_io kgdboc_io_ops = {
drivers/video/console/fbcon.c
... ... @@ -2342,6 +2342,30 @@
2342 2342 return 0;
2343 2343 }
2344 2344  
  2345 +static int fbcon_debug_enter(struct vc_data *vc)
  2346 +{
  2347 + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
  2348 + struct fbcon_ops *ops = info->fbcon_par;
  2349 +
  2350 + ops->save_graphics = ops->graphics;
  2351 + ops->graphics = 0;
  2352 + if (info->fbops->fb_debug_enter)
  2353 + info->fbops->fb_debug_enter(info);
  2354 + fbcon_set_palette(vc, color_table);
  2355 + return 0;
  2356 +}
  2357 +
  2358 +static int fbcon_debug_leave(struct vc_data *vc)
  2359 +{
  2360 + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
  2361 + struct fbcon_ops *ops = info->fbcon_par;
  2362 +
  2363 + ops->graphics = ops->save_graphics;
  2364 + if (info->fbops->fb_debug_leave)
  2365 + info->fbops->fb_debug_leave(info);
  2366 + return 0;
  2367 +}
  2368 +
2345 2369 static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
2346 2370 {
2347 2371 u8 *fontdata = vc->vc_font.data;
... ... @@ -3276,6 +3300,8 @@
3276 3300 .con_screen_pos = fbcon_screen_pos,
3277 3301 .con_getxy = fbcon_getxy,
3278 3302 .con_resize = fbcon_resize,
  3303 + .con_debug_enter = fbcon_debug_enter,
  3304 + .con_debug_leave = fbcon_debug_leave,
3279 3305 };
3280 3306  
3281 3307 static struct notifier_block fbcon_event_notifier = {
drivers/video/console/fbcon.h
... ... @@ -74,6 +74,7 @@
74 74 int cursor_reset;
75 75 int blank_state;
76 76 int graphics;
  77 + int save_graphics; /* for debug enter/leave */
77 78 int flags;
78 79 int rotate;
79 80 int cur_rotate;
include/drm/drm_crtc_helper.h
... ... @@ -60,6 +60,8 @@
60 60 /* Move the crtc on the current fb to the given position *optional* */
61 61 int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
62 62 struct drm_framebuffer *old_fb);
  63 + int (*mode_set_base_atomic)(struct drm_crtc *crtc,
  64 + struct drm_framebuffer *fb, int x, int y);
63 65  
64 66 /* reload the current crtc LUT */
65 67 void (*load_lut)(struct drm_crtc *crtc);
include/drm/drm_fb_helper.h
... ... @@ -32,6 +32,8 @@
32 32  
33 33 struct drm_fb_helper;
34 34  
  35 +#include <linux/kgdb.h>
  36 +
35 37 struct drm_fb_helper_crtc {
36 38 uint32_t crtc_id;
37 39 struct drm_mode_set mode_set;
... ... @@ -78,6 +80,7 @@
78 80  
79 81 struct drm_fb_helper {
80 82 struct drm_framebuffer *fb;
  83 + struct drm_framebuffer *saved_fb;
81 84 struct drm_device *dev;
82 85 struct drm_display_mode *mode;
83 86 int crtc_count;
... ... @@ -126,6 +129,8 @@
126 129 bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
127 130 bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
128 131 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
  132 +int drm_fb_helper_debug_enter(struct fb_info *info);
  133 +int drm_fb_helper_debug_leave(struct fb_info *info);
129 134  
130 135 #endif
include/linux/console.h
... ... @@ -55,6 +55,16 @@
55 55 void (*con_invert_region)(struct vc_data *, u16 *, int);
56 56 u16 *(*con_screen_pos)(struct vc_data *, int);
57 57 unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
  58 + /*
  59 + * Prepare the console for the debugger. This includes, but is not
  60 + * limited to, unblanking the console, loading an appropriate
  61 + * palette, and allowing debugger generated output.
  62 + */
  63 + int (*con_debug_enter)(struct vc_data *);
  64 + /*
  65 + * Restore the console to its pre-debug state as closely as possible.
  66 + */
  67 + int (*con_debug_leave)(struct vc_data *);
58 68 };
59 69  
60 70 extern const struct consw *conswitchp;
... ... @@ -69,6 +79,9 @@
69 79 int unregister_con_driver(const struct consw *csw);
70 80 int take_over_console(const struct consw *sw, int first, int last, int deflt);
71 81 void give_up_console(const struct consw *sw);
  82 +int con_debug_enter(struct vc_data *vc);
  83 +int con_debug_leave(void);
  84 +
72 85 /* scroll */
73 86 #define SM_UP (1)
74 87 #define SM_DOWN (2)
... ... @@ -3,6 +3,9 @@
3 3  
4 4 #include <linux/types.h>
5 5 #include <linux/i2c.h>
  6 +#ifdef __KERNEL__
  7 +#include <linux/kgdb.h>
  8 +#endif /* __KERNEL__ */
6 9  
7 10 /* Definitions of frame buffers */
8 11  
... ... @@ -607,6 +610,12 @@
607 610 * LOCKING NOTE: those functions must _ALL_ be called with the console
608 611 * semaphore held, this is the only suitable locking mechanism we have
609 612 * in 2.6. Some may be called at interrupt time at this point though.
  613 + *
  614 + * The exception to this is the debug related hooks. Putting the fb
  615 + * into a debug state (e.g. flipping to the kernel console) and restoring
  616 + * it must be done in a lock-free manner, so low level drivers should
  617 + * keep track of the initial console (if applicable) and may need to
  618 + * perform direct, unlocked hardware writes in these hooks.
610 619 */
611 620  
612 621 struct fb_ops {
... ... @@ -676,6 +685,10 @@
676 685  
677 686 /* teardown any resources to do with this framebuffer */
678 687 void (*fb_destroy)(struct fb_info *info);
  688 +
  689 + /* called at KDB enter and leave time to prepare the console */
  690 + int (*fb_debug_enter)(struct fb_info *info);
  691 + int (*fb_debug_leave)(struct fb_info *info);
679 692 };
680 693  
681 694 #ifdef CONFIG_FB_TILEBLITTING
... ... @@ -114,5 +114,9 @@
114 114 KDB_INIT_EARLY,
115 115 KDB_INIT_FULL,
116 116 };
  117 +
  118 +extern int kdbgetintenv(const char *, int *);
  119 +extern int kdb_set(int, const char **);
  120 +
117 121 #endif /* !_KDB_H */
kernel/debug/kdb/kdb_private.h
... ... @@ -144,9 +144,7 @@
144 144 extern int kdb_putword(unsigned long, unsigned long, size_t);
145 145  
146 146 extern int kdbgetularg(const char *, unsigned long *);
147   -extern int kdb_set(int, const char **);
148 147 extern char *kdbgetenv(const char *);
149   -extern int kdbgetintenv(const char *, int *);
150 148 extern int kdbgetaddrarg(int, const char **, int*, unsigned long *,
151 149 long *, char **);
152 150 extern int kdbgetsymval(const char *, kdb_symtab_t *);