[REPORT: armv7m/stm32] mmap -6 error on armv7m no-mmu platform
From: dillon min
Date: Wed Jun 03 2020 - 04:07:44 EST
Hi, Christoph Hellwig, folks,
i just writing a driver for stm32f4's dma2d controller(/dev/video0
v4l2-m2m device), got following mmap -6 error
(No such device or address) at user space.
working environment is:
hardware: stm32f469-disco board, ARM Cortex-M4 up to 180MHz with FPU,
ArmV7M, no d-cache, no i-cache
kernel: 5.7.0-rc7 commitid: d16eea2fa5a1ed9bc1788db39a76017916dc7f25
app code:
int fb_fd = open("/dev/fb0", O_RDWR);
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix) < 0) {
perror("ioctl FBIOGET_FSCREENINFO");
close(fb_fd);
return -1;
}
char *fbuffer = mmap(NULL,
fix.smem_len,
PROT_READ | PROT_WRITE, MAP_SHARED,
fb_fd,
0);
if (fbuffer == MAP_FAILED) {
perror("mmap framebuffer");
close(fb_fd);
return -1;
}
also tried mmap /dev/fb0 to userspace , get the same error.
after some debug, it's seems some side effect created by
Fixes: 34dc0ea6bc96 ("dma-direct: provide mmap and get_sgtable method
overrides")
arch/arm/mm/dma-mapping-nommu.c
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *iommu, bool coherent)
{
if (IS_ENABLED(CONFIG_CPU_V7M)) {
/*
* Cache support for v7m is optional, so can be treated as
* coherent if no cache has been detected. Note that it is not
* enough to check if MPU is in use or not since in absense of
* MPU system memory map is used.
*/
dev->archdata.dma_coherent = (cacheid) ? coherent : true;
} else {
/*
* Assume coherent DMA in case MMU/MPU has not been set up.
*/
dev->archdata.dma_coherent = (get_cr() & CR_M) ?
coherent : true;
}
if (!dev->archdata.dma_coherent)
set_dma_ops(dev, &arm_nommu_dma_ops);
}
CONFIG_CPU_V7M defined since !MMU,
'cacheid' is 0, 'dev->archdata.dma_coherent' is true, don't call set_dma_ops().
cause get_dma_ops() return NULL. so , dma_is_direct() return true.
kernel/dma/mapping.c
int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
{
const struct dma_map_ops *ops = get_dma_ops(dev);
if (dma_is_direct(ops))
return dma_direct_mmap(dev, vma, cpu_addr, dma_addr, size,
attrs);
if (!ops->mmap)
return -ENXIO;
return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
}
dma_direct_mmap() always return -ENXIO(-6) since CONFIG_MMU wasn't
defined for armv7m arch.
so, dma_mmap_attrs() -> dma_direct_mmap() -> -ENXIO, mmap on no-mmu platform
will get erro -6 all the time.
i'm not sure if there something wrong with my kernel config, so with
.config file attached.
Hi, Alexandre Torgue,
did st's test team verify the dcmi function with recently kernel
version? thanks.
thanks.
best regards.
Dillon,
Attachment:
config.tar.gz
Description: GNU Zip compressed data