lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 17 Jun 2015 16:50:10 +0200
From:	Michal Suchanek <hramrach@...il.com>
To:	Vinod Koul <vinod.koul@...el.com>
Cc:	Robert Baldyga <r.baldyga@...sung.com>,
	dmaengine <dmaengine@...r.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	linux-exynos <Linux-exynos@...ux-exynos.org>,
	Catalin Marinas <catalin.marinas@....com>
Subject: Re: pl330 dma failure

H

On 2 June 2015 at 16:17, Michal Suchanek <hramrach@...il.com> wrote:
> On 2 June 2015 at 15:08, Vinod Koul <vinod.koul@...el.com> wrote:
>> On Sat, May 30, 2015 at 09:37:07PM +0200, Michal Suchanek wrote:
>>> Hello,
>>>
>>> I was trying to read the SPI NOR flash and found that the pl330
>>> controller dma mysteriously fails.
>>
>> Adding Robert,
>>
>>>
>>> There is the problem that the 256 bytes of dma program buffer does not
>>> suffice for the whole of 4M of the flash memory so all of it cannot be
>>> possibly transferred in one go with the pl330 driver as is now.
>>>
>>> However, the practical limit is much smaller. At 1MHz or 40MHz the
>>> maximum transfer size that ever finishes is 64k. At 133MHz which is
>>> the rated flash memory clock the maximum transfer size that finishes
>>> is 128 bytes (only tried power of 2).
>>>
>>> There is no obvious issue with the DMA program. 128k happens to be the
>>> smallest size that requires that the burst instruction is repeated in
>>> the cycle and also happens to be the smallest size that fails for any
>>> speed I tried.
>>>
>>> Is there some obvious fix or should I just give up on transferring
>>> more than 64k and make the driver truncate any larger transfers?
>> Well dma controllers cannot transfer any size, the controllers do have
>> limitation on maximum transfer per block. So to transfer more data you need
>> to create descriptor with multiple segments (or driver should split that but
>> not done usually) and worst case multiple transfers.
>
> Hello,
>
> Thanks for your input.
>
> As I understand the pl330 it transfers data according to a program
> executed on the controller.
> The program itself uses DMALDPS/DMASTA instructions which transfers
> data one byte at a time and there are up to 2 loops with 8bit counter
> DMALP.
>
> So the theoretical limit by the program buffer size (256 bytes) is
> about 2Mbytes.
>
> However, the program for transferring 128k (which happens to have two
> DMALDPS/DMASTA instructions in the cycle as opposed to the one
> instruction for transferring 64k) locks up and never (within 10x the
> expected time it should take to complete the transfer) reaches DMASEV
> to signal completion of the DMA transfer. Also subsequent commands on
> on the flash fail probably due to stale data in some FIFO - this can
> be resolved by sending lots of nops to the flash.
>
> There are two problems with this - it is not known in advance what
> amount of data can be transferred without pl330 locking up. It is 64k
> at 40MHz spi and 128bytes at 133MHz spi on my system.
>
> The other problem is that even if the limitation was known there is no
> way to let the upper layer know other than transferring less data than
> requested.
>
> It is also possible to orchestrate many small transactions with DMASEV
> signalling some pl330 function to program new transfer rather than the
> user code that waits for the transfer to finish.

>>> [   60.780206] m25p80 spi1.0: from 0x00000000, len 131072
>>> [   60.780291] s3c64xx_spi_transfer_one 12d30000.spi spi1 spi1.0 xfer
>>> bpw 8 speed 40000000
>>> [   60.780297] s3c64xx_spi_transfer_one 12d30000.spi spi1 spi1.0 not using dma
>>> [   60.780312] s3c64xx_spi_transfer_one 12d30000.spi spi1 spi1.0 xfer
>>> bpw 8 speed 40000000
>>> [   60.780316] s3c64xx_spi_transfer_one 12d30000.spi spi1 spi1.0 using dma
>>> [   60.780327] bc041000:    DMAMOV CCR 0x804200
>>> [   60.780333] bc041006:    DMAMOV SAR 0x12d3001c
>>> [   60.780338] bc04100c:    DMAMOV DAR 0x68020000
>>> [   60.780344] bc041012:    DMALP_0 255
>>> [   60.780349] bc041014:    DMALP_1 255
>>> [   60.780355] bc041016:    DMAWFPS 4
>>> [   60.780360] bc041018:    DMALDPS 4
>>> [   60.780365] bc04101a:    DMASTA
>>> [   60.780370] bc04101b:    DMAFLUSHP 4
>>> [   60.780375] bc04101d:    DMAWFPS 4
>>> [   60.780380] bc04101f:    DMALDPS 4
>>> [   60.780385] bc041021:    DMASTA
>>> [   60.780390] bc041022:    DMAFLUSHP 4
>>> [   60.780395] bc041024:    DMALPENDA_1 bjmpto_e
>>> [   60.780401] bc041026:    DMALPENDA_0 bjmpto_12
>>> [   60.780406] bc041028:    DMASEV 0
>>> [   60.780411] bc04102a:    DMAEND
>>> [   60.780423] wait_for_dma 12d30000.spi spi1 (null) waiting for 72ms
>>> transferring 131072bytes@...00000Hz
>>> [   60.903505] wait_for_dma 12d30000.spi spi1 (null) waited 125 ms
>>> [   60.903518] m25p80 spi1.0: I/O Error: rx-1 tx-0 res:rx-f tx-p len-131072
>>> [   60.903530] m25p80 spi1.0: SPI transfer failed: -5
>>> [   60.903590] spi_master spi1: failed to transfer one message from queue

Hello,

I added more debug prints (and nops in the middle of the dma program
just in case) and clearly the event that is supposed to be produced by
the DMASEV in this program is never delivered for program of this
length. The shorter program with only  one DMALDPS in the loop works.

Attaching a dmesg excerpt.

It has been pointed out that Catalin Marinas might know of some source
of information on this dma controller so adding to CC.

Thanks

Michal

View attachment "pl330-dmesg.txt" of type "text/plain" (14919 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