Re: [PATCH] staging: octeon-usb: prevent memory corruption

2014-05-28 Thread Sergey Popov
26.05.2014 23:27, Aaro Koskinen пишет:
 On Fri, May 23, 2014 at 11:17:18AM +0400, Sergey Popov wrote:
 On Sat, Mar 22, 2014 at 01:13:52PM +0400, Sergey Popov wrote:
 scsi 0:0:0:0: Direct-Access SanDisk  Cruzer Facet 1.26 PQ: 0 
 ANSI: 5
 sd 0:0:0:0: [sda] 15633408 512-byte logical blocks: (8.00 GB/7.45 GiB)
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: device descriptor read/64, error -145

 Can you boot with PRINTK_TIME and USB_STORAGE_DEBUG enabled and send
 the logs?

 Hi again. I am very sorry, your email someway lost, probably due to
 misconfiguration of my MUA.

 I have attached new boot log, kernel(now - 3.15_rc2) is configured with
 PRINTK_TIME and USB_STORAGE_DEBUG as you requested.

 Ping. Any news on this issue? Or maybe any clues what triggers this?
 
 Unfortunately I'm not able to reproduce these errors with my HW.
 Do you have a possibility to try a different USB stick/storage?
 Does the stock EdgeRouter Lite USB stick work?
 
 When simulating some errors I noticed there's a case where the driver
 does not recover properly. I'll try to send fixes for that soon.
 But that still doesn't solve why get an error in the first place. :-(

Yep, sometimes, usually on warm reboots kernel does not recognize USB
device at all, but i thought that it could be board problem itself,
cause U-Boot lost it too.

