Commit 14778d9072e53d2171f66ffd9657daff41acfaed
1 parent
e952f31bce
[SPARC]: Respect vm_page_prot in io_remap_page_range().
Make sure the callers do a pgprot_noncached() on vma->vm_page_prot. Pointed out by Hugh Dickens. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 11 changed files with 29 additions and 21 deletions Side-by-side Diff
arch/sparc/mm/generic.c
arch/sparc/mm/loadmmu.c
arch/sparc/mm/srmmu.c
... | ... | @@ -2130,6 +2130,13 @@ |
2130 | 2130 | return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; |
2131 | 2131 | } |
2132 | 2132 | |
2133 | +static pgprot_t srmmu_pgprot_noncached(pgprot_t prot) | |
2134 | +{ | |
2135 | + prot &= ~__pgprot(SRMMU_CACHE); | |
2136 | + | |
2137 | + return prot; | |
2138 | +} | |
2139 | + | |
2133 | 2140 | /* Load up routines and constants for sun4m and sun4d mmu */ |
2134 | 2141 | void __init ld_mmu_srmmu(void) |
2135 | 2142 | { |
2136 | 2143 | |
... | ... | @@ -2150,9 +2157,9 @@ |
2150 | 2157 | BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); |
2151 | 2158 | BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); |
2152 | 2159 | page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); |
2153 | - pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; | |
2154 | 2160 | |
2155 | 2161 | /* Functions */ |
2162 | + BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM); | |
2156 | 2163 | #ifndef CONFIG_SMP |
2157 | 2164 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); |
2158 | 2165 | #endif |
arch/sparc/mm/sun4c.c
... | ... | @@ -1589,8 +1589,11 @@ |
1589 | 1589 | |
1590 | 1590 | static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr) |
1591 | 1591 | { |
1592 | - unsigned long page_entry; | |
1592 | + unsigned long page_entry, pg_iobits; | |
1593 | 1593 | |
1594 | + pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | | |
1595 | + _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; | |
1596 | + | |
1594 | 1597 | page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK); |
1595 | 1598 | page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT)); |
1596 | 1599 | sun4c_put_pte(virt_addr, page_entry); |
... | ... | @@ -2134,6 +2137,13 @@ |
2134 | 2137 | printk("SUN4C: %d mmu entries for the kernel\n", cnt); |
2135 | 2138 | } |
2136 | 2139 | |
2140 | +static pgprot_t sun4c_pgprot_noncached(pgprot_t prot) | |
2141 | +{ | |
2142 | + prot |= __pgprot(_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE); | |
2143 | + | |
2144 | + return prot; | |
2145 | +} | |
2146 | + | |
2137 | 2147 | /* Load up routines and constants for sun4c mmu */ |
2138 | 2148 | void __init ld_mmu_sun4c(void) |
2139 | 2149 | { |
2140 | 2150 | |
... | ... | @@ -2156,10 +2166,9 @@ |
2156 | 2166 | BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); |
2157 | 2167 | BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); |
2158 | 2168 | page_kernel = pgprot_val(SUN4C_PAGE_KERNEL); |
2159 | - pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | | |
2160 | - _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; | |
2161 | 2169 | |
2162 | 2170 | /* Functions */ |
2171 | + BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM); | |
2163 | 2172 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM); |
2164 | 2173 | BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); |
2165 | 2174 |
arch/sparc64/kernel/pci.c
... | ... | @@ -656,6 +656,7 @@ |
656 | 656 | __pci_mmap_set_flags(dev, vma, mmap_state); |
657 | 657 | __pci_mmap_set_pgprot(dev, vma, mmap_state); |
658 | 658 | |
659 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
659 | 660 | ret = io_remap_pfn_range(vma, vma->vm_start, |
660 | 661 | vma->vm_pgoff, |
661 | 662 | vma->vm_end - vma->vm_start, |
... | ... | @@ -663,7 +664,6 @@ |
663 | 664 | if (ret) |
664 | 665 | return ret; |
665 | 666 | |
666 | - vma->vm_flags |= VM_IO; | |
667 | 667 | return 0; |
668 | 668 | } |
669 | 669 |
arch/sparc64/mm/generic.c
drivers/char/drm/drm_vm.c
... | ... | @@ -619,6 +619,7 @@ |
619 | 619 | #endif |
620 | 620 | offset = dev->driver->get_reg_ofs(dev); |
621 | 621 | #ifdef __sparc__ |
622 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
622 | 623 | if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, |
623 | 624 | (map->offset + offset) >> PAGE_SHIFT, |
624 | 625 | vma->vm_end - vma->vm_start, |
drivers/sbus/char/flash.c
... | ... | @@ -71,9 +71,8 @@ |
71 | 71 | if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) |
72 | 72 | size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); |
73 | 73 | |
74 | - pgprot_val(vma->vm_page_prot) &= ~(_PAGE_CACHE); | |
75 | - pgprot_val(vma->vm_page_prot) |= _PAGE_E; | |
76 | 74 | vma->vm_flags |= (VM_SHM | VM_LOCKED); |
75 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
77 | 76 | |
78 | 77 | if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) |
79 | 78 | return -EAGAIN; |
drivers/video/fbmem.c
... | ... | @@ -1169,11 +1169,6 @@ |
1169 | 1169 | vma->vm_pgoff = off >> PAGE_SHIFT; |
1170 | 1170 | /* This is an IO map - tell maydump to skip this VMA */ |
1171 | 1171 | vma->vm_flags |= VM_IO | VM_RESERVED; |
1172 | -#if defined(__sparc_v9__) | |
1173 | - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | |
1174 | - vma->vm_end - vma->vm_start, vma->vm_page_prot)) | |
1175 | - return -EAGAIN; | |
1176 | -#else | |
1177 | 1172 | #if defined(__mc68000__) |
1178 | 1173 | #if defined(CONFIG_SUN3) |
1179 | 1174 | pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; |
... | ... | @@ -1195,7 +1190,7 @@ |
1195 | 1190 | #elif defined(__i386__) || defined(__x86_64__) |
1196 | 1191 | if (boot_cpu_data.x86 > 3) |
1197 | 1192 | pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; |
1198 | -#elif defined(__mips__) | |
1193 | +#elif defined(__mips__) || defined(__sparc_v9__) | |
1199 | 1194 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
1200 | 1195 | #elif defined(__hppa__) |
1201 | 1196 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; |
... | ... | @@ -1212,7 +1207,6 @@ |
1212 | 1207 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
1213 | 1208 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
1214 | 1209 | return -EAGAIN; |
1215 | -#endif /* !__sparc_v9__ */ | |
1216 | 1210 | return 0; |
1217 | 1211 | #endif /* !sparc32 */ |
1218 | 1212 | } |
drivers/video/sbuslib.c
... | ... | @@ -58,6 +58,8 @@ |
58 | 58 | /* To stop the swapper from even considering these pages */ |
59 | 59 | vma->vm_flags |= (VM_IO | VM_RESERVED); |
60 | 60 | |
61 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
62 | + | |
61 | 63 | /* Each page, see which map applies */ |
62 | 64 | for (page = 0; page < size; ){ |
63 | 65 | map_size = 0; |
include/asm-sparc/pgtable.h
... | ... | @@ -269,11 +269,14 @@ |
269 | 269 | |
270 | 270 | BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) |
271 | 271 | BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) |
272 | +BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t) | |
272 | 273 | |
273 | 274 | #define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) |
274 | 275 | #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) |
275 | 276 | #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) |
276 | 277 | |
278 | +#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot) | |
279 | + | |
277 | 280 | BTFIXUPDEF_INT(pte_modify_mask) |
278 | 281 | |
279 | 282 | static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; |
... | ... | @@ -308,9 +311,6 @@ |
308 | 311 | |
309 | 312 | #define pte_unmap(pte) do{}while(0) |
310 | 313 | #define pte_unmap_nested(pte) do{}while(0) |
311 | - | |
312 | -/* The permissions for pgprot_val to make a page mapped on the obio space */ | |
313 | -extern unsigned int pg_iobits; | |
314 | 314 | |
315 | 315 | /* Certain architectures need to do special things when pte's |
316 | 316 | * within a page table are directly modified. Thus, the following |