diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-06-30 00:21:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-06-30 00:21:34 +0000 |
commit | 3917ac5846dd0f9ad1238166f90caab9912052e6 (patch) | |
tree | 1c298935def4f29edb39192365a65d73de999155 /mm/memory.c | |
parent | af2f803c8b2d469fe38e4a7ce952658dfcb6681a (diff) |
o Merge with Linux 2.1.100.
o Cleanup the machine dependencies of floppy and rtc. The driver for
the Dallas thingy in the Indy is still missing.
o Handle allocation of zero'd pages correct for R4000SC / R4400SC.
o Page colouring shit to match the virtual and physical colour of all
mapped pages. This tends to produce extreme fragmentation problems,
so it's deactivated for now. Users of R4000SC / R4400SC may re-enable
the code in arch/mips/mm/init.c by removing the definition of
CONF_GIVE_A_SHIT_ABOUT_COLOURS. Should get them somewhat further -
but don't shake to hard ...
o Fixed ptrace(2)-ing of syscalls, strace is now working again.
o Fix the interrupt forwarding from the keyboard driver to the psaux
driver, PS/2 mice are now working on the Indy. The fix is somewhat
broken as it prevents generic kernels for Indy and machines which handle
things different.
o Things I can't remember.
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/mm/memory.c b/mm/memory.c index 66cdf0bc1..af4297702 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -61,7 +61,7 @@ void * high_memory = NULL; */ static inline void copy_cow_page(unsigned long from, unsigned long to) { - if (from == ZERO_PAGE) { + if (from == ZERO_PAGE(to)) { clear_page(to); return; } @@ -406,7 +406,8 @@ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long s } } -static inline void zeromap_pte_range(pte_t * pte, unsigned long address, unsigned long size, pte_t zero_pte) +static inline void zeromap_pte_range(pte_t * pte, unsigned long address, + unsigned long size, pgprot_t prot) { unsigned long end; @@ -415,6 +416,8 @@ static inline void zeromap_pte_range(pte_t * pte, unsigned long address, unsigne if (end > PMD_SIZE) end = PMD_SIZE; do { + pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(address), + prot)); pte_t oldpage = *pte; set_pte(pte, zero_pte); forget_pte(oldpage); @@ -423,7 +426,8 @@ static inline void zeromap_pte_range(pte_t * pte, unsigned long address, unsigne } while (address < end); } -static inline int zeromap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size, pte_t zero_pte) +static inline int zeromap_pmd_range(pmd_t * pmd, unsigned long address, + unsigned long size, pgprot_t prot) { unsigned long end; @@ -435,7 +439,7 @@ static inline int zeromap_pmd_range(pmd_t * pmd, unsigned long address, unsigned pte_t * pte = pte_alloc(pmd, address); if (!pte) return -ENOMEM; - zeromap_pte_range(pte, address, end - address, zero_pte); + zeromap_pte_range(pte, address, end - address, prot); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); @@ -448,9 +452,7 @@ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot) pgd_t * dir; unsigned long beg = address; unsigned long end = address + size; - pte_t zero_pte; - zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE, prot)); dir = pgd_offset(current->mm, address); flush_cache_range(current->mm, beg, end); while (address < end) { @@ -458,7 +460,7 @@ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot) error = -ENOMEM; if (!pmd) break; - error = zeromap_pmd_range(pmd, address, end - address, zero_pte); + error = zeromap_pmd_range(pmd, address, end - address, prot); if (error) break; address = (address + PGDIR_SIZE) & PGDIR_MASK; @@ -619,7 +621,7 @@ static void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, struct page * page_map; pte = *page_table; - new_page = __get_free_page(GFP_KERNEL); + new_page = get_user_page(address); /* Did someone else copy this page for us while we slept? */ if (pte_val(*page_table) != pte_val(pte)) goto end_wp_page; @@ -766,7 +768,7 @@ static inline void do_swap_page(struct task_struct * tsk, pte_t page; if (!vma->vm_ops || !vma->vm_ops->swapin) { - swap_in(tsk, vma, page_table, pte_val(entry), write_access); + swap_in(tsk, vma, address, page_table, pte_val(entry), write_access); flush_page_to_ram(pte_page(*page_table)); return; } @@ -838,9 +840,9 @@ static void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, return; anonymous_page: - entry = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot)); + entry = pte_wrprotect(mk_pte(ZERO_PAGE(address), vma->vm_page_prot)); if (write_access) { - unsigned long page = __get_free_page(GFP_KERNEL); + unsigned long page = get_user_page(address); if (!page) goto sigbus; clear_page(page); |