I have tried stock USB stick - unfortunately i have got same errors :-(

-- 
Best regards, Sergey Popov
Gentoo developer
Gentoo Desktop Effects project lead
Gentoo Qt project lead
Gentoo Proxy maintainers project lead



signature.asc
Description: OpenPGP digital signature
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: octeon-usb: prevent memory corruption

2014-05-26 Thread Aaro Koskinen
On Fri, May 23, 2014 at 11:17:18AM +0400, Sergey Popov wrote:
  On Sat, Mar 22, 2014 at 01:13:52PM +0400, Sergey Popov wrote:
  scsi 0:0:0:0: Direct-Access SanDisk  Cruzer Facet 1.26 PQ: 0 
  ANSI: 5
  sd 0:0:0:0: [sda] 15633408 512-byte logical blocks: (8.00 GB/7.45 GiB)
  usb 1-1: reset high-speed USB device number 2 using OcteonUSB
  usb 1-1: reset high-speed USB device number 2 using OcteonUSB
  usb 1-1: device descriptor read/64, error -145
 
  Can you boot with PRINTK_TIME and USB_STORAGE_DEBUG enabled and send
  the logs?
  
  Hi again. I am very sorry, your email someway lost, probably due to
  misconfiguration of my MUA.
  
  I have attached new boot log, kernel(now - 3.15_rc2) is configured with
  PRINTK_TIME and USB_STORAGE_DEBUG as you requested.
 
 Ping. Any news on this issue? Or maybe any clues what triggers this?

Unfortunately I'm not able to reproduce these errors with my HW.
Do you have a possibility to try a different USB stick/storage?
Does the stock EdgeRouter Lite USB stick work?

When simulating some errors I noticed there's a case where the driver
does not recover properly. I'll try to send fixes for that soon.
But that still doesn't solve why get an error in the first place. :-(

A.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: octeon-usb: prevent memory corruption

2014-05-23 Thread Sergey Popov
28.04.2014 20:14, Sergey Popov пишет:
 24.03.2014 01:18, Aaro Koskinen пишет:
 Hi,

 On Sat, Mar 22, 2014 at 01:13:52PM +0400, Sergey Popov wrote:
 scsi 0:0:0:0: Direct-Access SanDisk  Cruzer Facet 1.26 PQ: 0 ANSI: 5
 sd 0:0:0:0: [sda] 15633408 512-byte logical blocks: (8.00 GB/7.45 GiB)
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: device descriptor read/64, error -145

 Can you boot with PRINTK_TIME and USB_STORAGE_DEBUG enabled and send
 the logs?

 A.

 
 Hi again. I am very sorry, your email someway lost, probably due to
 misconfiguration of my MUA.
 
 I have attached new boot log, kernel(now - 3.15_rc2) is configured with
 PRINTK_TIME and USB_STORAGE_DEBUG as you requested.
 
 

Ping. Any news on this issue? Or maybe any clues what triggers this?

-- 
Best regards, Sergey Popov
Gentoo developer
Gentoo Desktop Effects project lead
Gentoo Qt project lead
Gentoo Proxy maintainers project lead



signature.asc
Description: OpenPGP digital signature
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: octeon-usb: prevent memory corruption

2014-04-28 Thread Sergey Popov
24.03.2014 01:18, Aaro Koskinen пишет:
 Hi,
 
 On Sat, Mar 22, 2014 at 01:13:52PM +0400, Sergey Popov wrote:
 scsi 0:0:0:0: Direct-Access SanDisk  Cruzer Facet 1.26 PQ: 0 ANSI: 5
 sd 0:0:0:0: [sda] 15633408 512-byte logical blocks: (8.00 GB/7.45 GiB)
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: reset high-speed USB device number 2 using OcteonUSB
 usb 1-1: device descriptor read/64, error -145
 
 Can you boot with PRINTK_TIME and USB_STORAGE_DEBUG enabled and send
 the logs?
 
 A.
 

Hi again. I am very sorry, your email someway lost, probably due to
misconfiguration of my MUA.

I have attached new boot log, kernel(now - 3.15_rc2) is configured with
PRINTK_TIME and USB_STORAGE_DEBUG as you requested.


-- 
Best regards, Sergey Popov
Gentoo developer
Gentoo Desktop-effects project lead
Gentoo Qt project lead
Gentoo Proxy maintainers project lead
U-Boot 1.1.1 (UBNT Build ID: 4493936-g009d77b) (Build time: Sep 20 2012 - 
15:48:51)

BIST check passed.
UBNT_E100 r1:2, r2:12, serial #: DC9FDB29E401
Core clock: 500 MHz, DDR clock: 266 MHz (532 Mhz data rate)
DRAM:  512 MB
Clearing DRAM... done
Flash:  4 MB
Net:   octeth0, octeth1, octeth2

USB:   (port 0) scanning bus for devices... 1 USB Devices found
   scanning bus for storage devices...
  Device 0: Vendor: SanDisk  Prod.: Cruzer Facet Rev: 1.26
Type: Removable Hard Disk
Capacity: 7633.5 MB = 7.4 GB (15633408 x 512)
 0 
reading vmlinux.64

...
.

..

10988919 bytes read
argv[2]: coremask=0x3
argv[3]: root=/dev/sda2
argv[4]: rootdelay=15
argv[5]: rw
argv[6]: mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom)
argv[7]: net.ifnames=0
argv[8]: console=ttyS0,115200
argv[9]: panic=5
ELF file is 64 bit
Allocating memory for ELF segment: addr: 0x8110 (adjusted to: 
0x110), size 0x8382c0
Allocated memory for ELF segment: addr: 0x8110, size 0x8382c0
Processing PHDR 0
  Loading 7fdf00 bytes at 8110
  Clearing 3a3c0 bytes at 818fdf00
