<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/linux.git/include/linux/tty.h, branch v3.18.67</title>
<subtitle>Linux Kernel
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.18.67</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.18.67'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/'/>
<updated>2016-04-12T13:10:04Z</updated>
<entry>
<title>tty: Fix GPF in flush_to_ldisc(), part 2</title>
<updated>2016-04-12T13:10:04Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2016-01-11T04:36:12Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=f2f1ca55069617cf85bca3f5f61b4aed9a9866b6'/>
<id>urn:sha1:f2f1ca55069617cf85bca3f5f61b4aed9a9866b6</id>
<content type='text'>
[ Upstream commit f33798deecbd59a2955f40ac0ae2bc7dff54c069 ]

commit 9ce119f318ba ("tty: Fix GPF in flush_to_ldisc()") fixed a
GPF caused by a line discipline which does not define a receive_buf()
method.

However, the vt driver (and speakup driver also) pushes selection
data directly to the line discipline receive_buf() method via
tty_ldisc_receive_buf(). Fix the same problem in tty_ldisc_receive_buf().

Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
</entry>
<entry>
<title>tty: Fix width of unsigned long bitfield padding</title>
<updated>2014-09-25T10:17:25Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-24T10:26:21Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=cc952e7017fa2e8871ee6a94f2c606ff5911f61e'/>
<id>urn:sha1:cc952e7017fa2e8871ee6a94f2c606ff5911f61e</id>
<content type='text'>
Commit c545b66c6922b002b5fe224a6eaec58c913650b5,
'tty: Serialize tcflow() with other tty flow control changes' and
commit 99416322dd16b810ba74098cc50ef2a844091d35,
'tty: Workaround Alpha non-atomic byte storage in tty_struct' work around
compiler bugs and non-atomic storage on multiple arches by padding
bitfields out to the declared type which is unsigned long. However, the
width varies by arch.

Pad bitfields to actual width of unsigned long (which is BITS_PER_LONG).

Reported-by: Fengguang Wu &lt;fengguang.wu@intel.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Workaround Alpha non-atomic byte storage in tty_struct</title>
<updated>2014-09-24T04:19:36Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-10T19:06:36Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=99416322dd16b810ba74098cc50ef2a844091d35'/>
<id>urn:sha1:99416322dd16b810ba74098cc50ef2a844091d35</id>
<content type='text'>
The Alpha EV4/EV5 cpus can corrupt adjacent byte and short data because
those cpus use RMW to store byte and short data. Thus, concurrent adjacent
byte stores could become corrupted, if serialized by a different lock.
tty_struct uses different locks to protect certain fields within the
structure, and thus is vulnerable to byte stores which are not atomic.

Merge the -&gt;ctrl_status byte and packet mode bit, both protected by the
-&gt;ctrl_lock, into an unsigned long.

The padding bits are necessary to force the compiler to allocate the
type specified; otherwise, gcc will ignore the type specifier and
allocate the minimum number of bytes required to store the bitfield.
In turn, this would allow Alpha EV4/EV5 cpus to corrupt adjacent byte
or short storage (because those cpus use RMW to store byte and short data).

gcc versions &lt; 4.7.2 will also corrupt storage adjacent to bitfields
smaller than unsigned long on ia64, ppc64, hppa64, and sparc64, thus
requiring more than unsigned int storage (which would otherwise be
sufficient to fix the Alpha non-atomic storage problem).

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Move and rename send_prio_char() as tty_send_xchar()</title>
<updated>2014-09-24T04:19:35Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-10T19:06:34Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=136d5258b2bc4ffae99cb69874a76624c26fbfad'/>
<id>urn:sha1:136d5258b2bc4ffae99cb69874a76624c26fbfad</id>
<content type='text'>
Relocate the file-scope function, send_prio_char(), as a global
helper tty_send_xchar(). Remove the global declarations for
tty_write_lock()/tty_write_unlock(), as these are file-scope only now.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Serialize tcflow() with other tty flow control changes</title>
<updated>2014-09-24T04:19:35Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-10T19:06:33Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=c545b66c6922b002b5fe224a6eaec58c913650b5'/>
<id>urn:sha1:c545b66c6922b002b5fe224a6eaec58c913650b5</id>
<content type='text'>
Use newly-introduced tty-&gt;flow_lock to serialize updates to
tty-&gt;flow_stopped (via tcflow()) and with concurrent tty flow
control changes from other sources.

Merge the storage for -&gt;stopped and -&gt;flow_stopped, now that both
flags are serialized by -&gt;flow_lock.

The padding bits are necessary to force the compiler to allocate the
type specified; otherwise, gcc will ignore the type specifier and
allocate the minimum number of bytes necessary to store the bitfield.
In turn, this would allow Alpha EV4 and EV5 cpus to corrupt adjacent
byte storage because those cpus use RMW to store byte and short data.

gcc versions &lt; 4.7.2 will also corrupt storage adjacent to bitfields
smaller than unsigned long on ia64, ppc64, hppa64 and sparc64, thus
requiring more than unsigned int storage (which would otherwise be
sufficient to workaround the Alpha non-atomic byte/short storage problem).

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Serialize tty flow control changes with flow_lock</title>
<updated>2014-09-24T04:19:35Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-10T19:06:31Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=f9e053dcfc02b0ad29daec8524fb1afe09774976'/>
<id>urn:sha1:f9e053dcfc02b0ad29daec8524fb1afe09774976</id>
<content type='text'>
Without serialization, the flow control state can become inverted
wrt. the actual hardware state. For example,

