| .. | .. |
|---|
| 49 | 49 | return 0; |
|---|
| 50 | 50 | } |
|---|
| 51 | 51 | |
|---|
| 52 | | -static int kdb_read_get_key(char *buffer, size_t bufsize) |
|---|
| 52 | +/** |
|---|
| 53 | + * kdb_handle_escape() - validity check on an accumulated escape sequence. |
|---|
| 54 | + * @buf: Accumulated escape characters to be examined. Note that buf |
|---|
| 55 | + * is not a string, it is an array of characters and need not be |
|---|
| 56 | + * nil terminated. |
|---|
| 57 | + * @sz: Number of accumulated escape characters. |
|---|
| 58 | + * |
|---|
| 59 | + * Return: -1 if the escape sequence is unwanted, 0 if it is incomplete, |
|---|
| 60 | + * otherwise it returns a mapped key value to pass to the upper layers. |
|---|
| 61 | + */ |
|---|
| 62 | +static int kdb_handle_escape(char *buf, size_t sz) |
|---|
| 63 | +{ |
|---|
| 64 | + char *lastkey = buf + sz - 1; |
|---|
| 65 | + |
|---|
| 66 | + switch (sz) { |
|---|
| 67 | + case 1: |
|---|
| 68 | + if (*lastkey == '\e') |
|---|
| 69 | + return 0; |
|---|
| 70 | + break; |
|---|
| 71 | + |
|---|
| 72 | + case 2: /* \e<something> */ |
|---|
| 73 | + if (*lastkey == '[') |
|---|
| 74 | + return 0; |
|---|
| 75 | + break; |
|---|
| 76 | + |
|---|
| 77 | + case 3: |
|---|
| 78 | + switch (*lastkey) { |
|---|
| 79 | + case 'A': /* \e[A, up arrow */ |
|---|
| 80 | + return 16; |
|---|
| 81 | + case 'B': /* \e[B, down arrow */ |
|---|
| 82 | + return 14; |
|---|
| 83 | + case 'C': /* \e[C, right arrow */ |
|---|
| 84 | + return 6; |
|---|
| 85 | + case 'D': /* \e[D, left arrow */ |
|---|
| 86 | + return 2; |
|---|
| 87 | + case '1': /* \e[<1,3,4>], may be home, del, end */ |
|---|
| 88 | + case '3': |
|---|
| 89 | + case '4': |
|---|
| 90 | + return 0; |
|---|
| 91 | + } |
|---|
| 92 | + break; |
|---|
| 93 | + |
|---|
| 94 | + case 4: |
|---|
| 95 | + if (*lastkey == '~') { |
|---|
| 96 | + switch (buf[2]) { |
|---|
| 97 | + case '1': /* \e[1~, home */ |
|---|
| 98 | + return 1; |
|---|
| 99 | + case '3': /* \e[3~, del */ |
|---|
| 100 | + return 4; |
|---|
| 101 | + case '4': /* \e[4~, end */ |
|---|
| 102 | + return 5; |
|---|
| 103 | + } |
|---|
| 104 | + } |
|---|
| 105 | + break; |
|---|
| 106 | + } |
|---|
| 107 | + |
|---|
| 108 | + return -1; |
|---|
| 109 | +} |
|---|
| 110 | + |
|---|
| 111 | +/** |
|---|
| 112 | + * kdb_getchar() - Read a single character from a kdb console (or consoles). |
|---|
| 113 | + * |
|---|
| 114 | + * Other than polling the various consoles that are currently enabled, |
|---|
| 115 | + * most of the work done in this function is dealing with escape sequences. |
|---|
| 116 | + * |
|---|
| 117 | + * An escape key could be the start of a vt100 control sequence such as \e[D |
|---|
| 118 | + * (left arrow) or it could be a character in its own right. The standard |
|---|
| 119 | + * method for detecting the difference is to wait for 2 seconds to see if there |
|---|
| 120 | + * are any other characters. kdb is complicated by the lack of a timer service |
|---|
| 121 | + * (interrupts are off), by multiple input sources. Escape sequence processing |
|---|
| 122 | + * has to be done as states in the polling loop. |
|---|
| 123 | + * |
|---|
| 124 | + * Return: The key pressed or a control code derived from an escape sequence. |
|---|
| 125 | + */ |
|---|
| 126 | +char kdb_getchar(void) |
|---|
| 53 | 127 | { |
|---|
| 54 | 128 | #define ESCAPE_UDELAY 1000 |
|---|
| 55 | 129 | #define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY) /* 2 seconds worth of udelays */ |
|---|
| 56 | | - char escape_data[5]; /* longest vt100 escape sequence is 4 bytes */ |
|---|
| 57 | | - char *ped = escape_data; |
|---|
| 130 | + char buf[4]; /* longest vt100 escape sequence is 4 bytes */ |
|---|
| 131 | + char *pbuf = buf; |
|---|
| 58 | 132 | int escape_delay = 0; |
|---|
| 59 | | - get_char_func *f, *f_escape = NULL; |
|---|
| 133 | + get_char_func *f, *f_prev = NULL; |
|---|
| 60 | 134 | int key; |
|---|
| 61 | 135 | |
|---|
| 62 | 136 | for (f = &kdb_poll_funcs[0]; ; ++f) { |
|---|
| .. | .. |
|---|
| 65 | 139 | touch_nmi_watchdog(); |
|---|
| 66 | 140 | f = &kdb_poll_funcs[0]; |
|---|
| 67 | 141 | } |
|---|
| 68 | | - if (escape_delay == 2) { |
|---|
| 69 | | - *ped = '\0'; |
|---|
| 70 | | - ped = escape_data; |
|---|
| 71 | | - --escape_delay; |
|---|
| 72 | | - } |
|---|
| 73 | | - if (escape_delay == 1) { |
|---|
| 74 | | - key = *ped++; |
|---|
| 75 | | - if (!*ped) |
|---|
| 76 | | - --escape_delay; |
|---|
| 77 | | - break; |
|---|
| 78 | | - } |
|---|
| 142 | + |
|---|
| 79 | 143 | key = (*f)(); |
|---|
| 80 | 144 | if (key == -1) { |
|---|
| 81 | 145 | if (escape_delay) { |
|---|
| 82 | 146 | udelay(ESCAPE_UDELAY); |
|---|
| 83 | | - --escape_delay; |
|---|
| 147 | + if (--escape_delay == 0) |
|---|
| 148 | + return '\e'; |
|---|
| 84 | 149 | } |
|---|
| 85 | 150 | continue; |
|---|
| 86 | 151 | } |
|---|
| 87 | | - if (bufsize <= 2) { |
|---|
| 88 | | - if (key == '\r') |
|---|
| 89 | | - key = '\n'; |
|---|
| 90 | | - *buffer++ = key; |
|---|
| 91 | | - *buffer = '\0'; |
|---|
| 92 | | - return -1; |
|---|
| 93 | | - } |
|---|
| 94 | | - if (escape_delay == 0 && key == '\e') { |
|---|
| 152 | + |
|---|
| 153 | + /* |
|---|
| 154 | + * When the first character is received (or we get a change |
|---|
| 155 | + * input source) we set ourselves up to handle an escape |
|---|
| 156 | + * sequences (just in case). |
|---|
| 157 | + */ |
|---|
| 158 | + if (f_prev != f) { |
|---|
| 159 | + f_prev = f; |
|---|
| 160 | + pbuf = buf; |
|---|
| 95 | 161 | escape_delay = ESCAPE_DELAY; |
|---|
| 96 | | - ped = escape_data; |
|---|
| 97 | | - f_escape = f; |
|---|
| 98 | 162 | } |
|---|
| 99 | | - if (escape_delay) { |
|---|
| 100 | | - *ped++ = key; |
|---|
| 101 | | - if (f_escape != f) { |
|---|
| 102 | | - escape_delay = 2; |
|---|
| 103 | | - continue; |
|---|
| 104 | | - } |
|---|
| 105 | | - if (ped - escape_data == 1) { |
|---|
| 106 | | - /* \e */ |
|---|
| 107 | | - continue; |
|---|
| 108 | | - } else if (ped - escape_data == 2) { |
|---|
| 109 | | - /* \e<something> */ |
|---|
| 110 | | - if (key != '[') |
|---|
| 111 | | - escape_delay = 2; |
|---|
| 112 | | - continue; |
|---|
| 113 | | - } else if (ped - escape_data == 3) { |
|---|
| 114 | | - /* \e[<something> */ |
|---|
| 115 | | - int mapkey = 0; |
|---|
| 116 | | - switch (key) { |
|---|
| 117 | | - case 'A': /* \e[A, up arrow */ |
|---|
| 118 | | - mapkey = 16; |
|---|
| 119 | | - break; |
|---|
| 120 | | - case 'B': /* \e[B, down arrow */ |
|---|
| 121 | | - mapkey = 14; |
|---|
| 122 | | - break; |
|---|
| 123 | | - case 'C': /* \e[C, right arrow */ |
|---|
| 124 | | - mapkey = 6; |
|---|
| 125 | | - break; |
|---|
| 126 | | - case 'D': /* \e[D, left arrow */ |
|---|
| 127 | | - mapkey = 2; |
|---|
| 128 | | - break; |
|---|
| 129 | | - case '1': /* dropthrough */ |
|---|
| 130 | | - case '3': /* dropthrough */ |
|---|
| 131 | | - /* \e[<1,3,4>], may be home, del, end */ |
|---|
| 132 | | - case '4': |
|---|
| 133 | | - mapkey = -1; |
|---|
| 134 | | - break; |
|---|
| 135 | | - } |
|---|
| 136 | | - if (mapkey != -1) { |
|---|
| 137 | | - if (mapkey > 0) { |
|---|
| 138 | | - escape_data[0] = mapkey; |
|---|
| 139 | | - escape_data[1] = '\0'; |
|---|
| 140 | | - } |
|---|
| 141 | | - escape_delay = 2; |
|---|
| 142 | | - } |
|---|
| 143 | | - continue; |
|---|
| 144 | | - } else if (ped - escape_data == 4) { |
|---|
| 145 | | - /* \e[<1,3,4><something> */ |
|---|
| 146 | | - int mapkey = 0; |
|---|
| 147 | | - if (key == '~') { |
|---|
| 148 | | - switch (escape_data[2]) { |
|---|
| 149 | | - case '1': /* \e[1~, home */ |
|---|
| 150 | | - mapkey = 1; |
|---|
| 151 | | - break; |
|---|
| 152 | | - case '3': /* \e[3~, del */ |
|---|
| 153 | | - mapkey = 4; |
|---|
| 154 | | - break; |
|---|
| 155 | | - case '4': /* \e[4~, end */ |
|---|
| 156 | | - mapkey = 5; |
|---|
| 157 | | - break; |
|---|
| 158 | | - } |
|---|
| 159 | | - } |
|---|
| 160 | | - if (mapkey > 0) { |
|---|
| 161 | | - escape_data[0] = mapkey; |
|---|
| 162 | | - escape_data[1] = '\0'; |
|---|
| 163 | | - } |
|---|
| 164 | | - escape_delay = 2; |
|---|
| 165 | | - continue; |
|---|
| 166 | | - } |
|---|
| 167 | | - } |
|---|
| 168 | | - break; /* A key to process */ |
|---|
| 163 | + |
|---|
| 164 | + *pbuf++ = key; |
|---|
| 165 | + key = kdb_handle_escape(buf, pbuf - buf); |
|---|
| 166 | + if (key < 0) /* no escape sequence; return best character */ |
|---|
| 167 | + return buf[pbuf - buf == 2 ? 1 : 0]; |
|---|
| 168 | + if (key > 0) |
|---|
| 169 | + return key; |
|---|
| 169 | 170 | } |
|---|
| 170 | | - return key; |
|---|
| 171 | + |
|---|
| 172 | + unreachable(); |
|---|
| 171 | 173 | } |
|---|
| 172 | 174 | |
|---|
| 173 | 175 | /* |
|---|
| .. | .. |
|---|
| 188 | 190 | * function. It is not reentrant - it relies on the fact |
|---|
| 189 | 191 | * that while kdb is running on only one "master debug" cpu. |
|---|
| 190 | 192 | * Remarks: |
|---|
| 191 | | - * |
|---|
| 192 | | - * The buffer size must be >= 2. A buffer size of 2 means that the caller only |
|---|
| 193 | | - * wants a single key. |
|---|
| 194 | | - * |
|---|
| 195 | | - * An escape key could be the start of a vt100 control sequence such as \e[D |
|---|
| 196 | | - * (left arrow) or it could be a character in its own right. The standard |
|---|
| 197 | | - * method for detecting the difference is to wait for 2 seconds to see if there |
|---|
| 198 | | - * are any other characters. kdb is complicated by the lack of a timer service |
|---|
| 199 | | - * (interrupts are off), by multiple input sources and by the need to sometimes |
|---|
| 200 | | - * return after just one key. Escape sequence processing has to be done as |
|---|
| 201 | | - * states in the polling loop. |
|---|
| 193 | + * The buffer size must be >= 2. |
|---|
| 202 | 194 | */ |
|---|
| 203 | 195 | |
|---|
| 204 | 196 | static char *kdb_read(char *buffer, size_t bufsize) |
|---|
| .. | .. |
|---|
| 233 | 225 | *cp = '\0'; |
|---|
| 234 | 226 | kdb_printf("%s", buffer); |
|---|
| 235 | 227 | poll_again: |
|---|
| 236 | | - key = kdb_read_get_key(buffer, bufsize); |
|---|
| 237 | | - if (key == -1) |
|---|
| 238 | | - return buffer; |
|---|
| 228 | + key = kdb_getchar(); |
|---|
| 239 | 229 | if (key != 9) |
|---|
| 240 | 230 | tab = 0; |
|---|
| 241 | 231 | switch (key) { |
|---|
| .. | .. |
|---|
| 446 | 436 | char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt) |
|---|
| 447 | 437 | { |
|---|
| 448 | 438 | if (prompt && kdb_prompt_str != prompt) |
|---|
| 449 | | - strncpy(kdb_prompt_str, prompt, CMD_BUFLEN); |
|---|
| 439 | + strscpy(kdb_prompt_str, prompt, CMD_BUFLEN); |
|---|
| 450 | 440 | kdb_printf(kdb_prompt_str); |
|---|
| 451 | 441 | kdb_nextline = 1; /* Prompt and input resets line number */ |
|---|
| 452 | 442 | return kdb_read(buffer, bufsize); |
|---|
| .. | .. |
|---|
| 552 | 542 | return 0; |
|---|
| 553 | 543 | } |
|---|
| 554 | 544 | |
|---|
| 545 | +static void kdb_msg_write(const char *msg, int msg_len) |
|---|
| 546 | +{ |
|---|
| 547 | + struct console *c; |
|---|
| 548 | + const char *cp; |
|---|
| 549 | + int len; |
|---|
| 550 | + |
|---|
| 551 | + if (msg_len == 0) |
|---|
| 552 | + return; |
|---|
| 553 | + |
|---|
| 554 | + cp = msg; |
|---|
| 555 | + len = msg_len; |
|---|
| 556 | + |
|---|
| 557 | + while (len--) { |
|---|
| 558 | + dbg_io_ops->write_char(*cp); |
|---|
| 559 | + cp++; |
|---|
| 560 | + } |
|---|
| 561 | + |
|---|
| 562 | + for_each_console(c) { |
|---|
| 563 | + if (!(c->flags & CON_ENABLED)) |
|---|
| 564 | + continue; |
|---|
| 565 | + if (c == dbg_io_ops->cons) |
|---|
| 566 | + continue; |
|---|
| 567 | + /* |
|---|
| 568 | + * Set oops_in_progress to encourage the console drivers to |
|---|
| 569 | + * disregard their internal spin locks: in the current calling |
|---|
| 570 | + * context the risk of deadlock is a bigger problem than risks |
|---|
| 571 | + * due to re-entering the console driver. We operate directly on |
|---|
| 572 | + * oops_in_progress rather than using bust_spinlocks() because |
|---|
| 573 | + * the calls bust_spinlocks() makes on exit are not appropriate |
|---|
| 574 | + * for this calling context. |
|---|
| 575 | + */ |
|---|
| 576 | + ++oops_in_progress; |
|---|
| 577 | + c->write(c, msg, msg_len); |
|---|
| 578 | + --oops_in_progress; |
|---|
| 579 | + touch_nmi_watchdog(); |
|---|
| 580 | + } |
|---|
| 581 | +} |
|---|
| 582 | + |
|---|
| 555 | 583 | int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) |
|---|
| 556 | 584 | { |
|---|
| 557 | 585 | int diag; |
|---|
| .. | .. |
|---|
| 563 | 591 | int this_cpu, old_cpu; |
|---|
| 564 | 592 | char *cp, *cp2, *cphold = NULL, replaced_byte = ' '; |
|---|
| 565 | 593 | char *moreprompt = "more> "; |
|---|
| 566 | | - struct console *c = console_drivers; |
|---|
| 567 | | - unsigned long uninitialized_var(flags); |
|---|
| 594 | + unsigned long flags; |
|---|
| 568 | 595 | |
|---|
| 569 | 596 | /* Serialize kdb_printf if multiple cpus try to write at once. |
|---|
| 570 | 597 | * But if any cpu goes recursive in kdb, just print the output, |
|---|
| .. | .. |
|---|
| 701 | 728 | */ |
|---|
| 702 | 729 | retlen = strlen(kdb_buffer); |
|---|
| 703 | 730 | cp = (char *) printk_skip_headers(kdb_buffer); |
|---|
| 704 | | - if (!dbg_kdb_mode && kgdb_connected) { |
|---|
| 731 | + if (!dbg_kdb_mode && kgdb_connected) |
|---|
| 705 | 732 | gdbstub_msg_write(cp, retlen - (cp - kdb_buffer)); |
|---|
| 706 | | - } else { |
|---|
| 707 | | - if (dbg_io_ops && !dbg_io_ops->is_console) { |
|---|
| 708 | | - len = retlen - (cp - kdb_buffer); |
|---|
| 709 | | - cp2 = cp; |
|---|
| 710 | | - while (len--) { |
|---|
| 711 | | - dbg_io_ops->write_char(*cp2); |
|---|
| 712 | | - cp2++; |
|---|
| 713 | | - } |
|---|
| 714 | | - } |
|---|
| 715 | | - while (c) { |
|---|
| 716 | | - c->write(c, cp, retlen - (cp - kdb_buffer)); |
|---|
| 717 | | - touch_nmi_watchdog(); |
|---|
| 718 | | - c = c->next; |
|---|
| 719 | | - } |
|---|
| 720 | | - } |
|---|
| 733 | + else |
|---|
| 734 | + kdb_msg_write(cp, retlen - (cp - kdb_buffer)); |
|---|
| 735 | + |
|---|
| 721 | 736 | if (logging) { |
|---|
| 722 | 737 | saved_loglevel = console_loglevel; |
|---|
| 723 | 738 | console_loglevel = CONSOLE_LOGLEVEL_SILENT; |
|---|
| .. | .. |
|---|
| 750 | 765 | |
|---|
| 751 | 766 | /* check for having reached the LINES number of printed lines */ |
|---|
| 752 | 767 | if (kdb_nextline >= linecount) { |
|---|
| 753 | | - char buf1[16] = ""; |
|---|
| 768 | + char ch; |
|---|
| 754 | 769 | |
|---|
| 755 | 770 | /* Watch out for recursion here. Any routine that calls |
|---|
| 756 | 771 | * kdb_printf will come back through here. And kdb_read |
|---|
| .. | .. |
|---|
| 766 | 781 | moreprompt = "more> "; |
|---|
| 767 | 782 | |
|---|
| 768 | 783 | kdb_input_flush(); |
|---|
| 769 | | - c = console_drivers; |
|---|
| 770 | | - |
|---|
| 771 | | - if (dbg_io_ops && !dbg_io_ops->is_console) { |
|---|
| 772 | | - len = strlen(moreprompt); |
|---|
| 773 | | - cp = moreprompt; |
|---|
| 774 | | - while (len--) { |
|---|
| 775 | | - dbg_io_ops->write_char(*cp); |
|---|
| 776 | | - cp++; |
|---|
| 777 | | - } |
|---|
| 778 | | - } |
|---|
| 779 | | - while (c) { |
|---|
| 780 | | - c->write(c, moreprompt, strlen(moreprompt)); |
|---|
| 781 | | - touch_nmi_watchdog(); |
|---|
| 782 | | - c = c->next; |
|---|
| 783 | | - } |
|---|
| 784 | + kdb_msg_write(moreprompt, strlen(moreprompt)); |
|---|
| 784 | 785 | |
|---|
| 785 | 786 | if (logging) |
|---|
| 786 | 787 | printk("%s", moreprompt); |
|---|
| 787 | 788 | |
|---|
| 788 | | - kdb_read(buf1, 2); /* '2' indicates to return |
|---|
| 789 | | - * immediately after getting one key. */ |
|---|
| 789 | + ch = kdb_getchar(); |
|---|
| 790 | 790 | kdb_nextline = 1; /* Really set output line 1 */ |
|---|
| 791 | 791 | |
|---|
| 792 | 792 | /* empty and reset the buffer: */ |
|---|
| 793 | 793 | kdb_buffer[0] = '\0'; |
|---|
| 794 | 794 | next_avail = kdb_buffer; |
|---|
| 795 | 795 | size_avail = sizeof(kdb_buffer); |
|---|
| 796 | | - if ((buf1[0] == 'q') || (buf1[0] == 'Q')) { |
|---|
| 796 | + if ((ch == 'q') || (ch == 'Q')) { |
|---|
| 797 | 797 | /* user hit q or Q */ |
|---|
| 798 | 798 | KDB_FLAG_SET(CMD_INTERRUPT); /* command interrupted */ |
|---|
| 799 | 799 | KDB_STATE_CLEAR(PAGER); |
|---|
| 800 | 800 | /* end of command output; back to normal mode */ |
|---|
| 801 | 801 | kdb_grepping_flag = 0; |
|---|
| 802 | 802 | kdb_printf("\n"); |
|---|
| 803 | | - } else if (buf1[0] == ' ') { |
|---|
| 803 | + } else if (ch == ' ') { |
|---|
| 804 | 804 | kdb_printf("\r"); |
|---|
| 805 | 805 | suspend_grep = 1; /* for this recursion */ |
|---|
| 806 | | - } else if (buf1[0] == '\n') { |
|---|
| 806 | + } else if (ch == '\n' || ch == '\r') { |
|---|
| 807 | 807 | kdb_nextline = linecount - 1; |
|---|
| 808 | 808 | kdb_printf("\r"); |
|---|
| 809 | 809 | suspend_grep = 1; /* for this recursion */ |
|---|
| 810 | | - } else if (buf1[0] == '/' && !kdb_grepping_flag) { |
|---|
| 810 | + } else if (ch == '/' && !kdb_grepping_flag) { |
|---|
| 811 | 811 | kdb_printf("\r"); |
|---|
| 812 | 812 | kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN, |
|---|
| 813 | 813 | kdbgetenv("SEARCHPROMPT") ?: "search> "); |
|---|
| 814 | 814 | *strchrnul(kdb_grep_string, '\n') = '\0'; |
|---|
| 815 | 815 | kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH; |
|---|
| 816 | 816 | suspend_grep = 1; /* for this recursion */ |
|---|
| 817 | | - } else if (buf1[0] && buf1[0] != '\n') { |
|---|
| 818 | | - /* user hit something other than enter */ |
|---|
| 817 | + } else if (ch) { |
|---|
| 818 | + /* user hit something unexpected */ |
|---|
| 819 | 819 | suspend_grep = 1; /* for this recursion */ |
|---|
| 820 | | - if (buf1[0] != '/') |
|---|
| 820 | + if (ch != '/') |
|---|
| 821 | 821 | kdb_printf( |
|---|
| 822 | 822 | "\nOnly 'q', 'Q' or '/' are processed at " |
|---|
| 823 | 823 | "more prompt, input ignored\n"); |
|---|
| .. | .. |
|---|
| 861 | 861 | va_list ap; |
|---|
| 862 | 862 | int r; |
|---|
| 863 | 863 | |
|---|
| 864 | | - kdb_trap_printk++; |
|---|
| 865 | 864 | va_start(ap, fmt); |
|---|
| 866 | 865 | r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap); |
|---|
| 867 | 866 | va_end(ap); |
|---|
| 868 | | - kdb_trap_printk--; |
|---|
| 869 | 867 | |
|---|
| 870 | 868 | return r; |
|---|
| 871 | 869 | } |
|---|