## Loading Linux kernel with entry point: 0x816d7b10 ...
Bootloader: Done loading app on coremask: 0x3
[0.00] Initializing cgroup subsys cpuset
[0.00] Initializing cgroup subsys cpu
[0.00] Initializing cgroup subsys cpuacct
[0.00] Linux version 3.15.0-rc2 (neko@phantom) (gcc version 4.8.2 
(Gentoo 4.8.2 p1.3r1, pie-0.5.8r1) ) #1 SMP Mon Apr 28 20:04:08 MSK 2014
[0.00] CVMSEG size: 2 cache lines (256 bytes)
[0.00] bootconsole [early0] enabled
[0.00] CPU0 revision is: 000d0601 (Cavium Octeon+)
[0.00] Checking for the multiply/shift bug... no.
[0.00] Checking for the daddiu bug... no.
[0.00] Determined physical RAM map:
[0.00]  memory: 0640 @ 01a0 (usable)
[0.00]  memory: 07c0 @ 0820 (usable)
[0.00]  memory: 0fc0 @ 00041000 (usable)
[0.00]  memory: 008382c0 @ 0110 (usable)
[0.00] Wasting 243712 bytes for tracking 4352 unused pages
[0.00] Initrd not found or empty - disabling initrd
[0.00] Using internal Device Tree.
[0.00] software IO TLB [mem 0x0218f000-0x0618f000] (64MB) mapped at 
[8218f000-8618efff]
[0.00] Zone ranges:
[0.00]   DMA32[mem 0x0110-0xefff]
[0.00]   Normal   [mem 0xf000-0x41fbf]
[0.00] Movable zone start for each node
[0.00] Early memory node ranges
[0.00]   node   0: [mem 0x0110-0x01937fff]
[0.00]   node   0: [mem 0x01a0-0x07df]
[0.00]   node   0: [mem 0x0820-0x0fdf]
[0.00]   node   0: [mem 0x41000-0x41fbf]
[0.00] Primary instruction cache 32kB, virtually tagged, 4 way, 64 
sets, linesize 128 bytes.
[0.00] Primary data cache 16kB, 64-way, 2 sets, linesize 128 bytes.
[0.00] PERCPU: Embedded 10 pages/cpu @8622a000 s12032 r8192 
d20736 u40960
[0.00] Built 1 zonelists in Zone order, mobility grouping on.  Total 
pages: 122265
[0.00] Kernel command line:  bootoctlinux $loadaddr coremask=0x3 
root=/dev/sda2 rootdelay=15 rw 
mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom5
[0.00] PID hash table entries: 2048 (order: 2, 16384 bytes)
[0.00] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes)
[0.00] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes)
[0.00] Memory: 413184K/495840K available (6029K kernel code, 530K 
rwdata, 1332K rodata, 272K init, 224K bss, 82656K reserved)
[0.00] Hierarchical RCU implementation.
[0.00]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[0.00] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[0.00] NR_IRQS:512
[7.553957] allocated 2097152 bytes of page_cgroup
[7.558583] please 

Re: [PATCH] staging: octeon-usb: prevent memory corruption

2014-03-21 Thread Thomas Pugliese


