* [vm 0/76] convert remap_page_range() to remap_pfn_range() vs. 2.6.9-rc2-mm3 @ 2004-09-25 6:53 William Lee Irwin III 2004-09-25 6:58 ` [vm 1/76] introduce remap_pfn_range() William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 6:53 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel This series resolves a physical address overflow issue in the remap_page_range() API by replacing it with remap_pfn_range(), which accepts its physical address argument as a pfn, hence allowing the use of a single-precision physical address argument without the risk of overflow at the API boundary. The above issue has hobbled support for various 32-bit architectures, including some embedded systems (ppc440 IIRC), caused persistent portability issues for sound drivers for legacy systems (sparc32; unfortunately this patch alone does not fully resolve those), and according to John Fusco's reports, made drivers for some PCI-X hardware infeasible to port to recent ia32 PAE enterprise systems. With this patch series applied, physical address overflows on 32-bit systems caused directly by remap_page_range() are gone forever, and ca. 100LOC of cut-and-waste driver code are swept out of existence alongside them. vs. 2.6.9-rc2-mm3 and the scheduler header cleanups. The parts touching mm.h should apply with just offsets if those aren't applied beforehand. Successfully tested on x86-64. -- wli P.S.: The existing solution to the sparc32 issue was to pass a double precision representation of the physical address as 2 single- precision arguments in an API (io_remap_page_range()) whose argument corresponding to those two was a single single- precision argument on most/all other architectures. The sparc32-specific issue requires more work beyond these patches to rectify. The most apparent consequence of the API skew is that drivers don't compile on sparc32 when they use io_remap_page_range() due to passing insufficient arguments, or vice-versa for drivers originally written for sparc32. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 1/76] introduce remap_pfn_range() 2004-09-25 6:53 [vm 0/76] convert remap_page_range() to remap_pfn_range() vs. 2.6.9-rc2-mm3 William Lee Irwin III @ 2004-09-25 6:58 ` William Lee Irwin III 2004-09-25 6:59 ` [vm 2/76] convert atyfb.c to use remap_pfn_range() William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 6:58 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel This patch introduces remap_pfn_range(), destined to replace remap_page_range(). In the sequel, the callers of remap_page_range() will be converted one at a time. By using a pfn to specify its physical address argument, remap_pfn_range() resolves a longstanding physical address overflow issue. Index: mm3-2.6.9-rc2/include/linux/mm.h =================================================================== --- mm3-2.6.9-rc2.orig/include/linux/mm.h 2004-09-24 19:17:00.863688360 -0700 +++ mm3-2.6.9-rc2/include/linux/mm.h 2004-09-24 22:01:48.366559448 -0700 @@ -856,8 +856,15 @@ extern struct page * vmalloc_to_page(void *addr); extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write); -extern int remap_page_range(struct vm_area_struct *vma, unsigned long from, - unsigned long to, unsigned long size, pgprot_t prot); +int remap_pfn_range(struct vm_area_struct *, unsigned long, + unsigned long, unsigned long, pgprot_t); + +static inline +int remap_page_range(struct vm_area_struct *vma, unsigned long uvaddr, + unsigned long paddr, unsigned long size, pgprot_t prot) +{ + return remap_pfn_range(vma, uvaddr, paddr >> PAGE_SHIFT, size, prot); +} #ifdef CONFIG_PROC_FS void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); Index: mm3-2.6.9-rc2/mm/memory.c =================================================================== --- mm3-2.6.9-rc2.orig/mm/memory.c 2004-09-24 17:37:15.000000000 -0700 +++ mm3-2.6.9-rc2/mm/memory.c 2004-09-24 21:58:50.300629584 -0700 @@ -945,16 +945,14 @@ * in null mappings (currently treated as "copy-on-access") */ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, pgprot_t prot) + unsigned long pfn, pgprot_t prot) { unsigned long end; - unsigned long pfn; address &= ~PMD_MASK; end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; - pfn = phys_addr >> PAGE_SHIFT; do { BUG_ON(!pte_none(*pte)); if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn))) @@ -966,7 +964,7 @@ } static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, pgprot_t prot) + unsigned long pfn, pgprot_t prot) { unsigned long base, end; @@ -975,12 +973,12 @@ end = address + size; if (end > PGDIR_SIZE) end = PGDIR_SIZE; - phys_addr -= address; + pfn -= address >> PAGE_SHIFT; do { pte_t * pte = pte_alloc_map(mm, pmd, base + address); if (!pte) return -ENOMEM; - remap_pte_range(pte, base + address, end - address, address + phys_addr, prot); + remap_pte_range(pte, base + address, end - address, pfn + (address >> PAGE_SHIFT), prot); pte_unmap(pte); address = (address + PMD_SIZE) & PMD_MASK; pmd++; @@ -989,7 +987,7 @@ } /* Note: this is only safe if the mm semaphore is held when called. */ -int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot) +int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) { int error = 0; pgd_t * dir; @@ -997,7 +995,7 @@ unsigned long end = from + size; struct mm_struct *mm = vma->vm_mm; - phys_addr -= from; + pfn -= from >> PAGE_SHIFT; dir = pgd_offset(mm, from); flush_cache_range(vma, beg, end); if (from >= end) @@ -1009,7 +1007,7 @@ error = -ENOMEM; if (!pmd) break; - error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot); + error = remap_pmd_range(mm, pmd, from, end - from, pfn + (from >> PAGE_SHIFT), prot); if (error) break; from = (from + PGDIR_SIZE) & PGDIR_MASK; @@ -1022,8 +1020,7 @@ spin_unlock(&mm->page_table_lock); return error; } - -EXPORT_SYMBOL(remap_page_range); +EXPORT_SYMBOL(remap_pfn_range); /* * Do pte_mkwrite, but only if the vma says VM_WRITE. We do this when Index: mm3-2.6.9-rc2/mm/nommu.c =================================================================== --- mm3-2.6.9-rc2.orig/mm/nommu.c 2004-09-24 02:10:30.000000000 -0700 +++ mm3-2.6.9-rc2/mm/nommu.c 2004-09-24 22:06:16.400812048 -0700 @@ -560,7 +560,7 @@ return NULL; } -int remap_page_range(struct vm_area_struct *vma, unsigned long from, +int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot) { return -EPERM; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 2/76] convert atyfb.c to use remap_pfn_range() 2004-09-25 6:58 ` [vm 1/76] introduce remap_pfn_range() William Lee Irwin III @ 2004-09-25 6:59 ` William Lee Irwin III 2004-09-25 7:01 ` [vm 3/76] convert gbefb.c " William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 6:59 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel On Fri, Sep 24, 2004 at 11:58:16PM -0700, William Lee Irwin III wrote: > This patch introduces remap_pfn_range(), destined to replace > remap_page_range(). In the sequel, the callers of remap_page_range() > will be converted one at a time. Convert atyfb.c to use remap_pfn_range(). Here (as in numerous other cases) shifting the argument right by PAGE_SHIFT suffices. Index: mm3-2.6.9-rc2/drivers/video/aty/atyfb_base.c =================================================================== --- mm3-2.6.9-rc2.orig/drivers/video/aty/atyfb_base.c 2004-09-24 17:37:14.000000000 -0700 +++ mm3-2.6.9-rc2/drivers/video/aty/atyfb_base.c 2004-09-24 22:07:40.573015928 -0700 @@ -1174,8 +1174,8 @@ ~(par->mmap_map[i].prot_mask); pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; - if (remap_page_range(vma, vma->vm_start + page, map_offset, - map_size, vma->vm_page_prot)) + if (remap_pfn_range(vma, vma->vm_start + page, + map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot)) return -EAGAIN; page += map_size; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 3/76] convert gbefb.c to use remap_pfn_range() 2004-09-25 6:59 ` [vm 2/76] convert atyfb.c to use remap_pfn_range() William Lee Irwin III @ 2004-09-25 7:01 ` William Lee Irwin III 2004-09-25 7:03 ` [vm 4/76] convert sgivwfb.c " William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 7:01 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel On Fri, Sep 24, 2004 at 11:59:59PM -0700, William Lee Irwin III wrote: > Convert atyfb.c to use remap_pfn_range(). Here (as in numerous other > cases) shifting the argument right by PAGE_SHIFT suffices. Conver the SGI GBE framebuffer driver to use remap_pfn_range(). Index: mm3-2.6.9-rc2/drivers/video/gbefb.c =================================================================== --- mm3-2.6.9-rc2.orig/drivers/video/gbefb.c 2004-09-24 02:10:27.000000000 -0700 +++ mm3-2.6.9-rc2/drivers/video/gbefb.c 2004-09-24 22:08:19.215141432 -0700 @@ -1018,8 +1018,8 @@ else phys_size = TILE_SIZE - offset; - if (remap_page_range - (vma, addr, phys_addr, phys_size, vma->vm_page_prot)) + if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT, + phys_size, vma->vm_page_prot)) return -EAGAIN; offset = 0; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 4/76] convert sgivwfb.c to use remap_pfn_range() 2004-09-25 7:01 ` [vm 3/76] convert gbefb.c " William Lee Irwin III @ 2004-09-25 7:03 ` William Lee Irwin III 2004-09-25 7:05 ` [vm 5/76] convert igafb.c " William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 7:03 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel On Sat, Sep 25, 2004 at 12:01:51AM -0700, William Lee Irwin III wrote: > Conver the SGI GBE framebuffer driver to use remap_pfn_range(). Convert the SGI DBE framebuffer driver to use remap_pfn_range(). Index: mm3-2.6.9-rc2/drivers/video/sgivwfb.c =================================================================== --- mm3-2.6.9-rc2.orig/drivers/video/sgivwfb.c 2004-09-24 02:10:27.000000000 -0700 +++ mm3-2.6.9-rc2/drivers/video/sgivwfb.c 2004-09-24 22:08:57.675294600 -0700 @@ -719,8 +719,8 @@ pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD; vma->vm_flags |= VM_IO; - if (remap_page_range - (vma, vma->vm_start, offset, size, vma->vm_page_prot)) + if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, + size, vma->vm_page_prot)) return -EAGAIN; vma->vm_file = file; printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 5/76] convert igafb.c to use remap_pfn_range() 2004-09-25 7:03 ` [vm 4/76] convert sgivwfb.c " William Lee Irwin III @ 2004-09-25 7:05 ` William Lee Irwin III 2004-09-25 7:08 ` [vm 6/76] convert zr36120.c " William Lee Irwin III 0 siblings, 1 reply; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 7:05 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel On Sat, Sep 25, 2004 at 12:03:46AM -0700, William Lee Irwin III wrote: > Convert the SGI DBE framebuffer driver to use remap_pfn_range(). Convert the IGA 1682 framebuffer driver to use remap_pfn_range(). Index: mm3-2.6.9-rc2/drivers/video/igafb.c =================================================================== --- mm3-2.6.9-rc2.orig/drivers/video/igafb.c 2004-09-24 17:37:14.000000000 -0700 +++ mm3-2.6.9-rc2/drivers/video/igafb.c 2004-09-24 22:09:34.845643848 -0700 @@ -262,8 +262,8 @@ pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; - if (remap_page_range(vma, vma->vm_start + page, map_offset, - map_size, vma->vm_page_prot)) + if (remap_pfn_range(vma, vma->vm_start + page, + map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot)) return -EAGAIN; page += map_size; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [vm 6/76] convert zr36120.c to use remap_pfn_range() 2004-09-25 7:05 ` [vm 5/76] convert igafb.c " William Lee Irwin III @ 2004-09-25 7:08 ` William Lee Irwin III 0 siblings, 0 replies; 7+ messages in thread From: William Lee Irwin III @ 2004-09-25 7:08 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel On Sat, Sep 25, 2004 at 12:05:36AM -0700, William Lee Irwin III wrote: > Convert the IGA 1682 framebuffer driver to use remap_pfn_range(). Conver the Zoran 36120/36125 framegrabber driver to use remap_pfn_range(). Index: mm3-2.6.9-rc2/drivers/media/video/zr36120.c =================================================================== --- mm3-2.6.9-rc2.orig/drivers/media/video/zr36120.c 2004-09-24 17:37:19.000000000 -0700 +++ mm3-2.6.9-rc2/drivers/media/video/zr36120.c 2004-09-24 22:10:34.377593616 -0700 @@ -1474,8 +1474,8 @@ /* start mapping the whole shabang to user memory */ pos = (unsigned long)ztv->fbuffer; while (size>0) { - unsigned long page = virt_to_phys((void*)pos); - if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) + unsigned long pfn = virt_to_phys((void*)pos) >> PAGE_SHIFT; + if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; start += PAGE_SIZE; pos += PAGE_SIZE; ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-09-25 7:08 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-09-25 6:53 [vm 0/76] convert remap_page_range() to remap_pfn_range() vs. 2.6.9-rc2-mm3 William Lee Irwin III 2004-09-25 6:58 ` [vm 1/76] introduce remap_pfn_range() William Lee Irwin III 2004-09-25 6:59 ` [vm 2/76] convert atyfb.c to use remap_pfn_range() William Lee Irwin III 2004-09-25 7:01 ` [vm 3/76] convert gbefb.c " William Lee Irwin III 2004-09-25 7:03 ` [vm 4/76] convert sgivwfb.c " William Lee Irwin III 2004-09-25 7:05 ` [vm 5/76] convert igafb.c " William Lee Irwin III 2004-09-25 7:08 ` [vm 6/76] convert zr36120.c " William Lee Irwin III
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox