aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c1
-rw-r--r--arch/ia64/kernel/kprobes.c2
-rw-r--r--arch/ia64/kernel/traps.c18
-rw-r--r--drivers/message/fusion/mptbase.c6
-rw-r--r--drivers/message/fusion/mptbase.h2
-rw-r--r--fs/exec.c12
-rw-r--r--include/asm-ia64/page.h3
-rw-r--r--include/linux/mm.h2
-rw-r--r--mm/fremap.c24
-rw-r--r--mm/memory.c48
10 files changed, 44 insertions, 74 deletions
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 01572814abe..5db9d3bcbbc 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -42,6 +42,7 @@ EXPORT_SYMBOL(clear_page);
#ifdef CONFIG_VIRTUAL_MEM_MAP
#include <linux/bootmem.h>
+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/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 801eeaeaf3d..2895d6e6062 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/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)
+ if (args->err == 0x80200 || args->err == 0x80300 || args->err == 0)
if (pre_kprobes_handler(args))
ret = NOTIFY_STOP;
break;
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index fba5fdd1f96..d3e0ecb56d6 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -132,24 +132,6 @@ __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/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 74022316fc6..65c2ec5c421 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -91,9 +91,9 @@ static int mfcounter = 0;
* Public data...
*/
int mpt_lan_index = -1;
-static int mpt_stm_index = -1;
+int mpt_stm_index = -1;
-static struct proc_dir_entry *mpt_proc_root_dir;
+struct proc_dir_entry *mpt_proc_root_dir;
#define WHOINIT_UNKNOWN 0xAA
@@ -6271,6 +6271,7 @@ 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);
@@ -6288,6 +6289,7 @@ 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/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8ad277a9afa..5f5b3fb5b4d 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -1006,8 +1006,10 @@ 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/fs/exec.c b/fs/exec.c
index 1f8a9fd2c9e..22533cce061 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -306,9 +306,6 @@ 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;
@@ -316,14 +313,7 @@ void install_arg_page(struct vm_area_struct *vma,
goto out;
flush_dcache_page(page);
- 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);
+ pte = get_locked_pte(mm, address, &ptl);
if (!pte)
goto out;
if (!pte_none(*pte)) {
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
index 9dd9da10527..5e6362a786b 100644
--- a/include/asm-ia64/page.h
+++ b/include/asm-ia64/page.h
@@ -110,8 +110,9 @@ 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) < max_low_pfn) && ia64_pfn_valid(pfn))
+# define pfn_valid(pfn) (((pfn) >= min_low_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/include/linux/mm.h b/include/linux/mm.h
index 74f90d7eb5e..0e73f1539d0 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -742,6 +742,8 @@ 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/mm/fremap.c b/mm/fremap.c
index f851775e09c..9f381e58bf4 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -55,20 +55,10 @@ 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;
- 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);
+ pte = get_locked_pte(mm, addr, &ptl);
if (!pte)
goto out;
@@ -110,20 +100,10 @@ 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;
- 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);
+ pte = get_locked_pte(mm, addr, &ptl);
if (!pte)
goto out;
diff --git a/mm/memory.c b/mm/memory.c
index 990e7dc666f..5bfa52a9863 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1146,6 +1146,18 @@ 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.
*
@@ -1156,10 +1168,7 @@ int zeromap_page_range(struct vm_area_struct *vma,
static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot)
{
int retval;
- pgd_t * pgd;
- pud_t * pud;
- pmd_t * pmd;
- pte_t * pte;
+ pte_t *pte;
spinlock_t *ptl;
retval = -EINVAL;
@@ -1167,14 +1176,7 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa
goto out;
retval = -ENOMEM;
flush_dcache_page(page);
- 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);
+ pte = get_locked_pte(mm, addr, &ptl);
if (!pte)
goto out;
retval = -EBUSY;
@@ -1392,8 +1394,15 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
*/
if (unlikely(!src)) {
void *kaddr = kmap_atomic(dst, KM_USER0);
- unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE);
- if (left)
+ 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))
memset(kaddr, 0, PAGE_SIZE);
kunmap_atomic(kaddr, KM_USER0);
return;
@@ -1424,12 +1433,11 @@ 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, *src_page, *new_page;
+ struct page *old_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;
@@ -1457,7 +1465,7 @@ gotten:
if (unlikely(anon_vma_prepare(vma)))
goto oom;
- if (src_page == ZERO_PAGE(address)) {
+ if (old_page == ZERO_PAGE(address)) {
new_page = alloc_zeroed_user_highpage(vma, address);
if (!new_page)
goto oom;
@@ -1465,7 +1473,7 @@ gotten:
new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!new_page)
goto oom;
- cow_user_page(new_page, src_page, address);
+ cow_user_page(new_page, old_page, address);
}
/*
@@ -2001,6 +2009,8 @@ 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;
@@ -2033,7 +2043,7 @@ retry:
page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!page)
goto oom;
- cow_user_page(page, new_page, address);
+ copy_user_highpage(page, new_page, address);
page_cache_release(new_page);
new_page = page;
anon = 1;