Просмотр исходного кода

USB: isp1760: Flush the D-cache for the pipe-in transfer buffers

When the HDC driver writes the data to the transfer buffers it pollutes
the D-cache (unlike DMA drivers where the device writes the data). If
the corresponding pages get mapped into user space, there are no
additional cache flushing operations performed and this causes random
user space faults on architectures with separate I and D caches
(Harvard) or those with aliasing D-cache.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Matthew Dharm <mdharm-kernel@one-eyed-alien.net>
Cc: Greg KH <greg@kroah.com>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Catalin Marinas 16 лет назад
Родитель
Сommit
db8516f61b
1 измененных файлов с 10 добавлено и 0 удалено
  1. 10 0
      drivers/usb/host/isp1760-hcd.c

+ 10 - 0
drivers/usb/host/isp1760-hcd.c

@@ -17,7 +17,9 @@
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
+#include <asm/cacheflush.h>
 
 
 #include "../core/hcd.h"
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
 #include "isp1760-hcd.h"
@@ -904,6 +906,14 @@ __acquires(priv->lock)
 			status = 0;
 			status = 0;
 	}
 	}
 
 
+	if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) {
+		void *ptr;
+		for (ptr = urb->transfer_buffer;
+		     ptr < urb->transfer_buffer + urb->transfer_buffer_length;
+		     ptr += PAGE_SIZE)
+			flush_dcache_page(virt_to_page(ptr));
+	}
+
 	/* complete() can reenter this HCD */
 	/* complete() can reenter this HCD */
 	usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
 	usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
 	spin_unlock(&priv->lock);
 	spin_unlock(&priv->lock);