1. 02 8月, 2017 1 次提交
  2. 30 7月, 2017 2 次提交
    • A
      tty: improve tty_insert_flip_char() slow path · 065ea0a7
      Arnd Bergmann 提交于
      While working on improving the fast path of tty_insert_flip_char(),
      I noticed that by calling tty_buffer_request_room(), we needlessly
      move to the separate flag buffer mode for the tty, even when all
      characters use TTY_NORMAL as the flag.
      
      This changes the code to call __tty_buffer_request_room() with the
      correct flag, which will then allocate a regular buffer when it rounds
      out of space but no special flags have been used. I'm guessing that
      this is the behavior that Peter Hurley intended when he introduced
      the compacted flip buffers.
      
      Fixes: acc0f67f ("tty: Halve flip buffer GFP_ATOMIC memory consumption")
      Cc: Peter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      065ea0a7
    • A
      tty: improve tty_insert_flip_char() fast path · 979990c6
      Arnd Bergmann 提交于
      kernelci.org reports a crazy stack usage for the VT code when CONFIG_KASAN
      is enabled:
      
      drivers/tty/vt/keyboard.c: In function 'kbd_keycode':
      drivers/tty/vt/keyboard.c:1452:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
      
      The problem is that tty_insert_flip_char() gets inlined many times into
      kbd_keycode(), and also into other functions, and each copy requires 128
      bytes for stack redzone to check for a possible out-of-bounds access on
      the 'ch' and 'flags' arguments that are passed into
      tty_insert_flip_string_flags as a variable-length string.
      
      This introduces a new __tty_insert_flip_char() function for the slow
      path, which receives the two arguments by value. This completely avoids
      the problem and the stack usage goes back down to around 100 bytes.
      
      Without KASAN, this is also slightly better, as we don't have to
      spill the arguments to the stack but can simply pass 'ch' and 'flag'
      in registers, saving a few bytes in .text for each call site.
      
      This should be backported to linux-4.0 or later, which first introduced
      the stack sanitizer in the kernel.
      
      Cc: stable@vger.kernel.org
      Fixes: c420f167 ("kasan: enable stack instrumentation")
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      979990c6
  3. 03 2月, 2017 1 次提交
  4. 20 1月, 2017 1 次提交
  5. 02 5月, 2016 1 次提交
  6. 29 1月, 2016 1 次提交
  7. 13 12月, 2015 1 次提交
    • P
      tty: Fix GPF in flush_to_ldisc() · 9ce119f3
      Peter Hurley 提交于
      A line discipline which does not define a receive_buf() method can
      can cause a GPF if data is ever received [1]. Oddly, this was known
      to the author of n_tracesink in 2011, but never fixed.
      
      [1] GPF report
          BUG: unable to handle kernel NULL pointer dereference at           (null)
          IP: [<          (null)>]           (null)
          PGD 3752d067 PUD 37a7b067 PMD 0
          Oops: 0010 [#1] SMP KASAN
          Modules linked in:
          CPU: 2 PID: 148 Comm: kworker/u10:2 Not tainted 4.4.0-rc2+ #51
          Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
          Workqueue: events_unbound flush_to_ldisc
          task: ffff88006da94440 ti: ffff88006db60000 task.ti: ffff88006db60000
          RIP: 0010:[<0000000000000000>]  [<          (null)>]           (null)
          RSP: 0018:ffff88006db67b50  EFLAGS: 00010246
          RAX: 0000000000000102 RBX: ffff88003ab32f88 RCX: 0000000000000102
          RDX: 0000000000000000 RSI: ffff88003ab330a6 RDI: ffff88003aabd388
          RBP: ffff88006db67c48 R08: ffff88003ab32f9c R09: ffff88003ab31fb0
          R10: ffff88003ab32fa8 R11: 0000000000000000 R12: dffffc0000000000
          R13: ffff88006db67c20 R14: ffffffff863df820 R15: ffff88003ab31fb8
          FS:  0000000000000000(0000) GS:ffff88006dc00000(0000) knlGS:0000000000000000
          CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
          CR2: 0000000000000000 CR3: 0000000037938000 CR4: 00000000000006e0
          Stack:
           ffffffff829f46f1 ffff88006da94bf8 ffff88006da94bf8 0000000000000000
           ffff88003ab31fb0 ffff88003aabd438 ffff88003ab31ff8 ffff88006430fd90
           ffff88003ab32f9c ffffed0007557a87 1ffff1000db6cf78 ffff88003ab32078
          Call Trace:
           [<ffffffff8127cf91>] process_one_work+0x8f1/0x17a0 kernel/workqueue.c:2030
           [<ffffffff8127df14>] worker_thread+0xd4/0x1180 kernel/workqueue.c:2162
           [<ffffffff8128faaf>] kthread+0x1cf/0x270 drivers/block/aoe/aoecmd.c:1302
           [<ffffffff852a7c2f>] ret_from_fork+0x3f/0x70 arch/x86/entry/entry_64.S:468
          Code:  Bad RIP value.
          RIP  [<          (null)>]           (null)
           RSP <ffff88006db67b50>
          CR2: 0000000000000000
          ---[ end trace a587f8947e54d6ea ]---
      Reported-by: NDmitry Vyukov <dvyukov@google.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9ce119f3
  8. 18 10月, 2015 2 次提交
  9. 05 10月, 2015 3 次提交
  10. 24 7月, 2015 2 次提交
  11. 11 5月, 2015 2 次提交
    • P
      pty: Fix input race when closing · 1a48632f
      Peter Hurley 提交于
      A read() from a pty master may mistakenly indicate EOF (errno == -EIO)
      after the pty slave has closed, even though input data remains to be read.
      For example,
      
             pty slave       |        input worker        |    pty master
                             |                            |
                             |                            |   n_tty_read()
      pty_write()            |                            |     input avail? no
        add data             |                            |     sleep
        schedule worker  --->|                            |     .
                             |---> flush_to_ldisc()       |     .
      pty_close()            |       fill read buffer     |     .
        wait for worker      |       wakeup reader    --->|     .
                             |       read buffer full?    |---> input avail ? yes
                             |<---   yes - exit worker    |     copy 4096 bytes to user
        TTY_OTHER_CLOSED <---|                            |<--- kick worker
                             |                            |
      
      		                **** New read() before worker starts ****
      
                             |                            |   n_tty_read()
                             |                            |     input avail? no
                             |                            |     TTY_OTHER_CLOSED? yes
                             |                            |     return -EIO
      
      Several conditions are required to trigger this race:
      1. the ldisc read buffer must become full so the input worker exits
      2. the read() count parameter must be >= 4096 so the ldisc read buffer
         is empty
      3. the subsequent read() occurs before the kicked worker has processed
         more input
      
      However, the underlying cause of the race is that data is pipelined, while
      tty state is not; ie., data already written by the pty slave end is not
      yet visible to the pty master end, but state changes by the pty slave end
      are visible to the pty master end immediately.
      
      Pipeline the TTY_OTHER_CLOSED state through input worker to the reader.
      1. Introduce TTY_OTHER_DONE which is set by the input worker when
         TTY_OTHER_CLOSED is set and either the input buffers are flushed or
         input processing has completed. Readers/polls are woken when
         TTY_OTHER_DONE is set.
      2. Reader/poll checks TTY_OTHER_DONE instead of TTY_OTHER_CLOSED.
      3. A new input worker is started from pty_close() after setting
         TTY_OTHER_CLOSED, which ensures the TTY_OTHER_DONE state will be
         set if the last input worker is already finished (or just about to
         exit).
      
      Remove tty_flush_to_ldisc(); no in-tree callers.
      
      Fixes: 52bce7f8 ("pty, n_tty: Simplify input processing on final close")
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96311
      BugLink: http://bugs.launchpad.net/bugs/1429756
      Cc: <stable@vger.kernel.org> # 3.19+
      Reported-by: NAndy Whitcroft <apw@canonical.com>
      Reported-by: NH.J. Lu <hjl.tools@gmail.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1a48632f
    • G
      tty: tty_buffer.c: move assignment out of if () block · e16cb0a7
      Greg Kroah-Hartman 提交于
      We should not be doing assignments within an if () block
      so fix up the code to not do this.
      
      change was created using Coccinelle.
      
      CC: Jiri Slaby <jslaby@suse.cz>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e16cb0a7
  12. 03 2月, 2015 1 次提交
    • P
      pty: Fix buffer flush deadlock · 1d1d14da
      Peter Hurley 提交于
      The pty driver does not clear its write buffer when commanded.
      This is to avoid an apparent deadlock between parallel flushes from
      both pty ends; specifically when handling either BRK or INTR input.
      However, parallel flushes from this source is not possible since
      the pty master can never be set to BRKINT or ISIG. Parallel flushes
      from other sources are possible but these do not threaten deadlocks.
      
      Annotate the tty buffer mutex for lockdep to represent the nested
      tty_buffer locking which occurs when the pty slave is processing input
      (its buffer mutex held) and receives INTR or BRK and acquires the
      linked tty buffer mutex via tty_buffer_flush().
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1d1d14da
  13. 06 11月, 2014 1 次提交
    • P
      tty: Flush ldisc buffer atomically with tty flip buffers · 86c80a8e
      Peter Hurley 提交于
      tty_ldisc_flush() first clears the line discipline input buffer,
      then clears the tty flip buffers. However, this allows for existing
      data in the tty flip buffers to be added after the ldisc input
      buffer has been cleared, but before the flip buffers have been cleared.
      
      Add an optional ldisc parameter to tty_buffer_flush() to allow
      tty_ldisc_flush() to pass the ldisc to clear.
      
      NB: Initially, the plan was to do this automatically in
      tty_buffer_flush(). However, an audit of the behavior of existing
      line disciplines showed that performing a ldisc buffer flush on
      ioctl(TCFLSH) was not always the outcome. For example, some line
      disciplines have flush_buffer() methods but not ioctl() methods,
      so a ->flush_buffer() command would be unexpected.
      Reviewed-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      86c80a8e
  14. 24 5月, 2014 1 次提交
  15. 04 5月, 2014 2 次提交
  16. 25 4月, 2014 1 次提交
    • M
      tty: Fix race condition between __tty_buffer_request_room and flush_to_ldisc · 6a20dbd6
      Manfred Schlaegl 提交于
      The race was introduced while development of linux-3.11 by
      e8437d7e and
      e9975fde.
      Originally it was found and reproduced on linux-3.12.15 and
      linux-3.12.15-rt25, by sending 500 byte blocks with 115kbaud to the
      target uart in a loop with 100 milliseconds delay.
      
      In short:
       1. The consumer flush_to_ldisc is on to remove the head tty_buffer.
       2. The producer adds a number of bytes, so that a new tty_buffer must
      	be allocated and added by __tty_buffer_request_room.
       3. The consumer removes the head tty_buffer element, without handling
      	newly committed data.
      
      Detailed example:
       * Initial buffer:
         * Head, Tail -> 0: used=250; commit=250; read=240; next=NULL
       * Consumer: ''flush_to_ldisc''
         * consumed 10 Byte
         * buffer:
           * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL
      {{{
      		count = head->commit - head->read;	// count = 0
      		if (!count) {				// enter
      			// INTERRUPTED BY PRODUCER ->
      			if (head->next == NULL)
      				break;
      			buf->head = head->next;
      			tty_buffer_free(port, head);
      			continue;
      		}
      }}}
       * Producer: tty_insert_flip_... 10 bytes + tty_flip_buffer_push
         * buffer:
           * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL
         * added 6 bytes: head-element filled to maximum.
           * buffer:
             * Head, Tail -> 0: used=256; commit=250; read=250; next=NULL
         * added 4 bytes: __tty_buffer_request_room is called
           * buffer:
             * Head -> 0: used=256; commit=256; read=250; next=1
             * Tail -> 1: used=4; commit=0; read=250 next=NULL
         * push (tty_flip_buffer_push)
           * buffer:
             * Head -> 0: used=256; commit=256; read=250; next=1
             * Tail -> 1: used=4; commit=4; read=250 next=NULL
       * Consumer
      {{{
      		count = head->commit - head->read;
      		if (!count) {
      			// INTERRUPTED BY PRODUCER <-
      			if (head->next == NULL)		// -> no break
      				break;
      			buf->head = head->next;
      			tty_buffer_free(port, head);
      			// ERROR: tty_buffer head freed -> 6 bytes lost
      			continue;
      		}
      }}}
      
      This patch reintroduces a spin_lock to protect this case. Perhaps later
      a lock-less solution could be found.
      Signed-off-by: NManfred Schlaegl <manfred.schlaegl@gmx.at>
      Cc: stable <stable@vger.kernel.org> # 3.11
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6a20dbd6
  17. 01 3月, 2014 1 次提交
    • P
      tty: Fix low_latency BUG · a9c3f68f
      Peter Hurley 提交于
      The user-settable knob, low_latency, has been the source of
      several BUG reports which stem from flush_to_ldisc() running
      in interrupt context. Since 3.12, which added several sleeping
      locks (termios_rwsem and buf->lock) to the input processing path,
      the frequency of these BUG reports has increased.
      
      Note that changes in 3.12 did not introduce this regression;
      sleeping locks were first added to the input processing path
      with the removal of the BKL from N_TTY in commit
      a88a69c9,
      'n_tty: Fix loss of echoed characters and remove bkl from n_tty'
      and later in commit 38db8979,
      'tty: throttling race fix'. Since those changes, executing
      flush_to_ldisc() in interrupt_context (ie, low_latency set), is unsafe.
      
      However, since most devices do not validate if the low_latency
      setting is appropriate for the context (process or interrupt) in
      which they receive data, some reports are due to misconfiguration.
      Further, serial dma devices for which dma fails, resort to
      interrupt receiving as a backup without resetting low_latency.
      
      Historically, low_latency was used to force wake-up the reading
      process rather than wait for the next scheduler tick. The
      effect was to trim multiple milliseconds of latency from
      when the process would receive new data.
      
      Recent tests [1] have shown that the reading process now receives
      data with only 10's of microseconds latency without low_latency set.
      
      Remove the low_latency rx steering from tty_flip_buffer_push();
      however, leave the knob as an optional hint to drivers that can
      tune their rx fifos and such like. Cleanup stale code comments
      regarding low_latency.
      
      [1] https://lkml.org/lkml/2014/2/20/434
      
      "Yay.. thats an annoying historical pain in the butt gone."
      	-- Alan Cox
      Reported-by: NBeat Bolli <bbolli@ewanet.ch>
      Reported-by: NPavel Roskin <proski@gnu.org>
      Acked-by: NDavid Sterba <dsterba@suse.cz>
      Cc: Grant Edwards <grant.b.edwards@gmail.com>
      Cc: Stanislaw Gruszka <sgruszka@redhat.com>
      Cc: Hal Murray <murray+fedora@ip-64-139-1-69.sjc.megapath.net>
      Cc: <stable@vger.kernel.org> # 3.12.x+
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a9c3f68f
  18. 08 1月, 2014 1 次提交
  19. 10 12月, 2013 1 次提交
  20. 09 12月, 2013 5 次提交
  21. 24 7月, 2013 9 次提交