]> err.no Git - linux-2.6/commitdiff
[PATCH] ppc64: Abolish ioremap_mm
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 22 Jun 2005 00:15:31 +0000 (17:15 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 22 Jun 2005 01:46:26 +0000 (18:46 -0700)
Currently ppc64 has two mm_structs for the kernel, init_mm and also
ioremap_mm.  The latter really isn't necessary: this patch abolishes it,
instead restricting vmallocs to the lower 1TB of the init_mm's range and
placing io mappings in the upper 1TB.  This simplifies the code in a number
of places and eliminates an unecessary set of pagetables.  It also tweaks
the unmap/free path a little, allowing us to remove the unmap_im_area() set
of page table walkers, replacing them with unmap_vm_area().

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/head.S
arch/ppc64/kernel/process.c
arch/ppc64/mm/hash_utils.c
arch/ppc64/mm/imalloc.c
arch/ppc64/mm/init.c
include/asm-ppc64/imalloc.h
include/asm-ppc64/page.h
include/asm-ppc64/pgtable.h
include/asm-ppc64/processor.h

index d63d41f3eecf788b6107269d36df2097075a637f..af5272fedadf4d8f4a2705edd735479dd9d96751 100644 (file)
@@ -505,7 +505,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
        pte_t *ptep;
        unsigned long pa;
 
-       ptep = find_linux_pte(ioremap_mm.pgd, token);
+       ptep = find_linux_pte(init_mm.pgd, token);
        if (!ptep)
                return token;
        pa = pte_pfn(*ptep) << PAGE_SHIFT;
index 346dbf606b5dd910e1a3609d315d96a1a830fa00..02c8f4e3e4bc644f66dbdde07b31544d9063266b 100644 (file)
@@ -2121,10 +2121,6 @@ empty_zero_page:
 swapper_pg_dir:
        .space  4096
 
-       .globl  ioremap_dir
-ioremap_dir:
-       .space  4096
-
 #ifdef CONFIG_SMP
 /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
        .globl  stab_array
index cdfecbeb331f58d586edd4b85aa58212f859d872..aba89554d89df912f268e465fab3f74f5cb7e90f 100644 (file)
@@ -58,14 +58,6 @@ struct task_struct *last_task_used_math = NULL;
 struct task_struct *last_task_used_altivec = NULL;
 #endif
 
-struct mm_struct ioremap_mm = {
-       .pgd            = ioremap_dir,
-       .mm_users       = ATOMIC_INIT(2),
-       .mm_count       = ATOMIC_INIT(1),
-       .cpu_vm_mask    = CPU_MASK_ALL,
-       .page_table_lock = SPIN_LOCK_UNLOCKED,
-};
-
 /*
  * Make sure the floating-point register state in the
  * the thread_struct is up to date for task tsk.
index 0a0f97008d02bc383e2b45aaf10cab443dea9561..87d0525f56fa03ffc84da6d4d8f607e197113afb 100644 (file)
@@ -310,10 +310,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
 
                vsid = get_vsid(mm->context.id, ea);
                break;
-       case IO_REGION_ID:
-               mm = &ioremap_mm;
-               vsid = get_kernel_vsid(ea);
-               break;
        case VMALLOC_REGION_ID:
                mm = &init_mm;
                vsid = get_kernel_vsid(ea);
index cb8727f3267a1c252b1f4d3d7fe1e498a210d3b4..b6e75b891ac0fef5a2aa9dea4152b2c2ea2b998b 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/semaphore.h>
 #include <asm/imalloc.h>
+#include <asm/cacheflush.h>
 
 static DECLARE_MUTEX(imlist_sem);
 struct vm_struct * imlist = NULL;
@@ -285,29 +286,32 @@ struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
        return area;
 }
 
-unsigned long im_free(void * addr)
+void im_free(void * addr)
 {
        struct vm_struct **p, *tmp;
-       unsigned long ret_size = 0;
   
        if (!addr)
-               return ret_size;
-       if ((PAGE_SIZE-1) & (unsigned long) addr) {
+               return;
+       if ((unsigned long) addr & ~PAGE_MASK) {
                printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__,                        addr);
-               return ret_size;
+               return;
        }
        down(&imlist_sem);
        for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
                if (tmp->addr == addr) {
-                       ret_size = tmp->size;
                        *p = tmp->next;
+
+                       /* XXX: do we need the lock? */
+                       spin_lock(&init_mm.page_table_lock);
+                       unmap_vm_area(tmp);
+                       spin_unlock(&init_mm.page_table_lock);
+
                        kfree(tmp);
                        up(&imlist_sem);
-                       return ret_size;
+                       return;
                }
        }
        up(&imlist_sem);
        printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
                        addr);
