csky: Fixup dma_alloc_coherent with PAGE_SO attribute
authorGuo Ren <ren_guo@c-sky.com>
Tue, 30 Jul 2019 06:43:22 +0000 (14:43 +0800)
committerGuo Ren <ren_guo@c-sky.com>
Wed, 31 Jul 2019 03:05:25 +0000 (11:05 +0800)
This bug is from commit: 2b070ccdf8c0 (fixup abiv2 mmap(... O_SYNC)
failed). In that patch we remove the _PAGE_SO for memory noncache
mapping and this will cause problem when drivers use dma descriptors
to control the transcations without dma_w/rmb().

After referencing other archs' implementation, pgprot_writecombine is
introduced for mmap(... O_SYNC).

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
arch/csky/include/asm/pgtable.h
arch/csky/mm/ioremap.c

index c429a6f347de9d7e9a7b9269fa92ad4b138389af..fc19ba446d6244923148c64443d51970050a7fa6 100644 (file)
@@ -258,6 +258,16 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
 {
        unsigned long prot = pgprot_val(_prot);
 
+       prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED | _PAGE_SO;
+
+       return __pgprot(prot);
+}
+
+#define pgprot_writecombine pgprot_writecombine
+static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
+{
+       unsigned long prot = pgprot_val(_prot);
+
        prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
 
        return __pgprot(prot);
index 8473b6bdf51205b35b761dac33f6456d1216072f..48531115fd9df2412bdf7cf72c30d176c30478dc 100644 (file)
@@ -29,8 +29,7 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
 
        vaddr = (unsigned long)area->addr;
 
-       prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
-                       _PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
+       prot = pgprot_noncached(PAGE_KERNEL);
 
        if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
                free_vm_area(area);
@@ -51,10 +50,9 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
                              unsigned long size, pgprot_t vma_prot)
 {
        if (!pfn_valid(pfn)) {
-               vma_prot.pgprot |= _PAGE_SO;
                return pgprot_noncached(vma_prot);
        } else if (file->f_flags & O_SYNC) {
-               return pgprot_noncached(vma_prot);
+               return pgprot_writecombine(vma_prot);
        }
 
        return vma_prot;