On Thu, 20 Mar 2014, Aaro Koskinen wrote:

 octeon-hcd will crash the kernel when SLOB is used. This usually happens
 after the 18-byte control transfer when a device descriptor is read.
 The DMA engine is always transfering full 32-bit words and if the
 transfer is shorter, some random garbage appears after the buffer.
 The problem is not visible with SLUB since it rounds up the allocations
 to word boundary, and the extra bytes will go undetected.
 
 Fix by providing quirk functions for DMA map/unmap that allocate a bigger
 temporary buffer when necessary. Tested by booting EdgeRouter Lite
 to USB stick root file system with SLAB, SLOB and SLUB kernels.
 
 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=72121
 Reported-by: Sergey Popov pinkb...@gentoo.org
 Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi
 ---
  drivers/staging/octeon-usb/octeon-hcd.c | 108 
 
  1 file changed, 108 insertions(+)
 
 diff --git a/drivers/staging/octeon-usb/octeon-hcd.c 
 b/drivers/staging/octeon-usb/octeon-hcd.c
 index 5a001d9..9c152f9 100644
 --- a/drivers/staging/octeon-usb/octeon-hcd.c
 +++ b/drivers/staging/octeon-usb/octeon-hcd.c
 @@ -465,6 +465,112 @@ struct octeon_hcd {
  #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) 
 + ((channel)+1)*0x1000)
  
  /**
 + * struct octeon_temp_buffer - a bounce buffer for USB transfers
 + * @temp_buffer: the newly allocated temporary buffer (including meta-data)
 + * @orig_buffer: the original buffer passed by the USB stack
 + * @data: the newly allocated temporary buffer (excluding meta-data)
 + *
 + * Both the DMA engine and FIFO mode will always transfer full 32-bit words. 
 If
 + * the buffer is too short, we need to allocate a temporary one, and this 
 struct
 + * represents it.
 + */
 +struct octeon_temp_buffer {
 + void *temp_buffer;
 + void *orig_buffer;
 + u8 data[0];
 +};
 +
 +/**
 + * octeon_alloc_temp_buffer - allocate a temporary buffer for USB transfer
 + *(if needed)
 + * @urb: URB.
 + * @mem_flags:   Memory allocation flags.
 + *
 + * This function allocates a temporary bounce buffer whenever it's needed
 + * due to HW limitations.
 + */
 +static int octeon_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
 +{
 + struct octeon_temp_buffer *temp;
 +
 + if (urb-num_sgs || urb-sg ||
 + (urb-transfer_flags  URB_NO_TRANSFER_DMA_MAP) ||
 + !(urb-transfer_buffer_length % sizeof(u32)))
 + return 0;
 +
 + temp = kmalloc(ALIGN(urb-transfer_buffer_length, sizeof(u32)) +
 +sizeof(*temp), mem_flags);
 + if (!temp)
 + return -ENOMEM;
 +
 + temp-temp_buffer = temp;
 + temp-orig_buffer = urb-transfer_buffer;
 + if (usb_urb_dir_out(urb))
 + memcpy(temp-data, urb-transfer_buffer,
 +urb-transfer_buffer_length);
 + urb-transfer_buffer = temp-data;
 + urb-transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
 +
 + return 0;
 +}
 +
 

I don't think you need the temp_buffer in struct octeon_temp_buffer.  
Once you have temp in octeon_free_temp_buffer via container_of, just free 
temp.  There is no need to look at temp_buffer to get its address.

Thomas Pugliese
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH] staging: octeon-usb: prevent memory corruption

2014-03-20 Thread David Laight
From: Aaro Koskinen
 octeon-hcd will crash the kernel when SLOB is used. This usually happens
 after the 18-byte control transfer when a device descriptor is read.
 The DMA engine is always transfering full 32-bit words and if the
 transfer is shorter, some random garbage appears after the buffer.
 The problem is not visible with SLUB since it rounds up the allocations
 to word boundary, and the extra bytes will go undetected.
 
 Fix by providing quirk functions for DMA map/unmap that allocate a bigger
 temporary buffer when necessary. Tested by booting EdgeRouter Lite
 to USB stick root file system with SLAB, SLOB and SLUB kernels.

Wouldn't it be simpler to just round up the existing allocation?
(With a comment that some DMA controllers write whole words.)

David



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: octeon-usb: prevent memory corruption

2014-03-19 Thread Aaro Koskinen
octeon-hcd will crash the kernel when SLOB is used. This usually happens
after the 18-byte control transfer when a device descriptor is read.
The DMA engine is always transfering full 32-bit words and if the
transfer is shorter, some random garbage appears after the buffer.
The problem is not visible with SLUB since it rounds up the allocations
to word boundary, and the extra bytes will go undetected.

Fix by providing quirk functions for DMA map/unmap that allocate a bigger
temporary buffer when necessary. Tested by booting EdgeRouter Lite
to USB stick root file system with SLAB, SLOB and SLUB kernels.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=72121
Reported-by: Sergey Popov pinkb...@gentoo.org
Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi
---
 drivers/staging/octeon-usb/octeon-hcd.c | 108 
 1 file changed, 108 insertions(+)

