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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 15 Jul 2014 11:38:38 +0200
From:	Arnd Bergmann <arnd@...db.de>
To:	Ley Foon Tan <lftan@...era.com>
Cc:	linux-arch@...r.kernel.org, linux-kernel@...r.kernel.org,
	linux-doc@...r.kernel.org, lftan.linux@...il.com,
	cltang@...esourcery.com
Subject: Re: [PATCH v2 13/29] nios2: DMA mapping API

On Tuesday 15 July 2014 16:45:40 Ley Foon Tan wrote:

> +static inline void __dma_sync(void *vaddr, size_t size,
> +			      enum dma_data_direction direction)
> +{
> +	switch (direction) {
> +	case DMA_FROM_DEVICE:	/* invalidate cache */
> +		invalidate_dcache_range((unsigned long)vaddr,
> +			(unsigned long)(vaddr + size));
> +		break;
> +	case DMA_TO_DEVICE:	/* flush and invalidate cache */
> +	case DMA_BIDIRECTIONAL:
> +		flush_dcache_range((unsigned long)vaddr,
> +			(unsigned long)(vaddr + size));
> +		break;
> +	default:
> +		BUG();
> +	}
> +}

This seems strange. More on that below.

> +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
> +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
> +
...
> +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
> +				  enum dma_data_direction direction)
> +{
> +	__dma_sync(vaddr, size, direction);
> +}

IIRC dma_cache_sync should be empty if you define dma_alloc_noncoherent
to be the same as dma_alloc_coherent: It's already coherent, so no sync
should be needed. What does the CPU do if you try to invalidate the cache
on a coherent mapping?

> +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
> +			     size_t size, enum dma_data_direction direction)
> +{
> +	BUG_ON(!valid_dma_direction(direction));
> +
> +	__dma_sync(phys_to_virt(dma_handle), size, direction);
> +}
> +EXPORT_SYMBOL(dma_sync_single_for_cpu);
> +
> +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
> +				size_t size, enum dma_data_direction direction)
> +{
> +	BUG_ON(!valid_dma_direction(direction));
> +
> +	__dma_sync(phys_to_virt(dma_handle), size, direction);
> +}
> +EXPORT_SYMBOL(dma_sync_single_for_device);

More importantly: you do the same operation for both _for_cpu and _for_device.
I assume your CPU can never do speculative cache prefetches, so it's not
incorrect, but you do twice the number of invalidations and flushes that
you need. 

Why would you do anything for _for_cpu here?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