Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/mm.h>
- #include <linux/mm_types.h>
- #include <linux/sched.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
- //vaddr_h: vaddr above 4G
- long sys_cr3(unsigned long vaddr_h)
- {
- unsigned long eax;
- unsigned long vaddr=0x10000000 | (vaddr_h & 0xfff);
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd, pmd_n;
- pte_t *pte, *pte_h;
- struct page *page;
- pgprot_t pgprot;
- //get origen page above 4G
- pgd = pgd_offset(current->mm, vaddr_h);
- pud = pud_offset(pgd, vaddr_h);
- pmd = pmd_offset(pud, vaddr_h);
- pgprot = __pgprot(pmd_val(*pmd) & 0xfff);
- pte_h = pte_offset_map(pmd, vaddr_h);
- //mapping vaddr_h above 4G to vaddr below 4G
- //alloc page entry
- pgd = pgd_offset(current->mm, vaddr);
- if(pgd_none(*pgd)) {
- printk("pgd entry not found, alloc new pud and set pgd entry\n");
- /* FIXME */
- //pud = pud_alloc(current->mm, current->mm->pgd, vaddr);
- //set_pud(pgd, *pud);
- pgd = pgd_alloc(current->mm);
- }
- pud = pud_offset(pgd, vaddr);
- if(pud_none(*pud)) {
- printk("pud entry not found, alloc new pmd and set pud entry\n");
- /* FIXME */
- pud = pud_alloc(current->mm, pgd, vaddr);
- }
- pmd = pmd_offset(pud, vaddr);
- if(pmd_none(*pmd)) {
- printk("pmd entry not found, alloc new pte and set pmd entry\n");
- //pmd = pmd_alloc(current->mm, pud, vaddr);
- page = pte_alloc_one(current->mm, vaddr);
- pmd_n = mk_pmd(page, pgprot);
- set_pmd(pmd, pmd_n);
- }
- //pte = page table entry
- pte = pte_offset_map(pmd, vaddr);
- //set new pte as origin pte_h
- set_pte(pte, *pte_h);
- //update_mmu_cache(current->mm->mmap, vaddr, pte);
- //flush_tlb_mm(current->mm);
- }
Add Comment
Please, Sign In to add comment