From 2c090f6c7d61d2eeeccb1447d438e9b4f6035e08 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 29 Nov 2005 13:59:03 -0800 Subject: [PATCH] --- yaml --- r: 14783 b: refs/heads/master c: cab3f16febeaf1a60e38159ff578f609f9976544 h: refs/heads/master i: 14781: 88577eccf808f18b8e80421bd8b05289c8201bdb 14779: 6a81c021f78f62927bc55cccf00f1d8c60bcfd6c 14775: 43b68caa42399874e6c00ef87607d7d9b75f116b 14767: b0bc287b32f7202f10d06106bcae1df785bc9fb0 14751: 23f71511f2d0ec9f7122f14b5282773bdedd326b 14719: 029f64605acef7c73cfb46e4720171d0165a78af v: v3 --- [refs] | 2 +- trunk/arch/ia64/kernel/ia64_ksyms.c | 1 - trunk/arch/ia64/kernel/kprobes.c | 2 +- trunk/arch/ia64/kernel/traps.c | 18 ++++++++++ trunk/arch/sparc64/mm/generic.c | 1 + trunk/drivers/message/fusion/mptbase.c | 6 ++-- trunk/drivers/message/fusion/mptbase.h | 2 -- trunk/fs/exec.c | 12 ++++++- trunk/include/asm-ia64/page.h | 3 +- trunk/include/linux/mm.h | 2 -- trunk/mm/fremap.c | 24 +++++++++++-- trunk/mm/memory.c | 48 ++++++++++---------------- 12 files changed, 76 insertions(+), 45 deletions(-) diff --git a/[refs] b/[refs] index 9cacb82accab..06de37303f94 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 92af254a1b7ea8c09ddff83887e5edc1342b37f8 +refs/heads/master: cab3f16febeaf1a60e38159ff578f609f9976544 diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c index 5db9d3bcbbcb..01572814abe4 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -42,7 +42,6 @@ EXPORT_SYMBOL(clear_page); #ifdef CONFIG_VIRTUAL_MEM_MAP #include -EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */ EXPORT_SYMBOL(max_low_pfn); /* defined by bootmem.c, but not exported by generic code */ #endif diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 2895d6e6062f..801eeaeaf3de 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -740,7 +740,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, switch(val) { case DIE_BREAK: /* err is break number from ia64_bad_break() */ - if (args->err == 0x80200 || args->err == 0x80300 || args->err == 0) + if (args->err == 0x80200 || args->err == 0x80300) if (pre_kprobes_handler(args)) ret = NOTIFY_STOP; break; diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index d3e0ecb56d62..fba5fdd1f968 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -132,6 +132,24 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) siginfo_t siginfo; int sig, code; + /* break.b always sets cr.iim to 0, which causes problems for + * debuggers. Get the real break number from the original instruction, + * but only for kernel code. User space break.b is left alone, to + * preserve the existing behaviour. All break codings have the same + * format, so there is no need to check the slot type. + */ + if (break_num == 0 && !user_mode(regs)) { + struct ia64_psr *ipsr = ia64_psr(regs); + unsigned long *bundle = (unsigned long *)regs->cr_iip; + unsigned long slot; + switch (ipsr->ri) { + case 0: slot = (bundle[0] >> 5); break; + case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; + default: slot = (bundle[1] >> 23); break; + } + break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); + } + /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; diff --git a/trunk/arch/sparc64/mm/generic.c b/trunk/arch/sparc64/mm/generic.c index d9396c1721cd..580b63da836b 100644 --- a/trunk/arch/sparc64/mm/generic.c +++ b/trunk/arch/sparc64/mm/generic.c @@ -77,6 +77,7 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, BUG_ON(!pte_none(*pte)); set_pte_at(mm, address, pte, entry); address += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; pte++; } while (address < curend); } while (address < end); diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 65c2ec5c421b..74022316fc63 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -91,9 +91,9 @@ static int mfcounter = 0; * Public data... */ int mpt_lan_index = -1; -int mpt_stm_index = -1; +static int mpt_stm_index = -1; -struct proc_dir_entry *mpt_proc_root_dir; +static struct proc_dir_entry *mpt_proc_root_dir; #define WHOINIT_UNKNOWN 0xAA @@ -6271,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume); EXPORT_SYMBOL(mpt_suspend); #endif EXPORT_SYMBOL(ioc_list); -EXPORT_SYMBOL(mpt_proc_root_dir); EXPORT_SYMBOL(mpt_register); EXPORT_SYMBOL(mpt_deregister); EXPORT_SYMBOL(mpt_event_register); @@ -6289,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_print_ioc_summary); EXPORT_SYMBOL(mpt_lan_index); -EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); EXPORT_SYMBOL(mpt_toolbox); diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index 5f5b3fb5b4d7..8ad277a9afa1 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -1006,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); * Public data decl's... */ extern struct list_head ioc_list; -extern struct proc_dir_entry *mpt_proc_root_dir; extern int mpt_lan_index; /* needed by mptlan.c */ -extern int mpt_stm_index; /* needed by mptstm.c */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 22533cce0611..1f8a9fd2c9ed 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -306,6 +306,9 @@ void install_arg_page(struct vm_area_struct *vma, struct page *page, unsigned long address) { struct mm_struct *mm = vma->vm_mm; + pgd_t * pgd; + pud_t * pud; + pmd_t * pmd; pte_t * pte; spinlock_t *ptl; @@ -313,7 +316,14 @@ void install_arg_page(struct vm_area_struct *vma, goto out; flush_dcache_page(page); - pte = get_locked_pte(mm, address, &ptl); + pgd = pgd_offset(mm, address); + pud = pud_alloc(mm, pgd, address); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, address); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, address, &ptl); if (!pte) goto out; if (!pte_none(*pte)) { diff --git a/trunk/include/asm-ia64/page.h b/trunk/include/asm-ia64/page.h index 5e6362a786b7..9dd9da105278 100644 --- a/trunk/include/asm-ia64/page.h +++ b/trunk/include/asm-ia64/page.h @@ -110,9 +110,8 @@ extern int ia64_pfn_valid (unsigned long pfn); # define pfn_to_page(pfn) (mem_map + (pfn)) #elif defined(CONFIG_DISCONTIGMEM) extern struct page *vmem_map; -extern unsigned long min_low_pfn; extern unsigned long max_low_pfn; -# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) +# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map)) # define pfn_to_page(pfn) (vmem_map + (pfn)) #endif diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 0e73f1539d08..74f90d7eb5ef 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -742,8 +742,6 @@ struct shrinker; extern struct shrinker *set_shrinker(int, shrinker_t); extern void remove_shrinker(struct shrinker *shrinker); -extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); - int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address); int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address); int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address); diff --git a/trunk/mm/fremap.c b/trunk/mm/fremap.c index 9f381e58bf44..f851775e09c2 100644 --- a/trunk/mm/fremap.c +++ b/trunk/mm/fremap.c @@ -55,10 +55,20 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma, pgoff_t size; int err = -ENOMEM; pte_t *pte; + pmd_t *pmd; + pud_t *pud; + pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pte = get_locked_pte(mm, addr, &ptl); + pgd = pgd_offset(mm, addr); + pud = pud_alloc(mm, pgd, addr); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); if (!pte) goto out; @@ -100,10 +110,20 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, { int err = -ENOMEM; pte_t *pte; + pmd_t *pmd; + pud_t *pud; + pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pte = get_locked_pte(mm, addr, &ptl); + pgd = pgd_offset(mm, addr); + pud = pud_alloc(mm, pgd, addr); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); if (!pte) goto out; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 5bfa52a98630..990e7dc666f8 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1146,18 +1146,6 @@ int zeromap_page_range(struct vm_area_struct *vma, return err; } -pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) -{ - pgd_t * pgd = pgd_offset(mm, addr); - pud_t * pud = pud_alloc(mm, pgd, addr); - if (pud) { - pmd_t * pmd = pmd_alloc(mm, pgd, addr); - if (pmd) - return pte_alloc_map_lock(mm, pmd, addr, ptl); - } - return NULL; -} - /* * This is the old fallback for page remapping. * @@ -1168,7 +1156,10 @@ pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot) { int retval; - pte_t *pte; + pgd_t * pgd; + pud_t * pud; + pmd_t * pmd; + pte_t * pte; spinlock_t *ptl; retval = -EINVAL; @@ -1176,7 +1167,14 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa goto out; retval = -ENOMEM; flush_dcache_page(page); - pte = get_locked_pte(mm, addr, &ptl); + pgd = pgd_offset(mm, addr); + pud = pud_alloc(mm, pgd, addr); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); if (!pte) goto out; retval = -EBUSY; @@ -1394,15 +1392,8 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo */ if (unlikely(!src)) { void *kaddr = kmap_atomic(dst, KM_USER0); - void __user *uaddr = (void __user *)(va & PAGE_MASK); - - /* - * This really shouldn't fail, because the page is there - * in the page tables. But it might just be unreadable, - * in which case we just give up and fill the result with - * zeroes. - */ - if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) + unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE); + if (left) memset(kaddr, 0, PAGE_SIZE); kunmap_atomic(kaddr, KM_USER0); return; @@ -1433,11 +1424,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, spinlock_t *ptl, pte_t orig_pte) { - struct page *old_page, *new_page; + struct page *old_page, *src_page, *new_page; pte_t entry; int ret = VM_FAULT_MINOR; old_page = vm_normal_page(vma, address, orig_pte); + src_page = old_page; if (!old_page) goto gotten; @@ -1465,7 +1457,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(anon_vma_prepare(vma))) goto oom; - if (old_page == ZERO_PAGE(address)) { + if (src_page == ZERO_PAGE(address)) { new_page = alloc_zeroed_user_highpage(vma, address); if (!new_page) goto oom; @@ -1473,7 +1465,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!new_page) goto oom; - cow_user_page(new_page, old_page, address); + cow_user_page(new_page, src_page, address); } /* @@ -2009,8 +2001,6 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, int anon = 0; pte_unmap(page_table); - BUG_ON(vma->vm_flags & VM_PFNMAP); - if (vma->vm_file) { mapping = vma->vm_file->f_mapping; sequence = mapping->truncate_count; @@ -2043,7 +2033,7 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!page) goto oom; - copy_user_highpage(page, new_page, address); + cow_user_page(page, new_page, address); page_cache_release(new_page); new_page = page; anon = 1;