add a function to change the pape permissions

This commit is contained in:
Stefan Lankes 2011-02-24 09:36:05 +01:00
parent ae52943045
commit b4884cde2d
2 changed files with 55 additions and 0 deletions

View file

@ -110,4 +110,9 @@ int get_kernel_pgd(task_t* task);
*/
int get_user_pgd(task_t* task);
/*
* Change the page permission in the page tables of the current task
*/
int change_page_permissions(size_t start, size_t end, uint32_t flags);
#endif

View file

@ -21,6 +21,7 @@
#include <metalsvm/stdio.h>
#include <metalsvm/stdlib.h>
#include <metalsvm/mmu.h>
#include <metalsvm/vma.h>
#include <metalsvm/string.h>
#include <metalsvm/page.h>
#include <metalsvm/spinlock.h>
@ -235,6 +236,55 @@ size_t map_region(task_t* task, size_t viraddr, size_t phyaddr, uint32_t npages,
return ret;
}
int change_page_permissions(size_t start, size_t end, uint32_t flags)
{
uint32_t index1, index2, newflags;
size_t viraddr = start & 0xFFFFF000;
size_t phyaddr;
page_table_t* pgt;
page_dir_t* pgd;
if (BUILTIN_EXPECT(!paging_enabled, 0))
return -EINVAL;
pgd = per_core(current_task)->pgd;
if (BUILTIN_EXPECT(!pgd, 0))
return -EINVAL;
spinlock_lock(per_core(current_task)->pgd_lock);
while (viraddr < end)
{
index1 = viraddr >> 22;
index2 = (viraddr >> 12) & 0x3FF;
while ((viraddr < end) && (index2 < 1024)) {
pgt = (page_table_t*) (page_table_t*) ((KERNEL_SPACE - 1024*PAGE_SIZE + index1*PAGE_SIZE) & 0xFFFFF000);
if (pgt && pgt->entries[index2]) {
phyaddr = pgt->entries[index2] & 0xFFFFF000;
newflags = pgt->entries[index2] & 0xFFF; // get old flags
// update flags
if (!(flags & VMA_WRITE))
newflags &= ~PG_RW;
else
newflags |= PG_RW;
pgt->entries[index2] = (newflags & 0xFFF) | (phyaddr & 0xFFFFF000);
tlb_flush_one_page(viraddr);
}
index2++;
viraddr += PAGE_SIZE;
}
}
spinlock_unlock(per_core(current_task)->pgd_lock);
return 0;
}
/*
* Use the first fit algorithm to find a valid address range
*