kernel - Fix multiple tty_token issues related to vt switching and X
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 1 Sep 2010 17:56:16 +0000 (10:56 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 1 Sep 2010 17:56:16 +0000 (10:56 -0700)
* Numerous places where gettoken/reltoken was not matched up

* Of particular note the multi-line macros in fbreg.h did not have
  any do/while() protection and were being used in if() macro()
  situations which caused massive issues.

Reported-by: Everyone
sys/dev/misc/kbd/kbd.c
sys/dev/misc/syscons/scvgarndr.c
sys/dev/misc/syscons/syscons.c
sys/dev/video/fb/fbreg.h

index 5babafa..f900119 100644 (file)
@@ -441,6 +441,7 @@ kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func,
        if (index >= 0) {
                if (KBD_IS_BUSY(keyboard[index])) {
                        crit_exit();
+                       lwkt_reltoken(&tty_token);
                        return -1;
                }
                keyboard[index]->kb_token = id;
@@ -1298,8 +1299,10 @@ make_accent_char(keyboard_t *kbd, u_int ch, int *accents)
        for (i = 0; i < NUM_ACCENTCHARS; ++i) {
                if (acc->map[i][0] == 0)        /* end of table */
                        break;
-               if (acc->map[i][0] == ch)
+               if (acc->map[i][0] == ch) {
+                       lwkt_reltoken(&tty_token);
                        return acc->map[i][1];
+               }
        }
        lwkt_reltoken(&tty_token);
        /* this char cannot be accented... */
index 36d959e..2013688 100644 (file)
@@ -236,10 +236,8 @@ draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip)
                        font = sc->font_14;
                        h = 14;
                }
-               if (scp->cursor_base >= h) {
-                       lwkt_reltoken(&tty_token);
+               if (scp->cursor_base >= h)
                        return;
-               }
                if (flip)
                        a = (a & 0x8800)
                                | ((a & 0x7000) >> 4) | ((a & 0x0700) << 4);
index 662c507..7cf4aba 100644 (file)
@@ -1043,6 +1043,7 @@ scioctl(struct dev_ioctl_args *ap)
            break;
        }
        crit_exit();
+       lwkt_reltoken(&tty_token);
        return error;
 
     case VT_OPENQRY:           /* return free virtual console */
@@ -1165,8 +1166,10 @@ scioctl(struct dev_ioctl_args *ap)
        return error;
 
     case KDSETRAD:             /* set keyboard repeat & delay rates (old) */
-       if (*(int *)data & ~0x7f)
+       if (*(int *)data & ~0x7f) {
+           lwkt_reltoken(&tty_token);
            return EINVAL;
+       }
        error = kbd_ioctl(sc->kbd, cmd, data);
        if (error == ENOIOCTL)
            error = ENODEV;
index 144b3a4..02881c2 100644 (file)
@@ -117,27 +117,40 @@ typedef struct video_switch {
 } video_switch_t;
 
 #define save_palette(adp, pal)                         \
-       lwkt_gettoken(&tty_token);                      \
-       (*vidsw[(adp)->va_index]->save_palette)((adp), (pal)); \
-       lwkt_reltoken(&tty_token)
+       do {                                            \
+               lwkt_gettoken(&tty_token);              \
+               (*vidsw[(adp)->va_index]->save_palette)((adp), (pal)); \
+               lwkt_reltoken(&tty_token);              \
+       } while (0)
+
 #define load_palette(adp, pal)                         \
-       lwkt_gettoken(&tty_token);                      \
-       (*vidsw[(adp)->va_index]->load_palette)((adp), (pal)); \
-       lwkt_reltoken(&tty_token)
+       do {                                            \
+               lwkt_gettoken(&tty_token);              \
+               (*vidsw[(adp)->va_index]->load_palette)((adp), (pal)); \
+               lwkt_reltoken(&tty_token);              \
+       } while (0)
+
 #define get_mode_info(adp, mode, buf)                  \
        (*vidsw[(adp)->va_index]->get_info)((adp), (mode), (buf))
+
 #define set_video_mode(adp, mode)                      \
        (*vidsw[(adp)->va_index]->set_mode)((adp), (mode))
+
 #if 0 /* XXX conflicts with syscons' set_border() */
 #define set_border(adp, border)                                \
-       lwkt_gettoken(&tty_token);                      \
-       (*vidsw[(adp)->va_index]->set_border)((adp), (border)); \
-       lwkt_reltoken(&tty_token)
+       do {                                            \
+               lwkt_gettoken(&tty_token);              \
+               (*vidsw[(adp)->va_index]->set_border)((adp), (border)); \
+               lwkt_reltoken(&tty_token);              \
+       } while (0)
 #endif
+
 #define set_origin(adp, o)                             \
-       lwkt_gettoken(&tty_token);                      \
-       (*vidsw[(adp)->va_index]->set_win_org)(adp, o); \
-       lwkt_reltoken(&tty_token)
+       do {                                            \
+               lwkt_gettoken(&tty_token);              \
+               (*vidsw[(adp)->va_index]->set_win_org)(adp, o); \
+               lwkt_reltoken(&tty_token);              \
+       } while (0)
 
 /* XXX - add more macros */