-       return ret_size;
 }
index 4b42aff74d7312e7f2cdad4aa58dcdaa13a04e1b..6fa1e6490b5747d9ece0de44a9ae4828156a4597 100644 (file)
@@ -73,9 +73,6 @@ static unsigned long phbs_io_bot = PHBS_IO_BASE;
 extern pgd_t swapper_pg_dir[];
 extern struct task_struct *current_set[NR_CPUS];
 
-extern pgd_t ioremap_dir[];
-pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
-
 unsigned long klimit = (unsigned long)_end;
 
 unsigned long _SDR1=0;
@@ -137,69 +134,6 @@ void iounmap(volatile void __iomem *addr)
 
 #else
 
-static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr,
-                                 unsigned long end)
-{
-       pte_t *pte;
-
-       pte = pte_offset_kernel(pmd, addr);
-       do {
-               pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte);
-               WARN_ON(!pte_none(ptent) && !pte_present(ptent));
-       } while (pte++, addr += PAGE_SIZE, addr != end);
-}
-
-static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr,
-                                    unsigned long end)
-{
-       pmd_t *pmd;
-       unsigned long next;
-
-       pmd = pmd_offset(pud, addr);
-       do {
-               next = pmd_addr_end(addr, end);
-               if (pmd_none_or_clear_bad(pmd))
-                       continue;
-               unmap_im_area_pte(pmd, addr, next);
-       } while (pmd++, addr = next, addr != end);
-}
-
-static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr,
-                                    unsigned long end)
-{
-       pud_t *pud;
-       unsigned long next;
-
-       pud = pud_offset(pgd, addr);
-       do {
-               next = pud_addr_end(addr, end);
-               if (pud_none_or_clear_bad(pud))
-                       continue;
-               unmap_im_area_pmd(pud, addr, next);
-       } while (pud++, addr = next, addr != end);
-}
-
-static void unmap_im_area(unsigned long addr, unsigned long end)
-{
-       struct mm_struct *mm = &ioremap_mm;
-       unsigned long next;
-       pgd_t *pgd;
-
-       spin_lock(&mm->page_table_lock);
-
-       pgd = pgd_offset_i(addr);
-       flush_cache_vunmap(addr, end);
-       do {
-               next = pgd_addr_end(addr, end);
-               if (pgd_none_or_clear_bad(pgd))
-                       continue;
-               unmap_im_area_pud(pgd, addr, next);
-       } while (pgd++, addr = next, addr != end);
-       flush_tlb_kernel_range(start, end);
-
-       spin_unlock(&mm->page_table_lock);
-}
-
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page adds an entry to the ioremap page table
@@ -214,21 +148,21 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
        unsigned long vsid;
 
        if (mem_init_done) {
-               spin_lock(&ioremap_mm.page_table_lock);
-               pgdp = pgd_offset_i(ea);
-               pudp = pud_alloc(&ioremap_mm, pgdp, ea);
+               spin_lock(&init_mm.page_table_lock);
+               pgdp = pgd_offset_k(ea);
+               pudp = pud_alloc(&init_mm, pgdp, ea);
                if (!pudp)
                        return -ENOMEM;
-               pmdp = pmd_alloc(&ioremap_mm, pudp, ea);
+               pmdp = pmd_alloc(&init_mm, pudp, ea);
                if (!pmdp)
                        return -ENOMEM;
-               ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
+               ptep = pte_alloc_kernel(&init_mm, pmdp, ea);
                if (!ptep)
                        return -ENOMEM;
                pa = abs_to_phys(pa);
-               set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+               set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
                                                          __pgprot(flags)));
-               spin_unlock(&ioremap_mm.page_table_lock);
+               spin_unlock(&init_mm.page_table_lock);
        } else {
                unsigned long va, vpn, hash, hpteg;
 
@@ -267,13 +201,9 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
 
        for (i = 0; i < size; i += PAGE_SIZE)
                if (map_io_page(ea+i, pa+i, flags))
-                       goto failure;
+                       return NULL;
 
        return (void __iomem *) (ea + (addr & ~PAGE_MASK));
- failure:
-       if (mem_init_done)
-               unmap_im_area(ea, ea + size);
-       return NULL;
 }
 
 