CPU 0                          | CPU 1
stop_tty()                     |
  lock ctrl_lock               |
  tty-&gt;stopped = 1             |
  unlock ctrl_lock             |
                               | start_tty()
                               |   lock ctrl_lock
                               |   tty-&gt;stopped = 0
                               |   unlock ctrl_lock
                               |   driver-&gt;start()
  driver-&gt;stop()               |

In this case, the flow control state now indicates the tty has
been started, but the actual hardware state has actually been stopped.

Introduce tty-&gt;flow_lock spinlock to serialize tty flow control changes.
Split out unlocked __start_tty()/__stop_tty() flavors for use by
ioctl(TCXONC) in follow-on patch.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Convert tty_struct bitfield to ints</title>
<updated>2014-09-24T04:19:35Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-09-10T19:06:30Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=d7a855bd6ab25d10d5e3b6aeb53d9c57fa17b808'/>
<id>urn:sha1:d7a855bd6ab25d10d5e3b6aeb53d9c57fa17b808</id>
<content type='text'>
The stopped, hw_stopped, flow_stopped and packet bits are smp-unsafe
and interrupt-unsafe. For example,

CPU 0                         | CPU 1
                              |
tty-&gt;flow_stopped = 1         | tty-&gt;hw_stopped = 0

One of these updates will be corrupted, as the bitwise operation
on the bitfield is non-atomic.

Ensure each flag has a separate memory location, so concurrent
updates do not corrupt orthogonal states. Because DEC Alpha EV4 and EV5
cpus (from 1995) perform RMW on smaller-than-machine-word storage,
"separate memory location" must be int instead of byte.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>drivers: tty: Merge alloc_tty_struct and initialize_tty_struct</title>
<updated>2014-07-12T00:54:28Z</updated>
<author>
<name>Rasmus Villemoes</name>
<email>linux@rasmusvillemoes.dk</email>
</author>
<published>2014-07-10T19:01:22Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=2c964a2f4191f2229566895f1a0e85f8339f5dd1'/>
<id>urn:sha1:2c964a2f4191f2229566895f1a0e85f8339f5dd1</id>
<content type='text'>
The two functions alloc_tty_struct and initialize_tty_struct are
always called together. Merge them into alloc_tty_struct, updating its
prototype and the only two callers of these functions.

Signed-off-by: Rasmus Villemoes &lt;linux@rasmusvillemoes.dk&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>Revert "tty: Fix race condition between __tty_buffer_request_room and flush_to_ldisc"</title>
<updated>2014-05-03T22:14:28Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-05-02T14:56:11Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=5fbf1a65dd53ef313783c34a0e93a6e29def6136'/>
<id>urn:sha1:5fbf1a65dd53ef313783c34a0e93a6e29def6136</id>
<content type='text'>
This reverts commit 6a20dbd6caa2358716136144bf524331d70b1e03.

Although the commit correctly identifies an unsafe race condition
between __tty_buffer_request_room() and flush_to_ldisc(), the commit
fixes the race with an unnecessary spinlock in a lockless algorithm.

The follow-on commit, "tty: Fix lockless tty buffer race" fixes
the race locklessly.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Fix race condition between __tty_buffer_request_room and flush_to_ldisc</title>
<updated>2014-04-24T22:18:02Z</updated>
<author>
<name>Manfred Schlaegl</name>
<email>manfred.schlaegl@gmx.at</email>
</author>
<published>2014-04-08T12:42:04Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=6a20dbd6caa2358716136144bf524331d70b1e03'/>
<id>urn:sha1:6a20dbd6caa2358716136144bf524331d70b1e03</id>
<content type='text'>
The race was introduced while development of linux-3.11 by
e8437d7ecbc50198705331449367d401ebb3181f and
e9975fdec0138f1b2a85b9624e41660abd9865d4.
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 -&gt; 0: used=250; commit=250; read=240; next=NULL
 * Consumer: ''flush_to_ldisc''
   * consumed 10 Byte
   * buffer:
     * Head, Tail -&gt; 0: used=250; commit=250; read=250; next=NULL
{{{
		count = head-&gt;commit - head-&gt;read;	// count = 0
		if (!count) {				// enter
			// INTERRUPTED BY PRODUCER -&gt;
			if (head-&gt;next == NULL)
				break;
			buf-&gt;head = head-&gt;next;
			tty_buffer_free(port, head);
			continue;
		}
}}}
 * Producer: tty_insert_flip_... 10 bytes + tty_flip_buffer_push
   * buffer:
     * Head, Tail -&gt; 0: used=250; commit=250; read=250; next=NULL
   * added 6 bytes: head-element filled to maximum.
     * buffer:
       * Head, Tail -&gt; 0: used=256; commit=250; read=250; next=NULL
   * added 4 bytes: __tty_buffer_request_room is called
     * buffer:
       * Head -&gt; 0: used=256; commit=256; read=250; next=1
       * Tail -&gt; 1: used=4; commit=0; read=250 next=NULL
   * push (tty_flip_buffer_push)
     * buffer:
       * Head -&gt; 0: used=256; commit=256; read=250; next=1
       * Tail -&gt; 1: used=4; commit=4; read=250 next=NULL
 * Consumer
{{{
		count = head-&gt;commit - head-&gt;read;
		if (!count) {
			// INTERRUPTED BY PRODUCER &lt;-
			if (head-&gt;next == NULL)		// -&gt; no break
				break;
			buf-&gt;head = head-&gt;next;
			tty_buffer_free(port, head);
			// ERROR: tty_buffer head freed -&gt; 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: Manfred Schlaegl &lt;manfred.schlaegl@gmx.at&gt;
Cc: stable &lt;stable@vger.kernel.org&gt; # 3.11
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
