From patchwork Mon Oct 14 15:46:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 176259 Delivered-To: patches@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp4682872ill; Mon, 14 Oct 2019 08:46:34 -0700 (PDT) X-Received: by 2002:a1c:e057:: with SMTP id x84mr15039781wmg.72.1571067994189; Mon, 14 Oct 2019 08:46:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571067994; cv=none; d=google.com; s=arc-20160816; b=ul1W0WOd1IRNDtE+BGc0uuOh41VVHQ+hFkuhEFndWk/xvvJ+dFcOvXtPp3Z9jNNtfs +CuHoCDuz+EKz3QfFK8FmRiJh1X2Rzci+G0/UgZbgFD+lSSbkf11ExMdCR+UA+G0KEqS JJPw9xBs7D9Kl7HY97bmKnAZpcWrCtYaCWuMoPnhh4aRKTBSbhxiiHQdoXSJsSCdeQ5B i9jjXiMUC/HHhPl4pDzInCa4SFAD/NDtzOhNLhBmrS0bD3ROHoIZJsgOAhz8N6DGp18C AY5Eaks6C8JmezHTrl7l+aRAnGp0WlIQZCEC7e/QUkc0qDJw1RIP/Fe0xr6EM4sY5jYA olPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=VzbHotXa2CNe+yOSdOVLXrQNHA0n+J4DgMTdXlIpchk=; b=EnHnYYJSo0/yRChCnZcOB9GEvJtR4fRQs2e29+unuFWs/PBGycU4nx5kZkFUcBcMzz g2jLyXj21nnlAZelWtI1SqwYc7Vg0Yo78FGAINaDFhyK3VOgYZKvyprtCtXKo7/56ds+ P72BEDMxGOLlACj/SeFawQFq0vzU8J4Zmnx+Oz174+q7vJCZiFtk/StjqLZiZGb+PdVb f1FT3iGH93PwM4jP4FvFjVtkPXWJDrymjGGAtQ06TpDyxpMwFadFj3D9Ne0TJZIsiKIL wXm3BS3ZhAoNmUZ+Lf+yLZx5acmeiILMJ9UMiuZ/bofsCqzcDjkjxWx4eoYa/IoPWPko 6EUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JZ0zW2yk; spf=pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=daniel.thompson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id g189sor10679031wme.12.2019.10.14.08.46.34 for (Google Transport Security); Mon, 14 Oct 2019 08:46:34 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JZ0zW2yk; spf=pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=daniel.thompson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VzbHotXa2CNe+yOSdOVLXrQNHA0n+J4DgMTdXlIpchk=; b=JZ0zW2ykyoUjwTVOOpVM0OAoNndUncqcPcM3iZQM6ogeifeEz5Ud/6+rgPXaf2ClAM Aju0uPZ0zRZ7yhzjv6bkbyZOdyY4YZ9wzITr38I6Ep2kqzIHmW2lghUCTTSrO79faAu0 FgxD8cm+7jGYL5Fvax3e+TvPJ5QAQeXQyV2/2Wisp3nueC1tPXY0djOqPbaueYKxBL0R 9p0fJ2EKJRybayba0NVlzcMwUwEe7eVt3IEzKIQFk2+uxL7yJPpQ4qWGMzvsuzC0sEdr fV8Pjm/CrIrha2kjdoaADiVt+nwaFJb/TEMzvTmasKJgdweqarshhZmJ26o7OrDVJ+Z+ 1vdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VzbHotXa2CNe+yOSdOVLXrQNHA0n+J4DgMTdXlIpchk=; b=OSmL1R4t1H8EqwSmod1GHiuXTg5XkRphF9zEAsj41jKTO8BXZic7Np2GMNDotGB7oF JX/nPmW80PrTRVddmuVYWKF7GemiQ5bl+lH/tZfb5JnkEp6FcmPYk0GUrXJeamUt4HiP LCDQi/btsVTsR7CsBxdgwrb0pqtZ5K0/9Jk/YHVy3Dkn0c29jzf0oj6JvQCu0HCXTDe3 cRmzWw/5qsICa/ztwapakTTl+KowLy6FtBPpz+tgnXFDI2Z5WByKm2MIFVNJz4ZW7n+p yl3ctis4nWfmune8TFI6SS/jV6+HBrgdgyf/scbDbq+kZyvBwA6sVPCtQAdvYwi5MPhZ rW/g== X-Gm-Message-State: APjAAAWMyMWFmBI1Cv06PgBaKbF6FtSZ4Lw9WC7948xeM7/sT1zAxC1W v69Bw7D73OaliWolu5UR87AES6X0 X-Google-Smtp-Source: APXvYqxE+dOkNfiWJwLl4yuWYmrcDvkahTPo50r3LUg8jfCJu+reTdEf/UpEq1yy6Sv/6BL65hhf8g== X-Received: by 2002:a1c:48d6:: with SMTP id v205mr14942664wma.35.1571067993614; Mon, 14 Oct 2019 08:46:33 -0700 (PDT) Return-Path: Received: from wychelm.lan (cpc141214-aztw34-2-0-cust773.18-1.cable.virginm.net. [86.9.19.6]) by smtp.gmail.com with ESMTPSA id q22sm16539738wmj.5.2019.10.14.08.46.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Oct 2019 08:46:32 -0700 (PDT) From: Daniel Thompson To: Jason Wessel , Douglas Anderson Cc: Daniel Thompson , kgdb-bugreport@lists.sourceforge.net, linux-kernel@vger.kernel.org, patches@linaro.org Subject: [PATCH v3 3/5] kdb: Remove special case logic from kdb_read() Date: Mon, 14 Oct 2019 16:46:24 +0100 Message-Id: <20191014154626.351-4-daniel.thompson@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191014154626.351-1-daniel.thompson@linaro.org> References: <20191014154626.351-1-daniel.thompson@linaro.org> MIME-Version: 1.0 kdb_read() contains special case logic to force it exit after reading a single character. We can remove all the special case logic by directly calling the function to read a single character instead. This also allows us to tidy up the function prototype which, because it now matches getchar(), we can also rename in order to make its role clearer. This does involve some extra code to handle btaprompt properly but we don't mind the new lines of code here because the old code had some interesting problems (bad newline handling, treating unexpected characters like ). Signed-off-by: Daniel Thompson --- kernel/debug/kdb/kdb_bt.c | 22 +++++++---- kernel/debug/kdb/kdb_io.c | 67 +++++++++++++++------------------- kernel/debug/kdb/kdb_private.h | 1 + 3 files changed, 45 insertions(+), 45 deletions(-) -- 2.21.0 Reviewed-by: Douglas Anderson diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index 7e2379aa0a1e..b6dc4d7470fd 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c @@ -81,9 +81,10 @@ static int kdb_bt1(struct task_struct *p, unsigned long mask, int argcount, int btaprompt) { - char buffer[2]; - if (kdb_getarea(buffer[0], (unsigned long)p) || - kdb_getarea(buffer[0], (unsigned long)(p+1)-1)) + char ch; + + if (kdb_getarea(ch, (unsigned long)p) || + kdb_getarea(ch, (unsigned long)(p+1)-1)) return KDB_BADADDR; if (!kdb_task_state(p, mask)) return 0; @@ -91,12 +92,17 @@ kdb_bt1(struct task_struct *p, unsigned long mask, kdb_ps1(p); kdb_show_stack(p, NULL); if (btaprompt) { - kdb_getstr(buffer, sizeof(buffer), - "Enter to end, to continue:"); - if (buffer[0] == 'q') { - kdb_printf("\n"); + kdb_printf("Enter to end, or to continue:"); + ch = kdb_getchar(); + while (!strchr("\r\n q", ch)) + ch = kdb_getchar(); + kdb_printf("\n"); + + /* reset the pager */ + kdb_nextline = 1; + + if (ch == 'q') return 1; - } } touch_nmi_watchdog(); return 0; diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 78cb6e339408..39476616295e 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -50,14 +50,14 @@ static int kgdb_transition_check(char *buffer) } /* - * kdb_read_handle_escape + * kdb_handle_escape * * Run a validity check on an accumulated escape sequence. * * Returns -1 if the escape sequence is unwanted, 0 if it is incomplete, * otherwise it returns a mapped key value to pass to the upper layers. */ -static int kdb_read_handle_escape(char *buf, size_t sz) +static int kdb_handle_escape(char *buf, size_t sz) { char *lastkey = buf + sz - 1; @@ -106,7 +106,22 @@ static int kdb_read_handle_escape(char *buf, size_t sz) return -1; } -static int kdb_read_get_key(char *buffer, size_t bufsize) +/** + * kdb_getchar() - Read a single character from a kdb console (or consoles). + * + * Other than polling the various consoles that are currently enabled, + * most of the work done in this function is dealing with escape sequences. + * + * An escape key could be the start of a vt100 control sequence such as \e[D + * (left arrow) or it could be a character in its own right. The standard + * method for detecting the difference is to wait for 2 seconds to see if there + * are any other characters. kdb is complicated by the lack of a timer service + * (interrupts are off), by multiple input sources. Escape sequence processing + * has to be done as states in the polling loop. + * + * Return: The key pressed or a control code derived from an escape sequence. + */ +char kdb_getchar(void) { #define ESCAPE_UDELAY 1000 #define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY) /* 2 seconds worth of udelays */ @@ -124,7 +139,6 @@ static int kdb_read_get_key(char *buffer, size_t bufsize) } key = (*f)(); - if (key == -1) { if (escape_delay) { udelay(ESCAPE_UDELAY); @@ -134,14 +148,6 @@ static int kdb_read_get_key(char *buffer, size_t bufsize) continue; } - if (bufsize <= 2) { - if (key == '\r') - key = '\n'; - *buffer++ = key; - *buffer = '\0'; - return -1; - } - if (escape_delay == 0 && key == '\e') { escape_delay = ESCAPE_DELAY; ped = escape_data; @@ -152,7 +158,7 @@ static int kdb_read_get_key(char *buffer, size_t bufsize) return '\e'; *ped++ = key; - key = kdb_read_handle_escape(escape_data, + key = kdb_handle_escape(escape_data, ped - escape_data); if (key < 0) return '\e'; @@ -183,17 +189,7 @@ static int kdb_read_get_key(char *buffer, size_t bufsize) * function. It is not reentrant - it relies on the fact * that while kdb is running on only one "master debug" cpu. * Remarks: - * - * The buffer size must be >= 2. A buffer size of 2 means that the caller only - * wants a single key. - * - * An escape key could be the start of a vt100 control sequence such as \e[D - * (left arrow) or it could be a character in its own right. The standard - * method for detecting the difference is to wait for 2 seconds to see if there - * are any other characters. kdb is complicated by the lack of a timer service - * (interrupts are off), by multiple input sources and by the need to sometimes - * return after just one key. Escape sequence processing has to be done as - * states in the polling loop. + * The buffer size must be >= 2. */ static char *kdb_read(char *buffer, size_t bufsize) @@ -228,9 +224,7 @@ static char *kdb_read(char *buffer, size_t bufsize) *cp = '\0'; kdb_printf("%s", buffer); poll_again: - key = kdb_read_get_key(buffer, bufsize); - if (key == -1) - return buffer; + key = kdb_getchar(); if (key != 9) tab = 0; switch (key) { @@ -741,7 +735,7 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) /* check for having reached the LINES number of printed lines */ if (kdb_nextline >= linecount) { - char buf1[16] = ""; + char ch; /* Watch out for recursion here. Any routine that calls * kdb_printf will come back through here. And kdb_read @@ -776,39 +770,38 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) if (logging) printk("%s", moreprompt); - kdb_read(buf1, 2); /* '2' indicates to return - * immediately after getting one key. */ + ch = kdb_getchar(); kdb_nextline = 1; /* Really set output line 1 */ /* empty and reset the buffer: */ kdb_buffer[0] = '\0'; next_avail = kdb_buffer; size_avail = sizeof(kdb_buffer); - if ((buf1[0] == 'q') || (buf1[0] == 'Q')) { + if ((ch == 'q') || (ch == 'Q')) { /* user hit q or Q */ KDB_FLAG_SET(CMD_INTERRUPT); /* command interrupted */ KDB_STATE_CLEAR(PAGER); /* end of command output; back to normal mode */ kdb_grepping_flag = 0; kdb_printf("\n"); - } else if (buf1[0] == ' ') { + } else if (ch == ' ') { kdb_printf("\r"); suspend_grep = 1; /* for this recursion */ - } else if (buf1[0] == '\n') { + } else if (ch == '\n' || ch == '\r') { kdb_nextline = linecount - 1; kdb_printf("\r"); suspend_grep = 1; /* for this recursion */ - } else if (buf1[0] == '/' && !kdb_grepping_flag) { + } else if (ch == '/' && !kdb_grepping_flag) { kdb_printf("\r"); kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN, kdbgetenv("SEARCHPROMPT") ?: "search> "); *strchrnul(kdb_grep_string, '\n') = '\0'; kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH; suspend_grep = 1; /* for this recursion */ - } else if (buf1[0] && buf1[0] != '\n') { - /* user hit something other than enter */ + } else if (ch) { + /* user hit something unexpected */ suspend_grep = 1; /* for this recursion */ - if (buf1[0] != '/') + if (ch != '/') kdb_printf( "\nOnly 'q', 'Q' or '/' are processed at " "more prompt, input ignored\n"); diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 2118d8258b7c..55d052061ef9 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -210,6 +210,7 @@ extern void kdb_ps1(const struct task_struct *p); extern void kdb_print_nameval(const char *name, unsigned long val); extern void kdb_send_sig(struct task_struct *p, int sig); extern void kdb_meminfo_proc_show(void); +extern char kdb_getchar(void); extern char *kdb_getstr(char *, size_t, const char *); extern void kdb_gdb_state_pass(char *buf);