diff --git a/drivers/staging/octeon-usb/octeon-hcd.c 
b/drivers/staging/octeon-usb/octeon-hcd.c
index 5a001d9..9c152f9 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -465,6 +465,112 @@ struct octeon_hcd {
 #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + 
((channel)+1)*0x1000)
 
 /**
+ * struct octeon_temp_buffer - a bounce buffer for USB transfers
+ * @temp_buffer: the newly allocated temporary buffer (including meta-data)
+ * @orig_buffer: the original buffer passed by the USB stack
+ * @data:   the newly allocated temporary buffer (excluding meta-data)
+ *
+ * Both the DMA engine and FIFO mode will always transfer full 32-bit words. If
+ * the buffer is too short, we need to allocate a temporary one, and this 
struct
+ * represents it.
+ */
+struct octeon_temp_buffer {
+   void *temp_buffer;
+   void *orig_buffer;
+   u8 data[0];
+};
+
+/**
+ * octeon_alloc_temp_buffer - allocate a temporary buffer for USB transfer
+ *(if needed)
+ * @urb:   URB.
+ * @mem_flags: Memory allocation flags.
+ *
+ * This function allocates a temporary bounce buffer whenever it's needed
+ * due to HW limitations.
+ */
+static int octeon_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+{
+   struct octeon_temp_buffer *temp;
+
+   if (urb-num_sgs || urb-sg ||
+   (urb-transfer_flags  URB_NO_TRANSFER_DMA_MAP) ||
+   !(urb-transfer_buffer_length % sizeof(u32)))
+   return 0;
+
+   temp = kmalloc(ALIGN(urb-transfer_buffer_length, sizeof(u32)) +
+  sizeof(*temp), mem_flags);
+   if (!temp)
+   return -ENOMEM;
+
+   temp-temp_buffer = temp;
+   temp-orig_buffer = urb-transfer_buffer;
+   if (usb_urb_dir_out(urb))
+   memcpy(temp-data, urb-transfer_buffer,
+  urb-transfer_buffer_length);
+   urb-transfer_buffer = temp-data;
+   urb-transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
+
+   return 0;
+}
+
+/**
+ * octeon_free_temp_buffer - free a temporary buffer used by USB transfers.
+ * @urb: URB.
+ *
+ * Frees a buffer allocated by octeon_alloc_temp_buffer().
+ */
+static void octeon_free_temp_buffer(struct urb *urb)
+{
+   struct octeon_temp_buffer *temp;
+
+   if (!(urb-transfer_flags  URB_ALIGNED_TEMP_BUFFER))
+   return;
+
+   temp = container_of(urb-transfer_buffer, struct octeon_temp_buffer,
+   data);
+   if (usb_urb_dir_in(urb))
+   memcpy(temp-orig_buffer, urb-transfer_buffer,
+  urb-actual_length);
+   urb-transfer_buffer = temp-orig_buffer;
+   urb-transfer_flags = ~URB_ALIGNED_TEMP_BUFFER;
+   kfree(temp-temp_buffer);
+}
+
+/**
+ * octeon_map_urb_for_dma - Octeon-specific map_urb_for_dma().
+ * @hcd:   USB HCD structure.
+ * @urb:   URB.
+ * @mem_flags: Memory allocation flags.
+ */
+static int octeon_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+   int ret;
+
+   ret = octeon_alloc_temp_buffer(urb, mem_flags);
+   if (ret)
+   return ret;
+
+   ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+   if (ret)
+   octeon_free_temp_buffer(urb);
+
+   return ret;
+}
+
+/**
+ * octeon_unmap_urb_for_dma - Octeon-specific unmap_urb_for_dma()
+ * @hcd:   USB HCD structure.
+ * @urb:   URB.
+ */
+static void octeon_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+{
+   usb_hcd_unmap_urb_for_dma(hcd, urb);
+   octeon_free_temp_buffer(urb);
+}
+
+/**
  * Read a USB 32bit CSR. It performs the necessary address swizzle
  * for 32bit CSRs and logs the value in a readable format if
  * debugging is on.
@@ -3369,6 +3475,8 @@ static const struct hc_driver octeon_hc_driver = {
.get_frame_number   = octeon_usb_get_frame_number,
.hub_status_data= octeon_usb_hub_status_data,
.hub_control= octeon_usb_hub_control,
+