linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/2] serial/sysrq: Add MAGIC_SYSRQ_SERIAL_SEQUENCE
@ 2020-03-02 17:51 Dmitry Safonov
  2020-03-02 17:51 ` [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy Dmitry Safonov
  0 siblings, 1 reply; 4+ messages in thread
From: Dmitry Safonov @ 2020-03-02 17:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dmitry Safonov, Dmitry Safonov, Greg Kroah-Hartman, Iurii Zaikin,
	Jiri Slaby, Joe Perches, Randy Dunlap, Vasiliy Khoruzhick,
	linux-serial, Luis Chamberlain, Kees Cook, linux-fsdevel

Magic sysrq has proven for Arista usecases to be useful for debugging issues
in field, over serial line when the switch is in such bad state
that it can't accept network connections anymore.

Unfortunately, having sysrq always enabled doesn't work for some
embedded boards that tend to generate garbage on serial line (including
BREAKs). Since commit 732dbf3a6104 ("serial: do not accept sysrq
characters via serial port"), it's possible to keep sysrq enabled, but
over serial line.

Add a way to enable sysrq on a uart, where currently it can be
constantly either on or off (CONFIG_MAGIC_SYSRQ_SERIAL).
While doing so, cleanup __sysrq_enabled and serial_core header file.

Changes since v2 [2]:
- sysrq_get_mask() renamed to sysrq_mask() as there isn't
  sysrq_put_mask(); acquired kernel-doc (by Greg's review, thanks)
- uart_try_toggle_sysrq() now returns true/false instead 1/0 as it's
  a bool function (nits by Joe Perches, thanks!)
- Dropped "sizeof(port->sysrq_seq)*U8_MAX" and used U8_MAX (Randy Dunlap)

Changes since v1 [1]:
- Fix typo in pr_info() message (noticed by Randy Dunlap, thanks)
- Add SYSRQ_TIMEOUT define for timeout after BREAK and separate removing
  @unused member of uart_port into cleanup patch (by Greg's review, thanks)
- Add const qualifier, make uart_try_toggle_sysrq() bool function
  (Joe Perches, thanks)
- Fix !CONFIG_SYSRQ and CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
  build failures (kudos to kbuild test robot)

[1]: https://lkml.kernel.org/r/20200109215444.95995-1-dima@arista.com
[2]: https://lkml.kernel.org/r/20200114171912.261787-1-dima@arista.com

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Iurii Zaikin <yzaikin@google.com>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Joe Perches <joe@perches.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Vasiliy Khoruzhick <vasilykh@arista.com>
Cc: linux-serial@vger.kernel.org

Thanks,
             Dmitry

Dmitry Safonov (2):
  sysctl/sysrq: Remove __sysrq_enabled copy
  serial/sysrq: Add MAGIC_SYSRQ_SERIAL_SEQUENCE

 drivers/tty/serial/serial_core.c | 75 +++++++++++++++++++++++++++++---
 drivers/tty/sysrq.c              | 12 +++++
 include/linux/serial_core.h      |  1 +
 include/linux/sysrq.h            |  7 +++
 kernel/sysctl.c                  | 41 +++++++++--------
 lib/Kconfig.debug                |  8 ++++
 6 files changed, 118 insertions(+), 26 deletions(-)

-- 
2.25.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy
  2020-03-02 17:51 [PATCHv3 0/2] serial/sysrq: Add MAGIC_SYSRQ_SERIAL_SEQUENCE Dmitry Safonov
@ 2020-03-02 17:51 ` Dmitry Safonov
  2020-04-01 12:22   ` Michael Ellerman
  0 siblings, 1 reply; 4+ messages in thread
From: Dmitry Safonov @ 2020-03-02 17:51 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dmitry Safonov, Dmitry Safonov, Greg Kroah-Hartman, Iurii Zaikin,
	Jiri Slaby, Joe Perches, Randy Dunlap, Vasiliy Khoruzhick,
	linux-serial, Luis Chamberlain, Kees Cook, linux-fsdevel

Many embedded boards have a disconnected TTL level serial which can
generate some garbage that can lead to spurious false sysrq detects.

Currently, sysrq can be either completely disabled for serial console
or always disabled (with CONFIG_MAGIC_SYSRQ_SERIAL), since
commit 732dbf3a6104 ("serial: do not accept sysrq characters via serial port")

At Arista, we have such boards that can generate BREAK and random
garbage. While disabling sysrq for serial console would solve
the problem with spurious false sysrq triggers, it's also desirable
to have a way to enable sysrq back.

Having the way to enable sysrq was beneficial to debug lockups with
a manual investigation in field and on the other side preventing false
sysrq detections.

As a preparation to add sysrq_toggle_support() call into uart,
remove a private copy of sysrq_enabled from sysctl - it should reflect
the actual status of sysrq.

Furthermore, the private copy isn't correct already in case
sysrq_always_enabled is true. So, remove __sysrq_enabled and use a
getter-helper sysrq_mask() to check sysrq_key_op enabled status.

Cc: Iurii Zaikin <yzaikin@google.com>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 drivers/tty/sysrq.c   | 12 ++++++++++++
 include/linux/sysrq.h |  7 +++++++
 kernel/sysctl.c       | 41 ++++++++++++++++++++++-------------------
 3 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index f724962a5906..5e0d0813da55 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -63,6 +63,18 @@ static bool sysrq_on(void)
 	return sysrq_enabled || sysrq_always_enabled;
 }
 
+/**
+ * sysrq_mask - Getter for sysrq_enabled mask.
+ *
+ * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise.
+ */
+int sysrq_mask(void)
+{
+	if (sysrq_always_enabled)
+		return 1;
+	return sysrq_enabled;
+}
+
 /*
  * A value of 1 means 'all', other nonzero values are an op mask:
  */
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 8c71874e8485..8e159e16850f 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -50,6 +50,7 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op);
 struct sysrq_key_op *__sysrq_get_key_op(int key);
 
 int sysrq_toggle_support(int enable_mask);
+int sysrq_mask(void);
 
 #else
 
@@ -71,6 +72,12 @@ static inline int unregister_sysrq_key(int key, struct sysrq_key_op *op)
 	return -EINVAL;
 }
 
+static inline int sysrq_mask(void)
+{
+	/* Magic SysRq disabled mask */
+	return 0;
+}
+
 #endif
 
 #endif /* _LINUX_SYSRQ_H */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ad5b88a53c5a..94638f695e60 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -229,25 +229,8 @@ static int proc_dopipe_max_size(struct ctl_table *table, int write,
 		void __user *buffer, size_t *lenp, loff_t *ppos);
 
 #ifdef CONFIG_MAGIC_SYSRQ
-/* Note: sysrq code uses its own private copy */
-static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
-
 static int sysrq_sysctl_handler(struct ctl_table *table, int write,
-				void __user *buffer, size_t *lenp,
-				loff_t *ppos)
-{
-	int error;
-
-	error = proc_dointvec(table, write, buffer, lenp, ppos);
-	if (error)
-		return error;
-
-	if (write)
-		sysrq_toggle_support(__sysrq_enabled);
-
-	return 0;
-}
-
+			void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
 static struct ctl_table kern_table[];
@@ -747,7 +730,7 @@ static struct ctl_table kern_table[] = {
 #ifdef CONFIG_MAGIC_SYSRQ
 	{
 		.procname	= "sysrq",
-		.data		= &__sysrq_enabled,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
 		.proc_handler	= sysrq_sysctl_handler,
@@ -2835,6 +2818,26 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
 }
 #endif
 
+#ifdef CONFIG_MAGIC_SYSRQ
+static int sysrq_sysctl_handler(struct ctl_table *table, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	int tmp, ret;
+
+	tmp = sysrq_mask();
+
+	ret = __do_proc_dointvec(&tmp, table, write, buffer,
+			       lenp, ppos, NULL, NULL);
+	if (ret || !write)
+		return ret;
+
+	if (write)
+		sysrq_toggle_support(tmp);
+
+	return 0;
+}
+#endif
+
 static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
 				     void __user *buffer,
 				     size_t *lenp, loff_t *ppos,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy
  2020-03-02 17:51 ` [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy Dmitry Safonov
@ 2020-04-01 12:22   ` Michael Ellerman
  2020-04-01 14:41     ` Dmitry Safonov
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Ellerman @ 2020-04-01 12:22 UTC (permalink / raw)
  To: Dmitry Safonov, linux-kernel
  Cc: Dmitry Safonov, Dmitry Safonov, Greg Kroah-Hartman, Iurii Zaikin,
	Jiri Slaby, Joe Perches, Randy Dunlap, Vasiliy Khoruzhick,
	linux-serial, Luis Chamberlain, Kees Cook, linux-fsdevel

Dmitry Safonov <dima@arista.com> writes:
> Many embedded boards have a disconnected TTL level serial which can
> generate some garbage that can lead to spurious false sysrq detects.
>
> Currently, sysrq can be either completely disabled for serial console
> or always disabled (with CONFIG_MAGIC_SYSRQ_SERIAL), since
> commit 732dbf3a6104 ("serial: do not accept sysrq characters via serial port")
>
> At Arista, we have such boards that can generate BREAK and random
> garbage. While disabling sysrq for serial console would solve
> the problem with spurious false sysrq triggers, it's also desirable
> to have a way to enable sysrq back.
>
> Having the way to enable sysrq was beneficial to debug lockups with
> a manual investigation in field and on the other side preventing false
> sysrq detections.
>
> As a preparation to add sysrq_toggle_support() call into uart,
> remove a private copy of sysrq_enabled from sysctl - it should reflect
> the actual status of sysrq.
>
> Furthermore, the private copy isn't correct already in case
> sysrq_always_enabled is true. So, remove __sysrq_enabled and use a
> getter-helper sysrq_mask() to check sysrq_key_op enabled status.
>
> Cc: Iurii Zaikin <yzaikin@google.com>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: Luis Chamberlain <mcgrof@kernel.org>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Dmitry Safonov <dima@arista.com>
> ---
>  drivers/tty/sysrq.c   | 12 ++++++++++++
>  include/linux/sysrq.h |  7 +++++++
>  kernel/sysctl.c       | 41 ++++++++++++++++++++++-------------------
>  3 files changed, 41 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
> index f724962a5906..5e0d0813da55 100644
> --- a/drivers/tty/sysrq.c
> +++ b/drivers/tty/sysrq.c
> @@ -63,6 +63,18 @@ static bool sysrq_on(void)
>  	return sysrq_enabled || sysrq_always_enabled;
>  }
>  
> +/**
> + * sysrq_mask - Getter for sysrq_enabled mask.
> + *
> + * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise.
> + */
> +int sysrq_mask(void)
> +{
> +	if (sysrq_always_enabled)
> +		return 1;
> +	return sysrq_enabled;
> +}

