15d5314d6SJason Wessel /* 25d5314d6SJason Wessel * Kernel Debugger Architecture Independent Console I/O handler 35d5314d6SJason Wessel * 45d5314d6SJason Wessel * This file is subject to the terms and conditions of the GNU General Public 55d5314d6SJason Wessel * License. See the file "COPYING" in the main directory of this archive 65d5314d6SJason Wessel * for more details. 75d5314d6SJason Wessel * 85d5314d6SJason Wessel * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. 95d5314d6SJason Wessel * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. 105d5314d6SJason Wessel */ 115d5314d6SJason Wessel 125d5314d6SJason Wessel #include <linux/module.h> 135d5314d6SJason Wessel #include <linux/types.h> 145d5314d6SJason Wessel #include <linux/ctype.h> 155d5314d6SJason Wessel #include <linux/kernel.h> 165d5314d6SJason Wessel #include <linux/init.h> 175d5314d6SJason Wessel #include <linux/kdev_t.h> 185d5314d6SJason Wessel #include <linux/console.h> 195d5314d6SJason Wessel #include <linux/string.h> 205d5314d6SJason Wessel #include <linux/sched.h> 215d5314d6SJason Wessel #include <linux/smp.h> 225d5314d6SJason Wessel #include <linux/nmi.h> 235d5314d6SJason Wessel #include <linux/delay.h> 24a0de055cSJason Wessel #include <linux/kgdb.h> 255d5314d6SJason Wessel #include <linux/kdb.h> 265d5314d6SJason Wessel #include <linux/kallsyms.h> 275d5314d6SJason Wessel #include "kdb_private.h" 285d5314d6SJason Wessel 295d5314d6SJason Wessel #define CMD_BUFLEN 256 305d5314d6SJason Wessel char kdb_prompt_str[CMD_BUFLEN]; 315d5314d6SJason Wessel 32d37d39aeSJason Wessel int kdb_trap_printk; 3334aaff40SPetr Mladek int kdb_printf_cpu = -1; 345d5314d6SJason Wessel 3537f86b46SJason Wessel static int kgdb_transition_check(char *buffer) 365d5314d6SJason Wessel { 3737f86b46SJason Wessel if (buffer[0] != '+' && buffer[0] != '$') { 385d5314d6SJason Wessel KDB_STATE_SET(KGDB_TRANS); 395d5314d6SJason Wessel kdb_printf("%s", buffer); 4037f86b46SJason Wessel } else { 4137f86b46SJason Wessel int slen = strlen(buffer); 4237f86b46SJason Wessel if (slen > 3 && buffer[slen - 3] == '#') { 4337f86b46SJason Wessel kdb_gdb_state_pass(buffer); 4437f86b46SJason Wessel strcpy(buffer, "kgdb"); 4537f86b46SJason Wessel KDB_STATE_SET(DOING_KGDB); 4637f86b46SJason Wessel return 1; 475d5314d6SJason Wessel } 485d5314d6SJason Wessel } 4937f86b46SJason Wessel return 0; 5037f86b46SJason Wessel } 515d5314d6SJason Wessel 5253b63136SDaniel Thompson /** 5353b63136SDaniel Thompson * kdb_handle_escape() - validity check on an accumulated escape sequence. 5453b63136SDaniel Thompson * @buf: Accumulated escape characters to be examined. Note that buf 5553b63136SDaniel Thompson * is not a string, it is an array of characters and need not be 5653b63136SDaniel Thompson * nil terminated. 5753b63136SDaniel Thompson * @sz: Number of accumulated escape characters. 5853b63136SDaniel Thompson * 5953b63136SDaniel Thompson * Return: -1 if the escape sequence is unwanted, 0 if it is incomplete, 6053b63136SDaniel Thompson * otherwise it returns a mapped key value to pass to the upper layers. 6153b63136SDaniel Thompson */ 6253b63136SDaniel Thompson static int kdb_handle_escape(char *buf, size_t sz) 6353b63136SDaniel Thompson { 6453b63136SDaniel Thompson char *lastkey = buf + sz - 1; 6553b63136SDaniel Thompson 6653b63136SDaniel Thompson switch (sz) { 6753b63136SDaniel Thompson case 1: 6853b63136SDaniel Thompson if (*lastkey == '\e') 6953b63136SDaniel Thompson return 0; 7053b63136SDaniel Thompson break; 7153b63136SDaniel Thompson 7253b63136SDaniel Thompson case 2: /* \e<something> */ 7353b63136SDaniel Thompson if (*lastkey == '[') 7453b63136SDaniel Thompson return 0; 7553b63136SDaniel Thompson break; 7653b63136SDaniel Thompson 7753b63136SDaniel Thompson case 3: 7853b63136SDaniel Thompson switch (*lastkey) { 7953b63136SDaniel Thompson case 'A': /* \e[A, up arrow */ 8053b63136SDaniel Thompson return 16; 8153b63136SDaniel Thompson case 'B': /* \e[B, down arrow */ 8253b63136SDaniel Thompson return 14; 8353b63136SDaniel Thompson case 'C': /* \e[C, right arrow */ 8453b63136SDaniel Thompson return 6; 8553b63136SDaniel Thompson case 'D': /* \e[D, left arrow */ 8653b63136SDaniel Thompson return 2; 8753b63136SDaniel Thompson case '1': /* \e[<1,3,4>], may be home, del, end */ 8853b63136SDaniel Thompson case '3': 8953b63136SDaniel Thompson case '4': 9053b63136SDaniel Thompson return 0; 9153b63136SDaniel Thompson } 9253b63136SDaniel Thompson break; 9353b63136SDaniel Thompson 9453b63136SDaniel Thompson case 4: 9553b63136SDaniel Thompson if (*lastkey == '~') { 9653b63136SDaniel Thompson switch (buf[2]) { 9753b63136SDaniel Thompson case '1': /* \e[1~, home */ 9853b63136SDaniel Thompson return 1; 9953b63136SDaniel Thompson case '3': /* \e[3~, del */ 10053b63136SDaniel Thompson return 4; 10153b63136SDaniel Thompson case '4': /* \e[4~, end */ 10253b63136SDaniel Thompson return 5; 10353b63136SDaniel Thompson } 10453b63136SDaniel Thompson } 10553b63136SDaniel Thompson break; 10653b63136SDaniel Thompson } 10753b63136SDaniel Thompson 10853b63136SDaniel Thompson return -1; 10953b63136SDaniel Thompson } 11053b63136SDaniel Thompson 1114f27e824SDaniel Thompson /** 1124f27e824SDaniel Thompson * kdb_getchar() - Read a single character from a kdb console (or consoles). 1134f27e824SDaniel Thompson * 1144f27e824SDaniel Thompson * Other than polling the various consoles that are currently enabled, 1154f27e824SDaniel Thompson * most of the work done in this function is dealing with escape sequences. 1164f27e824SDaniel Thompson * 1174f27e824SDaniel Thompson * An escape key could be the start of a vt100 control sequence such as \e[D 1184f27e824SDaniel Thompson * (left arrow) or it could be a character in its own right. The standard 1194f27e824SDaniel Thompson * method for detecting the difference is to wait for 2 seconds to see if there 1204f27e824SDaniel Thompson * are any other characters. kdb is complicated by the lack of a timer service 1214f27e824SDaniel Thompson * (interrupts are off), by multiple input sources. Escape sequence processing 1224f27e824SDaniel Thompson * has to be done as states in the polling loop. 1234f27e824SDaniel Thompson * 1244f27e824SDaniel Thompson * Return: The key pressed or a control code derived from an escape sequence. 1254f27e824SDaniel Thompson */ 1264f27e824SDaniel Thompson char kdb_getchar(void) 1275d5314d6SJason Wessel { 1285d5314d6SJason Wessel #define ESCAPE_UDELAY 1000 1295d5314d6SJason Wessel #define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY) /* 2 seconds worth of udelays */ 130cdca8d89SDaniel Thompson char buf[4]; /* longest vt100 escape sequence is 4 bytes */ 131cdca8d89SDaniel Thompson char *pbuf = buf; 1325d5314d6SJason Wessel int escape_delay = 0; 133cdca8d89SDaniel Thompson get_char_func *f, *f_prev = NULL; 1345d5314d6SJason Wessel int key; 1355d5314d6SJason Wessel 1365d5314d6SJason Wessel for (f = &kdb_poll_funcs[0]; ; ++f) { 1375d5314d6SJason Wessel if (*f == NULL) { 1385d5314d6SJason Wessel /* Reset NMI watchdog once per poll loop */ 1395d5314d6SJason Wessel touch_nmi_watchdog(); 1405d5314d6SJason Wessel f = &kdb_poll_funcs[0]; 1415d5314d6SJason Wessel } 142d04213afSDaniel Thompson 1435d5314d6SJason Wessel key = (*f)(); 1445d5314d6SJason Wessel if (key == -1) { 1455d5314d6SJason Wessel if (escape_delay) { 1465d5314d6SJason Wessel udelay(ESCAPE_UDELAY); 147d04213afSDaniel Thompson if (--escape_delay == 0) 148d04213afSDaniel Thompson return '\e'; 1495d5314d6SJason Wessel } 1505d5314d6SJason Wessel continue; 1515d5314d6SJason Wessel } 152d04213afSDaniel Thompson 153cdca8d89SDaniel Thompson /* 154cdca8d89SDaniel Thompson * When the first character is received (or we get a change 155cdca8d89SDaniel Thompson * input source) we set ourselves up to handle an escape 156cdca8d89SDaniel Thompson * sequences (just in case). 157cdca8d89SDaniel Thompson */ 158cdca8d89SDaniel Thompson if (f_prev != f) { 159cdca8d89SDaniel Thompson f_prev = f; 160cdca8d89SDaniel Thompson pbuf = buf; 1615d5314d6SJason Wessel escape_delay = ESCAPE_DELAY; 1625d5314d6SJason Wessel } 16353b63136SDaniel Thompson 164cdca8d89SDaniel Thompson *pbuf++ = key; 165cdca8d89SDaniel Thompson key = kdb_handle_escape(buf, pbuf - buf); 166c58ff643SDaniel Thompson if (key < 0) /* no escape sequence; return best character */ 167c58ff643SDaniel Thompson return buf[pbuf - buf == 2 ? 1 : 0]; 168cdca8d89SDaniel Thompson if (key > 0) 1695d5314d6SJason Wessel return key; 1705d5314d6SJason Wessel } 1715d5314d6SJason Wessel 172cdca8d89SDaniel Thompson unreachable(); 173cdca8d89SDaniel Thompson } 174cdca8d89SDaniel Thompson 1755d5314d6SJason Wessel /* 1765d5314d6SJason Wessel * kdb_read 1775d5314d6SJason Wessel * 1785d5314d6SJason Wessel * This function reads a string of characters, terminated by 1795d5314d6SJason Wessel * a newline, or by reaching the end of the supplied buffer, 1805d5314d6SJason Wessel * from the current kernel debugger console device. 1815d5314d6SJason Wessel * Parameters: 1825d5314d6SJason Wessel * buffer - Address of character buffer to receive input characters. 1835d5314d6SJason Wessel * bufsize - size, in bytes, of the character buffer 1845d5314d6SJason Wessel * Returns: 1855d5314d6SJason Wessel * Returns a pointer to the buffer containing the received 1865d5314d6SJason Wessel * character string. This string will be terminated by a 1875d5314d6SJason Wessel * newline character. 1885d5314d6SJason Wessel * Locking: 1895d5314d6SJason Wessel * No locks are required to be held upon entry to this 1905d5314d6SJason Wessel * function. It is not reentrant - it relies on the fact 1915d5314d6SJason Wessel * that while kdb is running on only one "master debug" cpu. 1925d5314d6SJason Wessel * Remarks: 1934f27e824SDaniel Thompson * The buffer size must be >= 2. 1945d5314d6SJason Wessel */ 1955d5314d6SJason Wessel 1965d5314d6SJason Wessel static char *kdb_read(char *buffer, size_t bufsize) 1975d5314d6SJason Wessel { 1985d5314d6SJason Wessel char *cp = buffer; 1995d5314d6SJason Wessel char *bufend = buffer+bufsize-2; /* Reserve space for newline 2005d5314d6SJason Wessel * and null byte */ 2015d5314d6SJason Wessel char *lastchar; 2025d5314d6SJason Wessel char *p_tmp; 2035d5314d6SJason Wessel char tmp; 2045d5314d6SJason Wessel static char tmpbuffer[CMD_BUFLEN]; 2055d5314d6SJason Wessel int len = strlen(buffer); 2065d5314d6SJason Wessel int len_tmp; 2075d5314d6SJason Wessel int tab = 0; 2085d5314d6SJason Wessel int count; 2095d5314d6SJason Wessel int i; 2105d5314d6SJason Wessel int diag, dtab_count; 211c2b94c72SPrarit Bhargava int key, buf_size, ret; 2125d5314d6SJason Wessel 2135d5314d6SJason Wessel 2145d5314d6SJason Wessel diag = kdbgetintenv("DTABCOUNT", &dtab_count); 2155d5314d6SJason Wessel if (diag) 2165d5314d6SJason Wessel dtab_count = 30; 2175d5314d6SJason Wessel 2185d5314d6SJason Wessel if (len > 0) { 2195d5314d6SJason Wessel cp += len; 2205d5314d6SJason Wessel if (*(buffer+len-1) == '\n') 2215d5314d6SJason Wessel cp--; 2225d5314d6SJason Wessel } 2235d5314d6SJason Wessel 2245d5314d6SJason Wessel lastchar = cp; 2255d5314d6SJason Wessel *cp = '\0'; 2265d5314d6SJason Wessel kdb_printf("%s", buffer); 2275d5314d6SJason Wessel poll_again: 2284f27e824SDaniel Thompson key = kdb_getchar(); 2295d5314d6SJason Wessel if (key != 9) 2305d5314d6SJason Wessel tab = 0; 2315d5314d6SJason Wessel switch (key) { 2325d5314d6SJason Wessel case 8: /* backspace */ 2335d5314d6SJason Wessel if (cp > buffer) { 2345d5314d6SJason Wessel if (cp < lastchar) { 2355d5314d6SJason Wessel memcpy(tmpbuffer, cp, lastchar - cp); 2365d5314d6SJason Wessel memcpy(cp-1, tmpbuffer, lastchar - cp); 2375d5314d6SJason Wessel } 2385d5314d6SJason Wessel *(--lastchar) = '\0'; 2395d5314d6SJason Wessel --cp; 2405d5314d6SJason Wessel kdb_printf("\b%s \r", cp); 2415d5314d6SJason Wessel tmp = *cp; 2425d5314d6SJason Wessel *cp = '\0'; 2435d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 2445d5314d6SJason Wessel kdb_printf("%s", buffer); 2455d5314d6SJason Wessel *cp = tmp; 2465d5314d6SJason Wessel } 2475d5314d6SJason Wessel break; 2485d5314d6SJason Wessel case 13: /* enter */ 2495d5314d6SJason Wessel *lastchar++ = '\n'; 2505d5314d6SJason Wessel *lastchar++ = '\0'; 25137f86b46SJason Wessel if (!KDB_STATE(KGDB_TRANS)) { 25237f86b46SJason Wessel KDB_STATE_SET(KGDB_TRANS); 25337f86b46SJason Wessel kdb_printf("%s", buffer); 25437f86b46SJason Wessel } 2555d5314d6SJason Wessel kdb_printf("\n"); 2565d5314d6SJason Wessel return buffer; 2575d5314d6SJason Wessel case 4: /* Del */ 2585d5314d6SJason Wessel if (cp < lastchar) { 2595d5314d6SJason Wessel memcpy(tmpbuffer, cp+1, lastchar - cp - 1); 2605d5314d6SJason Wessel memcpy(cp, tmpbuffer, lastchar - cp - 1); 2615d5314d6SJason Wessel *(--lastchar) = '\0'; 2625d5314d6SJason Wessel kdb_printf("%s \r", cp); 2635d5314d6SJason Wessel tmp = *cp; 2645d5314d6SJason Wessel *cp = '\0'; 2655d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 2665d5314d6SJason Wessel kdb_printf("%s", buffer); 2675d5314d6SJason Wessel *cp = tmp; 2685d5314d6SJason Wessel } 2695d5314d6SJason Wessel break; 2705d5314d6SJason Wessel case 1: /* Home */ 2715d5314d6SJason Wessel if (cp > buffer) { 2725d5314d6SJason Wessel kdb_printf("\r"); 2735d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 2745d5314d6SJason Wessel cp = buffer; 2755d5314d6SJason Wessel } 2765d5314d6SJason Wessel break; 2775d5314d6SJason Wessel case 5: /* End */ 2785d5314d6SJason Wessel if (cp < lastchar) { 2795d5314d6SJason Wessel kdb_printf("%s", cp); 2805d5314d6SJason Wessel cp = lastchar; 2815d5314d6SJason Wessel } 2825d5314d6SJason Wessel break; 2835d5314d6SJason Wessel case 2: /* Left */ 2845d5314d6SJason Wessel if (cp > buffer) { 2855d5314d6SJason Wessel kdb_printf("\b"); 2865d5314d6SJason Wessel --cp; 2875d5314d6SJason Wessel } 2885d5314d6SJason Wessel break; 2895d5314d6SJason Wessel case 14: /* Down */ 2905d5314d6SJason Wessel memset(tmpbuffer, ' ', 2915d5314d6SJason Wessel strlen(kdb_prompt_str) + (lastchar-buffer)); 2925d5314d6SJason Wessel *(tmpbuffer+strlen(kdb_prompt_str) + 2935d5314d6SJason Wessel (lastchar-buffer)) = '\0'; 2945d5314d6SJason Wessel kdb_printf("\r%s\r", tmpbuffer); 2955d5314d6SJason Wessel *lastchar = (char)key; 2965d5314d6SJason Wessel *(lastchar+1) = '\0'; 2975d5314d6SJason Wessel return lastchar; 2985d5314d6SJason Wessel case 6: /* Right */ 2995d5314d6SJason Wessel if (cp < lastchar) { 3005d5314d6SJason Wessel kdb_printf("%c", *cp); 3015d5314d6SJason Wessel ++cp; 3025d5314d6SJason Wessel } 3035d5314d6SJason Wessel break; 3045d5314d6SJason Wessel case 16: /* Up */ 3055d5314d6SJason Wessel memset(tmpbuffer, ' ', 3065d5314d6SJason Wessel strlen(kdb_prompt_str) + (lastchar-buffer)); 3075d5314d6SJason Wessel *(tmpbuffer+strlen(kdb_prompt_str) + 3085d5314d6SJason Wessel (lastchar-buffer)) = '\0'; 3095d5314d6SJason Wessel kdb_printf("\r%s\r", tmpbuffer); 3105d5314d6SJason Wessel *lastchar = (char)key; 3115d5314d6SJason Wessel *(lastchar+1) = '\0'; 3125d5314d6SJason Wessel return lastchar; 3135d5314d6SJason Wessel case 9: /* Tab */ 3145d5314d6SJason Wessel if (tab < 2) 3155d5314d6SJason Wessel ++tab; 3165d5314d6SJason Wessel p_tmp = buffer; 3175d5314d6SJason Wessel while (*p_tmp == ' ') 3185d5314d6SJason Wessel p_tmp++; 3195d5314d6SJason Wessel if (p_tmp > cp) 3205d5314d6SJason Wessel break; 3215d5314d6SJason Wessel memcpy(tmpbuffer, p_tmp, cp-p_tmp); 3225d5314d6SJason Wessel *(tmpbuffer + (cp-p_tmp)) = '\0'; 3235d5314d6SJason Wessel p_tmp = strrchr(tmpbuffer, ' '); 3245d5314d6SJason Wessel if (p_tmp) 3255d5314d6SJason Wessel ++p_tmp; 3265d5314d6SJason Wessel else 3275d5314d6SJason Wessel p_tmp = tmpbuffer; 3285d5314d6SJason Wessel len = strlen(p_tmp); 329c2b94c72SPrarit Bhargava buf_size = sizeof(tmpbuffer) - (p_tmp - tmpbuffer); 330c2b94c72SPrarit Bhargava count = kallsyms_symbol_complete(p_tmp, buf_size); 3315d5314d6SJason Wessel if (tab == 2 && count > 0) { 3325d5314d6SJason Wessel kdb_printf("\n%d symbols are found.", count); 3335d5314d6SJason Wessel if (count > dtab_count) { 3345d5314d6SJason Wessel count = dtab_count; 3355d5314d6SJason Wessel kdb_printf(" But only first %d symbols will" 3365d5314d6SJason Wessel " be printed.\nYou can change the" 3375d5314d6SJason Wessel " environment variable DTABCOUNT.", 3385d5314d6SJason Wessel count); 3395d5314d6SJason Wessel } 3405d5314d6SJason Wessel kdb_printf("\n"); 3415d5314d6SJason Wessel for (i = 0; i < count; i++) { 342c2b94c72SPrarit Bhargava ret = kallsyms_symbol_next(p_tmp, i, buf_size); 343c2b94c72SPrarit Bhargava if (WARN_ON(!ret)) 3445d5314d6SJason Wessel break; 345c2b94c72SPrarit Bhargava if (ret != -E2BIG) 3465d5314d6SJason Wessel kdb_printf("%s ", p_tmp); 347c2b94c72SPrarit Bhargava else 348c2b94c72SPrarit Bhargava kdb_printf("%s... ", p_tmp); 3495d5314d6SJason Wessel *(p_tmp + len) = '\0'; 3505d5314d6SJason Wessel } 3515d5314d6SJason Wessel if (i >= dtab_count) 3525d5314d6SJason Wessel kdb_printf("..."); 3535d5314d6SJason Wessel kdb_printf("\n"); 3545d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 3555d5314d6SJason Wessel kdb_printf("%s", buffer); 3565d5314d6SJason Wessel } else if (tab != 2 && count > 0) { 3575d5314d6SJason Wessel len_tmp = strlen(p_tmp); 3585d5314d6SJason Wessel strncpy(p_tmp+len_tmp, cp, lastchar-cp+1); 3595d5314d6SJason Wessel len_tmp = strlen(p_tmp); 3605d5314d6SJason Wessel strncpy(cp, p_tmp+len, len_tmp-len + 1); 3615d5314d6SJason Wessel len = len_tmp - len; 3625d5314d6SJason Wessel kdb_printf("%s", cp); 3635d5314d6SJason Wessel cp += len; 3645d5314d6SJason Wessel lastchar += len; 3655d5314d6SJason Wessel } 3665d5314d6SJason Wessel kdb_nextline = 1; /* reset output line number */ 3675d5314d6SJason Wessel break; 3685d5314d6SJason Wessel default: 3695d5314d6SJason Wessel if (key >= 32 && lastchar < bufend) { 3705d5314d6SJason Wessel if (cp < lastchar) { 3715d5314d6SJason Wessel memcpy(tmpbuffer, cp, lastchar - cp); 3725d5314d6SJason Wessel memcpy(cp+1, tmpbuffer, lastchar - cp); 3735d5314d6SJason Wessel *++lastchar = '\0'; 3745d5314d6SJason Wessel *cp = key; 3755d5314d6SJason Wessel kdb_printf("%s\r", cp); 3765d5314d6SJason Wessel ++cp; 3775d5314d6SJason Wessel tmp = *cp; 3785d5314d6SJason Wessel *cp = '\0'; 3795d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 3805d5314d6SJason Wessel kdb_printf("%s", buffer); 3815d5314d6SJason Wessel *cp = tmp; 3825d5314d6SJason Wessel } else { 3835d5314d6SJason Wessel *++lastchar = '\0'; 3845d5314d6SJason Wessel *cp++ = key; 3855d5314d6SJason Wessel /* The kgdb transition check will hide 3865d5314d6SJason Wessel * printed characters if we think that 3875d5314d6SJason Wessel * kgdb is connecting, until the check 3885d5314d6SJason Wessel * fails */ 38937f86b46SJason Wessel if (!KDB_STATE(KGDB_TRANS)) { 39037f86b46SJason Wessel if (kgdb_transition_check(buffer)) 39137f86b46SJason Wessel return buffer; 39237f86b46SJason Wessel } else { 3935d5314d6SJason Wessel kdb_printf("%c", key); 3945d5314d6SJason Wessel } 39537f86b46SJason Wessel } 3965d5314d6SJason Wessel /* Special escape to kgdb */ 3975d5314d6SJason Wessel if (lastchar - buffer >= 5 && 3985d5314d6SJason Wessel strcmp(lastchar - 5, "$?#3f") == 0) { 399f679c498SJason Wessel kdb_gdb_state_pass(lastchar - 5); 4005d5314d6SJason Wessel strcpy(buffer, "kgdb"); 4015d5314d6SJason Wessel KDB_STATE_SET(DOING_KGDB); 4025d5314d6SJason Wessel return buffer; 4035d5314d6SJason Wessel } 404f679c498SJason Wessel if (lastchar - buffer >= 11 && 405f679c498SJason Wessel strcmp(lastchar - 11, "$qSupported") == 0) { 406f679c498SJason Wessel kdb_gdb_state_pass(lastchar - 11); 4075d5314d6SJason Wessel strcpy(buffer, "kgdb"); 408d613d828SJason Wessel KDB_STATE_SET(DOING_KGDB); 4095d5314d6SJason Wessel return buffer; 4105d5314d6SJason Wessel } 4115d5314d6SJason Wessel } 4125d5314d6SJason Wessel break; 4135d5314d6SJason Wessel } 4145d5314d6SJason Wessel goto poll_again; 4155d5314d6SJason Wessel } 4165d5314d6SJason Wessel 4175d5314d6SJason Wessel /* 4185d5314d6SJason Wessel * kdb_getstr 4195d5314d6SJason Wessel * 4205d5314d6SJason Wessel * Print the prompt string and read a command from the 4215d5314d6SJason Wessel * input device. 4225d5314d6SJason Wessel * 4235d5314d6SJason Wessel * Parameters: 4245d5314d6SJason Wessel * buffer Address of buffer to receive command 4255d5314d6SJason Wessel * bufsize Size of buffer in bytes 4265d5314d6SJason Wessel * prompt Pointer to string to use as prompt string 4275d5314d6SJason Wessel * Returns: 4285d5314d6SJason Wessel * Pointer to command buffer. 4295d5314d6SJason Wessel * Locking: 4305d5314d6SJason Wessel * None. 4315d5314d6SJason Wessel * Remarks: 4325d5314d6SJason Wessel * For SMP kernels, the processor number will be 4335d5314d6SJason Wessel * substituted for %d, %x or %o in the prompt. 4345d5314d6SJason Wessel */ 4355d5314d6SJason Wessel 43632d375f6SDaniel Thompson char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt) 4375d5314d6SJason Wessel { 4385d5314d6SJason Wessel if (prompt && kdb_prompt_str != prompt) 439ca976bfbSWenlin Kang strscpy(kdb_prompt_str, prompt, CMD_BUFLEN); 4405d5314d6SJason Wessel kdb_printf(kdb_prompt_str); 4415d5314d6SJason Wessel kdb_nextline = 1; /* Prompt and input resets line number */ 4425d5314d6SJason Wessel return kdb_read(buffer, bufsize); 4435d5314d6SJason Wessel } 4445d5314d6SJason Wessel 4455d5314d6SJason Wessel /* 4465d5314d6SJason Wessel * kdb_input_flush 4475d5314d6SJason Wessel * 4485d5314d6SJason Wessel * Get rid of any buffered console input. 4495d5314d6SJason Wessel * 4505d5314d6SJason Wessel * Parameters: 4515d5314d6SJason Wessel * none 4525d5314d6SJason Wessel * Returns: 4535d5314d6SJason Wessel * nothing 4545d5314d6SJason Wessel * Locking: 4555d5314d6SJason Wessel * none 4565d5314d6SJason Wessel * Remarks: 4575d5314d6SJason Wessel * Call this function whenever you want to flush input. If there is any 4585d5314d6SJason Wessel * outstanding input, it ignores all characters until there has been no 4595d5314d6SJason Wessel * data for approximately 1ms. 4605d5314d6SJason Wessel */ 4615d5314d6SJason Wessel 4625d5314d6SJason Wessel static void kdb_input_flush(void) 4635d5314d6SJason Wessel { 4645d5314d6SJason Wessel get_char_func *f; 4655d5314d6SJason Wessel int res; 4665d5314d6SJason Wessel int flush_delay = 1; 4675d5314d6SJason Wessel while (flush_delay) { 4685d5314d6SJason Wessel flush_delay--; 4695d5314d6SJason Wessel empty: 4705d5314d6SJason Wessel touch_nmi_watchdog(); 4715d5314d6SJason Wessel for (f = &kdb_poll_funcs[0]; *f; ++f) { 4725d5314d6SJason Wessel res = (*f)(); 4735d5314d6SJason Wessel if (res != -1) { 4745d5314d6SJason Wessel flush_delay = 1; 4755d5314d6SJason Wessel goto empty; 4765d5314d6SJason Wessel } 4775d5314d6SJason Wessel } 4785d5314d6SJason Wessel if (flush_delay) 4795d5314d6SJason Wessel mdelay(1); 4805d5314d6SJason Wessel } 4815d5314d6SJason Wessel } 4825d5314d6SJason Wessel 4835d5314d6SJason Wessel /* 4845d5314d6SJason Wessel * kdb_printf 4855d5314d6SJason Wessel * 4865d5314d6SJason Wessel * Print a string to the output device(s). 4875d5314d6SJason Wessel * 4885d5314d6SJason Wessel * Parameters: 4895d5314d6SJason Wessel * printf-like format and optional args. 4905d5314d6SJason Wessel * Returns: 4915d5314d6SJason Wessel * 0 4925d5314d6SJason Wessel * Locking: 4935d5314d6SJason Wessel * None. 4945d5314d6SJason Wessel * Remarks: 4955d5314d6SJason Wessel * use 'kdbcons->write()' to avoid polluting 'log_buf' with 4965d5314d6SJason Wessel * kdb output. 4975d5314d6SJason Wessel * 4985d5314d6SJason Wessel * If the user is doing a cmd args | grep srch 4995d5314d6SJason Wessel * then kdb_grepping_flag is set. 5005d5314d6SJason Wessel * In that case we need to accumulate full lines (ending in \n) before 5015d5314d6SJason Wessel * searching for the pattern. 5025d5314d6SJason Wessel */ 5035d5314d6SJason Wessel 5045d5314d6SJason Wessel static char kdb_buffer[256]; /* A bit too big to go on stack */ 5055d5314d6SJason Wessel static char *next_avail = kdb_buffer; 5065d5314d6SJason Wessel static int size_avail; 5075d5314d6SJason Wessel static int suspend_grep; 5085d5314d6SJason Wessel 5095d5314d6SJason Wessel /* 5105d5314d6SJason Wessel * search arg1 to see if it contains arg2 5115d5314d6SJason Wessel * (kdmain.c provides flags for ^pat and pat$) 5125d5314d6SJason Wessel * 5135d5314d6SJason Wessel * return 1 for found, 0 for not found 5145d5314d6SJason Wessel */ 5155d5314d6SJason Wessel static int kdb_search_string(char *searched, char *searchfor) 5165d5314d6SJason Wessel { 5175d5314d6SJason Wessel char firstchar, *cp; 5185d5314d6SJason Wessel int len1, len2; 5195d5314d6SJason Wessel 5205d5314d6SJason Wessel /* not counting the newline at the end of "searched" */ 5215d5314d6SJason Wessel len1 = strlen(searched)-1; 5225d5314d6SJason Wessel len2 = strlen(searchfor); 5235d5314d6SJason Wessel if (len1 < len2) 5245d5314d6SJason Wessel return 0; 5255d5314d6SJason Wessel if (kdb_grep_leading && kdb_grep_trailing && len1 != len2) 5265d5314d6SJason Wessel return 0; 5275d5314d6SJason Wessel if (kdb_grep_leading) { 5285d5314d6SJason Wessel if (!strncmp(searched, searchfor, len2)) 5295d5314d6SJason Wessel return 1; 5305d5314d6SJason Wessel } else if (kdb_grep_trailing) { 5315d5314d6SJason Wessel if (!strncmp(searched+len1-len2, searchfor, len2)) 5325d5314d6SJason Wessel return 1; 5335d5314d6SJason Wessel } else { 5345d5314d6SJason Wessel firstchar = *searchfor; 5355d5314d6SJason Wessel cp = searched; 5365d5314d6SJason Wessel while ((cp = strchr(cp, firstchar))) { 5375d5314d6SJason Wessel if (!strncmp(cp, searchfor, len2)) 5385d5314d6SJason Wessel return 1; 5395d5314d6SJason Wessel cp++; 5405d5314d6SJason Wessel } 5415d5314d6SJason Wessel } 5425d5314d6SJason Wessel return 0; 5435d5314d6SJason Wessel } 5445d5314d6SJason Wessel 5459d71b344SSumit Garg static void kdb_msg_write(const char *msg, int msg_len) 5469d71b344SSumit Garg { 5479d71b344SSumit Garg struct console *c; 548fcdb84ccSCengiz Can const char *cp; 549fcdb84ccSCengiz Can int len; 5509d71b344SSumit Garg 5519d71b344SSumit Garg if (msg_len == 0) 5529d71b344SSumit Garg return; 5539d71b344SSumit Garg 554fcdb84ccSCengiz Can cp = msg; 555fcdb84ccSCengiz Can len = msg_len; 5569d71b344SSumit Garg 5579d71b344SSumit Garg while (len--) { 5589d71b344SSumit Garg dbg_io_ops->write_char(*cp); 5599d71b344SSumit Garg cp++; 5609d71b344SSumit Garg } 5619d71b344SSumit Garg 5629d71b344SSumit Garg for_each_console(c) { 563e8857288SSumit Garg if (!(c->flags & CON_ENABLED)) 564e8857288SSumit Garg continue; 5655946d1f5SSumit Garg if (c == dbg_io_ops->cons) 5665946d1f5SSumit Garg continue; 5672a78b85bSSumit Garg /* 5682a78b85bSSumit Garg * Set oops_in_progress to encourage the console drivers to 5692a78b85bSSumit Garg * disregard their internal spin locks: in the current calling 5702a78b85bSSumit Garg * context the risk of deadlock is a bigger problem than risks 5712a78b85bSSumit Garg * due to re-entering the console driver. We operate directly on 5722a78b85bSSumit Garg * oops_in_progress rather than using bust_spinlocks() because 5732a78b85bSSumit Garg * the calls bust_spinlocks() makes on exit are not appropriate 5742a78b85bSSumit Garg * for this calling context. 5752a78b85bSSumit Garg */ 5762a78b85bSSumit Garg ++oops_in_progress; 5779d71b344SSumit Garg c->write(c, msg, msg_len); 5782a78b85bSSumit Garg --oops_in_progress; 5799d71b344SSumit Garg touch_nmi_watchdog(); 5809d71b344SSumit Garg } 5819d71b344SSumit Garg } 5829d71b344SSumit Garg 583f7d4ca8bSDaniel Thompson int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) 5845d5314d6SJason Wessel { 5855d5314d6SJason Wessel int diag; 5865d5314d6SJason Wessel int linecount; 58717b572e8SJason Wessel int colcount; 5885d5314d6SJason Wessel int logging, saved_loglevel = 0; 5895d5314d6SJason Wessel int retlen = 0; 5905d5314d6SJason Wessel int fnd, len; 591d5d8d3d0SPetr Mladek int this_cpu, old_cpu; 5925d5314d6SJason Wessel char *cp, *cp2, *cphold = NULL, replaced_byte = ' '; 5935d5314d6SJason Wessel char *moreprompt = "more> "; 5943f649ab7SKees Cook unsigned long flags; 5955d5314d6SJason Wessel 5965d5314d6SJason Wessel /* Serialize kdb_printf if multiple cpus try to write at once. 5975d5314d6SJason Wessel * But if any cpu goes recursive in kdb, just print the output, 5985d5314d6SJason Wessel * even if it is interleaved with any other text. 5995d5314d6SJason Wessel */ 60034aaff40SPetr Mladek local_irq_save(flags); 601d5d8d3d0SPetr Mladek this_cpu = smp_processor_id(); 602d5d8d3d0SPetr Mladek for (;;) { 603d5d8d3d0SPetr Mladek old_cpu = cmpxchg(&kdb_printf_cpu, -1, this_cpu); 604d5d8d3d0SPetr Mladek if (old_cpu == -1 || old_cpu == this_cpu) 605d5d8d3d0SPetr Mladek break; 606d5d8d3d0SPetr Mladek 607d5d8d3d0SPetr Mladek cpu_relax(); 6085d5314d6SJason Wessel } 6095d5314d6SJason Wessel 6105d5314d6SJason Wessel diag = kdbgetintenv("LINES", &linecount); 6115d5314d6SJason Wessel if (diag || linecount <= 1) 6125d5314d6SJason Wessel linecount = 24; 6135d5314d6SJason Wessel 61417b572e8SJason Wessel diag = kdbgetintenv("COLUMNS", &colcount); 61517b572e8SJason Wessel if (diag || colcount <= 1) 61617b572e8SJason Wessel colcount = 80; 61717b572e8SJason Wessel 6185d5314d6SJason Wessel diag = kdbgetintenv("LOGGING", &logging); 6195d5314d6SJason Wessel if (diag) 6205d5314d6SJason Wessel logging = 0; 6215d5314d6SJason Wessel 6225d5314d6SJason Wessel if (!kdb_grepping_flag || suspend_grep) { 6235d5314d6SJason Wessel /* normally, every vsnprintf starts a new buffer */ 6245d5314d6SJason Wessel next_avail = kdb_buffer; 6255d5314d6SJason Wessel size_avail = sizeof(kdb_buffer); 6265d5314d6SJason Wessel } 6275d5314d6SJason Wessel vsnprintf(next_avail, size_avail, fmt, ap); 6285d5314d6SJason Wessel 6295d5314d6SJason Wessel /* 6305d5314d6SJason Wessel * If kdb_parse() found that the command was cmd xxx | grep yyy 6315d5314d6SJason Wessel * then kdb_grepping_flag is set, and kdb_grep_string contains yyy 6325d5314d6SJason Wessel * 6335d5314d6SJason Wessel * Accumulate the print data up to a newline before searching it. 6345d5314d6SJason Wessel * (vsnprintf does null-terminate the string that it generates) 6355d5314d6SJason Wessel */ 6365d5314d6SJason Wessel 6375d5314d6SJason Wessel /* skip the search if prints are temporarily unconditional */ 6385d5314d6SJason Wessel if (!suspend_grep && kdb_grepping_flag) { 6395d5314d6SJason Wessel cp = strchr(kdb_buffer, '\n'); 6405d5314d6SJason Wessel if (!cp) { 6415d5314d6SJason Wessel /* 6425d5314d6SJason Wessel * Special cases that don't end with newlines 6435d5314d6SJason Wessel * but should be written without one: 6445d5314d6SJason Wessel * The "[nn]kdb> " prompt should 6455d5314d6SJason Wessel * appear at the front of the buffer. 6465d5314d6SJason Wessel * 6475d5314d6SJason Wessel * The "[nn]more " prompt should also be 6485d5314d6SJason Wessel * (MOREPROMPT -> moreprompt) 6495d5314d6SJason Wessel * written * but we print that ourselves, 6505d5314d6SJason Wessel * we set the suspend_grep flag to make 6515d5314d6SJason Wessel * it unconditional. 6525d5314d6SJason Wessel * 6535d5314d6SJason Wessel */ 6545d5314d6SJason Wessel if (next_avail == kdb_buffer) { 6555d5314d6SJason Wessel /* 6565d5314d6SJason Wessel * these should occur after a newline, 6575d5314d6SJason Wessel * so they will be at the front of the 6585d5314d6SJason Wessel * buffer 6595d5314d6SJason Wessel */ 6605d5314d6SJason Wessel cp2 = kdb_buffer; 6615d5314d6SJason Wessel len = strlen(kdb_prompt_str); 6625d5314d6SJason Wessel if (!strncmp(cp2, kdb_prompt_str, len)) { 6635d5314d6SJason Wessel /* 6645d5314d6SJason Wessel * We're about to start a new 6655d5314d6SJason Wessel * command, so we can go back 6665d5314d6SJason Wessel * to normal mode. 6675d5314d6SJason Wessel */ 6685d5314d6SJason Wessel kdb_grepping_flag = 0; 6695d5314d6SJason Wessel goto kdb_printit; 6705d5314d6SJason Wessel } 6715d5314d6SJason Wessel } 6725d5314d6SJason Wessel /* no newline; don't search/write the buffer 6735d5314d6SJason Wessel until one is there */ 6745d5314d6SJason Wessel len = strlen(kdb_buffer); 6755d5314d6SJason Wessel next_avail = kdb_buffer + len; 6765d5314d6SJason Wessel size_avail = sizeof(kdb_buffer) - len; 6775d5314d6SJason Wessel goto kdb_print_out; 6785d5314d6SJason Wessel } 6795d5314d6SJason Wessel 6805d5314d6SJason Wessel /* 6815d5314d6SJason Wessel * The newline is present; print through it or discard 6825d5314d6SJason Wessel * it, depending on the results of the search. 6835d5314d6SJason Wessel */ 6845d5314d6SJason Wessel cp++; /* to byte after the newline */ 6855d5314d6SJason Wessel replaced_byte = *cp; /* remember what/where it was */ 6865d5314d6SJason Wessel cphold = cp; 6875d5314d6SJason Wessel *cp = '\0'; /* end the string for our search */ 6885d5314d6SJason Wessel 6895d5314d6SJason Wessel /* 6905d5314d6SJason Wessel * We now have a newline at the end of the string 6915d5314d6SJason Wessel * Only continue with this output if it contains the 6925d5314d6SJason Wessel * search string. 6935d5314d6SJason Wessel */ 6945d5314d6SJason Wessel fnd = kdb_search_string(kdb_buffer, kdb_grep_string); 6955d5314d6SJason Wessel if (!fnd) { 6965d5314d6SJason Wessel /* 6975d5314d6SJason Wessel * At this point the complete line at the start 6985d5314d6SJason Wessel * of kdb_buffer can be discarded, as it does 6995d5314d6SJason Wessel * not contain what the user is looking for. 7005d5314d6SJason Wessel * Shift the buffer left. 7015d5314d6SJason Wessel */ 7025d5314d6SJason Wessel *cphold = replaced_byte; 7035d5314d6SJason Wessel strcpy(kdb_buffer, cphold); 7045d5314d6SJason Wessel len = strlen(kdb_buffer); 7055d5314d6SJason Wessel next_avail = kdb_buffer + len; 7065d5314d6SJason Wessel size_avail = sizeof(kdb_buffer) - len; 7075d5314d6SJason Wessel goto kdb_print_out; 7085d5314d6SJason Wessel } 709fb6daa75SDaniel Thompson if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH) 710fb6daa75SDaniel Thompson /* 711fb6daa75SDaniel Thompson * This was a interactive search (using '/' at more 712fb6daa75SDaniel Thompson * prompt) and it has completed. Clear the flag. 713fb6daa75SDaniel Thompson */ 714fb6daa75SDaniel Thompson kdb_grepping_flag = 0; 7155d5314d6SJason Wessel /* 7165d5314d6SJason Wessel * at this point the string is a full line and 7175d5314d6SJason Wessel * should be printed, up to the null. 7185d5314d6SJason Wessel */ 7195d5314d6SJason Wessel } 7205d5314d6SJason Wessel kdb_printit: 7215d5314d6SJason Wessel 7225d5314d6SJason Wessel /* 7235d5314d6SJason Wessel * Write to all consoles. 7245d5314d6SJason Wessel */ 7255d5314d6SJason Wessel retlen = strlen(kdb_buffer); 72649795757SPetr Mladek cp = (char *) printk_skip_headers(kdb_buffer); 7279d71b344SSumit Garg if (!dbg_kdb_mode && kgdb_connected) 728f7d4ca8bSDaniel Thompson gdbstub_msg_write(cp, retlen - (cp - kdb_buffer)); 7299d71b344SSumit Garg else 7309d71b344SSumit Garg kdb_msg_write(cp, retlen - (cp - kdb_buffer)); 7319d71b344SSumit Garg 7325d5314d6SJason Wessel if (logging) { 7335d5314d6SJason Wessel saved_loglevel = console_loglevel; 734a8fe19ebSBorislav Petkov console_loglevel = CONSOLE_LOGLEVEL_SILENT; 735f7d4ca8bSDaniel Thompson if (printk_get_level(kdb_buffer) || src == KDB_MSGSRC_PRINTK) 736f7d4ca8bSDaniel Thompson printk("%s", kdb_buffer); 737f7d4ca8bSDaniel Thompson else 738f7d4ca8bSDaniel Thompson pr_info("%s", kdb_buffer); 7395d5314d6SJason Wessel } 7405d5314d6SJason Wessel 74117b572e8SJason Wessel if (KDB_STATE(PAGER)) { 74217b572e8SJason Wessel /* 74317b572e8SJason Wessel * Check printed string to decide how to bump the 74417b572e8SJason Wessel * kdb_nextline to control when the more prompt should 74517b572e8SJason Wessel * show up. 74617b572e8SJason Wessel */ 74717b572e8SJason Wessel int got = 0; 74817b572e8SJason Wessel len = retlen; 74917b572e8SJason Wessel while (len--) { 75017b572e8SJason Wessel if (kdb_buffer[len] == '\n') { 7515d5314d6SJason Wessel kdb_nextline++; 75217b572e8SJason Wessel got = 0; 75317b572e8SJason Wessel } else if (kdb_buffer[len] == '\r') { 75417b572e8SJason Wessel got = 0; 75517b572e8SJason Wessel } else { 75617b572e8SJason Wessel got++; 75717b572e8SJason Wessel } 75817b572e8SJason Wessel } 75917b572e8SJason Wessel kdb_nextline += got / (colcount + 1); 76017b572e8SJason Wessel } 7615d5314d6SJason Wessel 7625d5314d6SJason Wessel /* check for having reached the LINES number of printed lines */ 76317b572e8SJason Wessel if (kdb_nextline >= linecount) { 7644f27e824SDaniel Thompson char ch; 7655d5314d6SJason Wessel 7665d5314d6SJason Wessel /* Watch out for recursion here. Any routine that calls 7675d5314d6SJason Wessel * kdb_printf will come back through here. And kdb_read 7685d5314d6SJason Wessel * uses kdb_printf to echo on serial consoles ... 7695d5314d6SJason Wessel */ 7705d5314d6SJason Wessel kdb_nextline = 1; /* In case of recursion */ 7715d5314d6SJason Wessel 7725d5314d6SJason Wessel /* 7735d5314d6SJason Wessel * Pause until cr. 7745d5314d6SJason Wessel */ 7755d5314d6SJason Wessel moreprompt = kdbgetenv("MOREPROMPT"); 7765d5314d6SJason Wessel if (moreprompt == NULL) 7775d5314d6SJason Wessel moreprompt = "more> "; 7785d5314d6SJason Wessel 7795d5314d6SJason Wessel kdb_input_flush(); 7809d71b344SSumit Garg kdb_msg_write(moreprompt, strlen(moreprompt)); 7815d5314d6SJason Wessel 7825d5314d6SJason Wessel if (logging) 7835d5314d6SJason Wessel printk("%s", moreprompt); 7845d5314d6SJason Wessel 7854f27e824SDaniel Thompson ch = kdb_getchar(); 7865d5314d6SJason Wessel kdb_nextline = 1; /* Really set output line 1 */ 7875d5314d6SJason Wessel 7885d5314d6SJason Wessel /* empty and reset the buffer: */ 7895d5314d6SJason Wessel kdb_buffer[0] = '\0'; 7905d5314d6SJason Wessel next_avail = kdb_buffer; 7915d5314d6SJason Wessel size_avail = sizeof(kdb_buffer); 7924f27e824SDaniel Thompson if ((ch == 'q') || (ch == 'Q')) { 7935d5314d6SJason Wessel /* user hit q or Q */ 7945d5314d6SJason Wessel KDB_FLAG_SET(CMD_INTERRUPT); /* command interrupted */ 7955d5314d6SJason Wessel KDB_STATE_CLEAR(PAGER); 7965d5314d6SJason Wessel /* end of command output; back to normal mode */ 7975d5314d6SJason Wessel kdb_grepping_flag = 0; 7985d5314d6SJason Wessel kdb_printf("\n"); 7994f27e824SDaniel Thompson } else if (ch == ' ') { 80017b572e8SJason Wessel kdb_printf("\r"); 8015d5314d6SJason Wessel suspend_grep = 1; /* for this recursion */ 8024f27e824SDaniel Thompson } else if (ch == '\n' || ch == '\r') { 8035d5314d6SJason Wessel kdb_nextline = linecount - 1; 8045d5314d6SJason Wessel kdb_printf("\r"); 8055d5314d6SJason Wessel suspend_grep = 1; /* for this recursion */ 8064f27e824SDaniel Thompson } else if (ch == '/' && !kdb_grepping_flag) { 807fb6daa75SDaniel Thompson kdb_printf("\r"); 808fb6daa75SDaniel Thompson kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN, 809fb6daa75SDaniel Thompson kdbgetenv("SEARCHPROMPT") ?: "search> "); 810fb6daa75SDaniel Thompson *strchrnul(kdb_grep_string, '\n') = '\0'; 811fb6daa75SDaniel Thompson kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH; 812fb6daa75SDaniel Thompson suspend_grep = 1; /* for this recursion */ 8134f27e824SDaniel Thompson } else if (ch) { 8144f27e824SDaniel Thompson /* user hit something unexpected */ 8155d5314d6SJason Wessel suspend_grep = 1; /* for this recursion */ 8164f27e824SDaniel Thompson if (ch != '/') 817fb6daa75SDaniel Thompson kdb_printf( 818fb6daa75SDaniel Thompson "\nOnly 'q', 'Q' or '/' are processed at " 819fb6daa75SDaniel Thompson "more prompt, input ignored\n"); 820fb6daa75SDaniel Thompson else 821fb6daa75SDaniel Thompson kdb_printf("\n'/' cannot be used during | " 822fb6daa75SDaniel Thompson "grep filtering, input ignored\n"); 8235d5314d6SJason Wessel } else if (kdb_grepping_flag) { 8245d5314d6SJason Wessel /* user hit enter */ 8255d5314d6SJason Wessel suspend_grep = 1; /* for this recursion */ 8265d5314d6SJason Wessel kdb_printf("\n"); 8275d5314d6SJason Wessel } 8285d5314d6SJason Wessel kdb_input_flush(); 8295d5314d6SJason Wessel } 8305d5314d6SJason Wessel 8315d5314d6SJason Wessel /* 8325d5314d6SJason Wessel * For grep searches, shift the printed string left. 8335d5314d6SJason Wessel * replaced_byte contains the character that was overwritten with 8345d5314d6SJason Wessel * the terminating null, and cphold points to the null. 8355d5314d6SJason Wessel * Then adjust the notion of available space in the buffer. 8365d5314d6SJason Wessel */ 8375d5314d6SJason Wessel if (kdb_grepping_flag && !suspend_grep) { 8385d5314d6SJason Wessel *cphold = replaced_byte; 8395d5314d6SJason Wessel strcpy(kdb_buffer, cphold); 8405d5314d6SJason Wessel len = strlen(kdb_buffer); 8415d5314d6SJason Wessel next_avail = kdb_buffer + len; 8425d5314d6SJason Wessel size_avail = sizeof(kdb_buffer) - len; 8435d5314d6SJason Wessel } 8445d5314d6SJason Wessel 8455d5314d6SJason Wessel kdb_print_out: 8465d5314d6SJason Wessel suspend_grep = 0; /* end of what may have been a recursive call */ 8475d5314d6SJason Wessel if (logging) 8485d5314d6SJason Wessel console_loglevel = saved_loglevel; 849d5d8d3d0SPetr Mladek /* kdb_printf_cpu locked the code above. */ 850d5d8d3d0SPetr Mladek smp_store_release(&kdb_printf_cpu, old_cpu); 851d5d8d3d0SPetr Mladek local_irq_restore(flags); 8525d5314d6SJason Wessel return retlen; 8535d5314d6SJason Wessel } 854d37d39aeSJason Wessel 855d37d39aeSJason Wessel int kdb_printf(const char *fmt, ...) 856d37d39aeSJason Wessel { 857d37d39aeSJason Wessel va_list ap; 858d37d39aeSJason Wessel int r; 859d37d39aeSJason Wessel 860d37d39aeSJason Wessel va_start(ap, fmt); 861f7d4ca8bSDaniel Thompson r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap); 862d37d39aeSJason Wessel va_end(ap); 863d37d39aeSJason Wessel 864d37d39aeSJason Wessel return r; 865d37d39aeSJason Wessel } 866f7030bbcSJason Wessel EXPORT_SYMBOL_GPL(kdb_printf); 867