summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2010-03-08 12:25:15 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2011-02-17 15:36:52 -0800
commitf3a234342aa4ceb45adf1e11c16b11fdb297300c (patch)
tree2d905818d090890ac58f881837587a708f82b973 /drivers
parent47aab12693ef835f80c1d49f0f24b062dcac629b (diff)
hvc_iucv: allocate memory buffers for IUCV in zone DMA
commit 91a970d9889c7d6f451ee91ed361d0f0119d3778 upstream. The device driver must allocate memory for IUCV buffers with GFP_DMA, because IUCV cannot address memory above 2GB (31bit addresses only). Because the IUCV ignores the higher bits of the address, sending and receiving IUCV data with this driver might cause memory corruptions. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: maximilian attems <max@stro.at>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/hvc_iucv.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index b8a5d654d3d0..b0e168fe1516 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -139,6 +139,8 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
*
* This function allocates a new struct iucv_tty_buffer element and, optionally,
* allocates an internal data buffer with the specified size @size.
+ * The internal data buffer is always allocated with GFP_DMA which is
+ * required for receiving and sending data with IUCV.
* Note: The total message size arises from the internal buffer size and the
* members of the iucv_tty_msg structure.
* The function returns NULL if memory allocation has failed.
@@ -154,7 +156,7 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
if (size > 0) {
bufp->msg.length = MSG_SIZE(size);
- bufp->mbuf = kmalloc(bufp->msg.length, flags);
+ bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
if (!bufp->mbuf) {
mempool_free(bufp, hvc_iucv_mempool);
return NULL;
@@ -237,7 +239,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
if (!rb->mbuf) { /* message not yet received ... */
/* allocate mem to store msg data; if no memory is available
* then leave the buffer on the list and re-try later */
- rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC);
+ rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
if (!rb->mbuf)
return -ENOMEM;