This seems to have broken several configs, when serial_core is modular, with:

  ERROR: modpost: "sysrq_mask" [drivers/tty/serial/serial_core.ko] undefined!

See:

  http://kisskb.ellerman.id.au/kisskb/buildresult/14169386/

It's also being reported by the kernelci bot:

  https://lore.kernel.org/linux-next/5e677bd0.1c69fb81.c43fe.7f7d@mx.google.com/


cheers

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy
  2020-04-01 12:22   ` Michael Ellerman
@ 2020-04-01 14:41     ` Dmitry Safonov
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Safonov @ 2020-04-01 14:41 UTC (permalink / raw)
  To: Michael Ellerman, linux-kernel
  Cc: Dmitry Safonov, Greg Kroah-Hartman, Iurii Zaikin, Jiri Slaby,
	Joe Perches, Randy Dunlap, Vasiliy Khoruzhick, linux-serial,
	Luis Chamberlain, Kees Cook, linux-fsdevel

Hi Michael,

On 4/1/20 1:22 PM, Michael Ellerman wrote:
[..]
>>  
>> +/**
>> + * sysrq_mask - Getter for sysrq_enabled mask.
>> + *
>> + * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise.
>> + */
>> +int sysrq_mask(void)
>> +{
>> +	if (sysrq_always_enabled)
>> +		return 1;
>> +	return sysrq_enabled;
>> +}
> 
> This seems to have broken several configs, when serial_core is modular, with:
> 
>   ERROR: modpost: "sysrq_mask" [drivers/tty/serial/serial_core.ko] undefined!
> 
> See:
> 
>   http://kisskb.ellerman.id.au/kisskb/buildresult/14169386/
> 
> It's also being reported by the kernelci bot:
> 
>   https://lore.kernel.org/linux-next/5e677bd0.1c69fb81.c43fe.7f7d@mx.google.com/


Thanks for reporting this,

I've reproduced it and sent a fix:
https://lkml.kernel.org/r/20200401143904.423450-1-dima@arista.com

Thanks,
          Dmitry

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-04-01 14:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-02 17:51 [PATCHv3 0/2] serial/sysrq: Add MAGIC_SYSRQ_SERIAL_SEQUENCE Dmitry Safonov
2020-03-02 17:51 ` [PATCHv3 1/2] sysctl/sysrq: Remove __sysrq_enabled copy Dmitry Safonov
2020-04-01 12:22   ` Michael Ellerman
2020-04-01 14:41     ` Dmitry Safonov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).