@@ -381,19 +311,14 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
  */
 void iounmap(volatile void __iomem *token)
 {
-       unsigned long address, size;
        void *addr;
 
        if (!mem_init_done)
                return;
        
        addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-       
-       if ((size = im_free(addr)) == 0)
-               return;
 
-       address = (unsigned long)addr; 
-       unmap_im_area(address, address + size);
+       im_free(addr);
 }
 
 static int iounmap_subset_regions(unsigned long addr, unsigned long size)
index 3a45e918bf16606a34e0cf1791af858610d2b6d4..e46ff68a6e4184923547153af0853d91bef2264e 100644 (file)
@@ -4,9 +4,9 @@
 /*
  * Define the address range of the imalloc VM area.
  */
-#define PHBS_IO_BASE     IOREGIONBASE
-#define IMALLOC_BASE      (IOREGIONBASE + 0x80000000ul)        /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END       (IOREGIONBASE + EADDR_MASK)
+#define PHBS_IO_BASE     VMALLOC_END
+#define IMALLOC_BASE      (PHBS_IO_BASE + 0x80000000ul)        /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END       (VMALLOC_START + EADDR_MASK)
 
 
 /* imalloc region types */
@@ -18,7 +18,9 @@
 
 extern struct vm_struct * im_get_free_area(unsigned long size);
 extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-                       int region_type);
-unsigned long im_free(void *addr);
+                                     int region_type);
+extern void im_free(void *addr);
+
+extern unsigned long ioremap_bot;
 
 #endif /* _PPC64_IMALLOC_H */
index bcd21789d3b7816e2e53e85dac6515b347c101cd..257d87eb7c34b48066def0c4d172d1df3529b6cb 100644 (file)
@@ -202,9 +202,7 @@ extern u64 ppc64_pft_size;          /* Log 2 of page table size */
 #define PAGE_OFFSET     ASM_CONST(0xC000000000000000)
 #define KERNELBASE      PAGE_OFFSET
 #define VMALLOCBASE     ASM_CONST(0xD000000000000000)
-#define IOREGIONBASE    ASM_CONST(0xE000000000000000)
 
-#define IO_REGION_ID       (IOREGIONBASE >> REGION_SHIFT)
 #define VMALLOC_REGION_ID  (VMALLOCBASE >> REGION_SHIFT)
 #define KERNEL_REGION_ID   (KERNELBASE >> REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
index 264c4f7993be3557a6b5932bf8dcf943b7c8fd8e..46cf61c2ff69a3b920231122402b1405ca0d4fca 100644 (file)
@@ -53,7 +53,8 @@
  * Define the address range of the vmalloc VM area.
  */
 #define VMALLOC_START (0xD000000000000000ul)
-#define VMALLOC_END   (VMALLOC_START + EADDR_MASK)
+#define VMALLOC_SIZE  (0x10000000000UL)
+#define VMALLOC_END   (VMALLOC_START + VMALLOC_SIZE)
 
 /*
  * Bits in a linux-style PTE.  These match the bits in the
@@ -239,9 +240,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
 /* This now only contains the vmalloc pages */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-/* to find an entry in the ioremap page-table-directory */
-#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
-
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -459,15 +457,12 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
 #define __HAVE_ARCH_PTE_SAME
 #define pte_same(A,B)  (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
 
-extern unsigned long ioremap_bot, ioremap_base;
-
 #define pmd_ERROR(e) \
        printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e))
 
 extern pgd_t swapper_pg_dir[];
-extern pgd_t ioremap_dir[];
 
 extern void paging_init(void);
 
index 809c634ba1dfa03e41078b737a3f0be4945f7314..3084099086a820f2d25d13456e86bf258f4ed388 100644 (file)
@@ -429,16 +429,6 @@ struct thread_struct {
        .fpexc_mode = MSR_FE0|MSR_FE1, \
 }
 
-/*
- * Note: the vm_start and vm_end fields here should *not*
- * be in kernel space.  (Could vm_end == vm_start perhaps?)
- */
-#define IOREMAP_MMAP { &ioremap_mm, 0, 0x1000, NULL, \
-                   PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, \
-                   1, NULL, NULL }
-
-extern struct mm_struct ioremap_mm;
-
 /*
  * Return saved PC of a blocked thread. For now, this is the "user" PC
  */