diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-03-21 05:29:39 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-22 04:15:13 -0500 |
commit | 14778d9072e53d2171f66ffd9657daff41acfaed (patch) | |
tree | 3b60565ec1e957800fc3bf4743497202a24f8279 | |
parent | e952f31bce6e9f64db01f607abc46529ba57ac9e (diff) |
[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>
-rw-r--r-- | arch/sparc/mm/generic.c | 1 | ||||
-rw-r--r-- | arch/sparc/mm/loadmmu.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 9 | ||||
-rw-r--r-- | arch/sparc/mm/sun4c.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 2 | ||||
-rw-r--r-- | arch/sparc64/mm/generic.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/drm_vm.c | 1 | ||||
-rw-r--r-- | drivers/sbus/char/flash.c | 3 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 8 | ||||
-rw-r--r-- | drivers/video/sbuslib.c | 2 | ||||
-rw-r--r-- | include/asm-sparc/pgtable.h | 6 |
11 files changed, 29 insertions, 21 deletions
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c index 2cb0728cee05..1ef7fa03fefe 100644 --- a/arch/sparc/mm/generic.c +++ b/arch/sparc/mm/generic.c | |||
@@ -76,7 +76,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, | |||
76 | vma->vm_pgoff = (offset >> PAGE_SHIFT) | | 76 | vma->vm_pgoff = (offset >> PAGE_SHIFT) | |
77 | ((unsigned long)space << 28UL); | 77 | ((unsigned long)space << 28UL); |
78 | 78 | ||
79 | prot = __pgprot(pg_iobits); | ||
80 | offset -= from; | 79 | offset -= from; |
81 | dir = pgd_offset(mm, from); | 80 | dir = pgd_offset(mm, from); |
82 | flush_cache_range(vma, beg, end); | 81 | flush_cache_range(vma, beg, end); |
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c index e9f9571601ba..36b4d24988f8 100644 --- a/arch/sparc/mm/loadmmu.c +++ b/arch/sparc/mm/loadmmu.c | |||
@@ -22,8 +22,6 @@ struct ctx_list *ctx_list_pool; | |||
22 | struct ctx_list ctx_free; | 22 | struct ctx_list ctx_free; |
23 | struct ctx_list ctx_used; | 23 | struct ctx_list ctx_used; |
24 | 24 | ||
25 | unsigned int pg_iobits; | ||
26 | |||
27 | extern void ld_mmu_sun4c(void); | 25 | extern void ld_mmu_sun4c(void); |
28 | extern void ld_mmu_srmmu(void); | 26 | extern void ld_mmu_srmmu(void); |
29 | 27 | ||
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index c664b962987c..27b0e0ba8581 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -2130,6 +2130,13 @@ static unsigned long srmmu_pte_to_pgoff(pte_t pte) | |||
2130 | return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; | 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 | /* Load up routines and constants for sun4m and sun4d mmu */ | 2140 | /* Load up routines and constants for sun4m and sun4d mmu */ |
2134 | void __init ld_mmu_srmmu(void) | 2141 | void __init ld_mmu_srmmu(void) |
2135 | { | 2142 | { |
@@ -2150,9 +2157,9 @@ void __init ld_mmu_srmmu(void) | |||
2150 | BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); | 2157 | BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); |
2151 | BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); | 2158 | BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); |
2152 | page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); | 2159 | page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); |
2153 | pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; | ||
2154 | 2160 | ||
2155 | /* Functions */ | 2161 | /* Functions */ |
2162 | BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM); | ||
2156 | #ifndef CONFIG_SMP | 2163 | #ifndef CONFIG_SMP |
2157 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); | 2164 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); |
2158 | #endif | 2165 | #endif |
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 731f19603cad..49f28c1bdc6d 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c | |||
@@ -1589,7 +1589,10 @@ static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
1589 | 1589 | ||
1590 | static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr) | 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 | |||
1594 | pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | | ||
1595 | _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; | ||
1593 | 1596 | ||
1594 | page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK); | 1597 | page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK); |
1595 | page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT)); | 1598 | page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT)); |
@@ -2134,6 +2137,13 @@ void __init sun4c_paging_init(void) | |||
2134 | printk("SUN4C: %d mmu entries for the kernel\n", cnt); | 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 | /* Load up routines and constants for sun4c mmu */ | 2147 | /* Load up routines and constants for sun4c mmu */ |
2138 | void __init ld_mmu_sun4c(void) | 2148 | void __init ld_mmu_sun4c(void) |
2139 | { | 2149 | { |
@@ -2156,10 +2166,9 @@ void __init ld_mmu_sun4c(void) | |||
2156 | BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); | 2166 | BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); |
2157 | BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); | 2167 | BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); |
2158 | page_kernel = pgprot_val(SUN4C_PAGE_KERNEL); | 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 | /* Functions */ | 2170 | /* Functions */ |
2171 | BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM); | ||
2163 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM); | 2172 | BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM); |
2164 | BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); | 2173 | BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); |
2165 | 2174 | ||
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 95ffa9418620..dfccff29e182 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -656,6 +656,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
656 | __pci_mmap_set_flags(dev, vma, mmap_state); | 656 | __pci_mmap_set_flags(dev, vma, mmap_state); |
657 | __pci_mmap_set_pgprot(dev, vma, mmap_state); | 657 | __pci_mmap_set_pgprot(dev, vma, mmap_state); |
658 | 658 | ||
659 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
659 | ret = io_remap_pfn_range(vma, vma->vm_start, | 660 | ret = io_remap_pfn_range(vma, vma->vm_start, |
660 | vma->vm_pgoff, | 661 | vma->vm_pgoff, |
661 | vma->vm_end - vma->vm_start, | 662 | vma->vm_end - vma->vm_start, |
@@ -663,7 +664,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
663 | if (ret) | 664 | if (ret) |
664 | return ret; | 665 | return ret; |
665 | 666 | ||
666 | vma->vm_flags |= VM_IO; | ||
667 | return 0; | 667 | return 0; |
668 | } | 668 | } |
669 | 669 | ||
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index 5fc5c579e35e..8cb06205d265 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c | |||
@@ -140,7 +140,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, | |||
140 | vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; | 140 | vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; |
141 | vma->vm_pgoff = phys_base >> PAGE_SHIFT; | 141 | vma->vm_pgoff = phys_base >> PAGE_SHIFT; |
142 | 142 | ||
143 | prot = __pgprot(pg_iobits); | ||
144 | offset -= from; | 143 | offset -= from; |
145 | dir = pgd_offset(mm, from); | 144 | dir = pgd_offset(mm, from); |
146 | flush_cache_range(vma, beg, end); | 145 | flush_cache_range(vma, beg, end); |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 0291cd62c69f..ffd0800ed601 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -619,6 +619,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
619 | #endif | 619 | #endif |
620 | offset = dev->driver->get_reg_ofs(dev); | 620 | offset = dev->driver->get_reg_ofs(dev); |
621 | #ifdef __sparc__ | 621 | #ifdef __sparc__ |
622 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
622 | if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, | 623 | if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, |
623 | (map->offset + offset) >> PAGE_SHIFT, | 624 | (map->offset + offset) >> PAGE_SHIFT, |
624 | vma->vm_end - vma->vm_start, | 625 | vma->vm_end - vma->vm_start, |
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 6bdd768b731d..2beb3dded087 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c | |||
@@ -71,9 +71,8 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) | |||
71 | if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) | 71 | if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) |
72 | size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); | 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 | vma->vm_flags |= (VM_SHM | VM_LOCKED); | 74 | vma->vm_flags |= (VM_SHM | VM_LOCKED); |
75 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
77 | 76 | ||
78 | if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) | 77 | if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) |
79 | return -EAGAIN; | 78 | return -EAGAIN; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 996c7b58564e..07d882b14396 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1169,11 +1169,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1169 | vma->vm_pgoff = off >> PAGE_SHIFT; | 1169 | vma->vm_pgoff = off >> PAGE_SHIFT; |
1170 | /* This is an IO map - tell maydump to skip this VMA */ | 1170 | /* This is an IO map - tell maydump to skip this VMA */ |
1171 | vma->vm_flags |= VM_IO | VM_RESERVED; | 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 | #if defined(__mc68000__) | 1172 | #if defined(__mc68000__) |
1178 | #if defined(CONFIG_SUN3) | 1173 | #if defined(CONFIG_SUN3) |
1179 | pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; | 1174 | pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; |
@@ -1195,7 +1190,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1195 | #elif defined(__i386__) || defined(__x86_64__) | 1190 | #elif defined(__i386__) || defined(__x86_64__) |
1196 | if (boot_cpu_data.x86 > 3) | 1191 | if (boot_cpu_data.x86 > 3) |
1197 | pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; | 1192 | pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; |
1198 | #elif defined(__mips__) | 1193 | #elif defined(__mips__) || defined(__sparc_v9__) |
1199 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 1194 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
1200 | #elif defined(__hppa__) | 1195 | #elif defined(__hppa__) |
1201 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; | 1196 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; |
@@ -1212,7 +1207,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1212 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1207 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
1213 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 1208 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
1214 | return -EAGAIN; | 1209 | return -EAGAIN; |
1215 | #endif /* !__sparc_v9__ */ | ||
1216 | return 0; | 1210 | return 0; |
1217 | #endif /* !sparc32 */ | 1211 | #endif /* !sparc32 */ |
1218 | } | 1212 | } |
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index a4d7cc51ce0b..34ef859ee414 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c | |||
@@ -58,6 +58,8 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, | |||
58 | /* To stop the swapper from even considering these pages */ | 58 | /* To stop the swapper from even considering these pages */ |
59 | vma->vm_flags |= (VM_IO | VM_RESERVED); | 59 | vma->vm_flags |= (VM_IO | VM_RESERVED); |
60 | 60 | ||
61 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
62 | |||
61 | /* Each page, see which map applies */ | 63 | /* Each page, see which map applies */ |
62 | for (page = 0; page < size; ){ | 64 | for (page = 0; page < size; ){ |
63 | map_size = 0; | 65 | map_size = 0; |
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index b33c35411e82..9eea8f4d41f0 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h | |||
@@ -269,11 +269,14 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t) | |||
269 | 269 | ||
270 | BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) | 270 | BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) |
271 | BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) | 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 | #define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) | 274 | #define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) |
274 | #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) | 275 | #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) |
275 | #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) | 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 | BTFIXUPDEF_INT(pte_modify_mask) | 280 | BTFIXUPDEF_INT(pte_modify_mask) |
278 | 281 | ||
279 | static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; | 282 | static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; |
@@ -309,9 +312,6 @@ BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long) | |||
309 | #define pte_unmap(pte) do{}while(0) | 312 | #define pte_unmap(pte) do{}while(0) |
310 | #define pte_unmap_nested(pte) do{}while(0) | 313 | #define pte_unmap_nested(pte) do{}while(0) |
311 | 314 | ||
312 | /* The permissions for pgprot_val to make a page mapped on the obio space */ | ||
313 | extern unsigned int pg_iobits; | ||
314 | |||
315 | /* Certain architectures need to do special things when pte's | 315 | /* Certain architectures need to do special things when pte's |
316 | * within a page table are directly modified. Thus, the following | 316 | * within a page table are directly modified. Thus, the following |
317 | * hook is made available. | 317 | * hook is made available. |