diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2014-09-10 23:06:36 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-24 08:19:36 +0400 |
commit | 99416322dd16b810ba74098cc50ef2a844091d35 (patch) | |
tree | 4bc8b94a8d26c609d84953652d47812dbc9e07a6 /include/linux/tty.h | |
parent | c274f6ef1c6665632767d32e4ab912aad839ce27 (diff) | |
download | linux-99416322dd16b810ba74098cc50ef2a844091d35.tar.xz |
tty: Workaround Alpha non-atomic byte storage in tty_struct
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 ->ctrl_status byte and packet mode bit, both protected by the
->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 < 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 <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/tty.h')
-rw-r--r-- | include/linux/tty.h | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h index 4c6b9fd3c750..546e94557895 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -266,8 +266,9 @@ struct tty_struct { flow_stopped:1, unused:62; int hw_stopped; - int packet; - unsigned char ctrl_status; /* ctrl_lock */ + unsigned long ctrl_status:8, /* ctrl_lock */ + packet:1, + unused_ctrl:55; unsigned int receive_room; /* Bytes free for queue */ int flow_change; |