implemented copy_page_map() (more testing needed)
This commit is contained in:
parent
cdcd9e7d20
commit
92b2badf71
1 changed files with 57 additions and 0 deletions
|
@ -101,6 +101,63 @@ static inline size_t map_to_virt(size_t addr)
|
||||||
{
|
{
|
||||||
return canonicalize(addr << (map_to_level(addr) * PAGE_MAP_SHIFT));
|
return canonicalize(addr << (map_to_level(addr) * PAGE_MAP_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy page maps using recursion
|
||||||
|
*
|
||||||
|
* @param from pointer to virtual address of source page tables
|
||||||
|
* @param to pointer to virtual address of destination page tables
|
||||||
|
* @param copy flags what should be copied (see #define COPY_*)
|
||||||
|
* @return number of new allocated page frames (for tables only)
|
||||||
|
*/
|
||||||
|
static int copy_page_map(page_map_t *src, page_map_t *dest, int copy)
|
||||||
|
{
|
||||||
|
page_map_t* next_src, * next_dest;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t i;
|
||||||
|
for(i=0; i<PAGE_MAP_ENTRIES; i++) {
|
||||||
|
if (!(src->entries[i] & PG_PRESENT))
|
||||||
|
// skip empty entries
|
||||||
|
dest->entries[i] = 0;
|
||||||
|
else if (src->entries[i] & PG_USER) {
|
||||||
|
size_t phys;
|
||||||
|
kprintf("d:%p (%s: 0x%012lx) -> %p\n", &src->entries[i], map_to_lvlname((size_t) &src->entries[i]), map_to_virt((size_t) &src->entries[i]), &dest->entries[i]);
|
||||||
|
|
||||||
|
// deep copy user tables
|
||||||
|
if ((size_t) src >= PAGE_PGT) {
|
||||||
|
phys = get_page();
|
||||||
|
if (BUILTIN_EXPECT(!phys, 0))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
dest->entries[i] = phys|(src->entries[i] & ~PAGE_MASK);
|
||||||
|
|
||||||
|
// reuse pointers to next lower page map tables
|
||||||
|
next_src = (page_map_t*) ((size_t) &src->entries[i] << 9);
|
||||||
|
next_dest = (page_map_t*) ((size_t) &dest->entries[i] << 9);
|
||||||
|
|
||||||
|
ret += 1 + copy_page_map(next_src, next_dest, copy);
|
||||||
|
}
|
||||||
|
// deep copy page frame
|
||||||
|
else {
|
||||||
|
if (copy) {
|
||||||
|
phys = copy_page_frame((size_t*) src->entries[i]);
|
||||||
|
dest->entries[i] = phys|(src->entries[i] & ~PAGE_MASK);
|
||||||
|
}
|
||||||
|
kprintf("c: %p (%lx)\n", &src->entries[i], src->entries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// shallow copy kernel only tables
|
||||||
|
else {
|
||||||
|
kprintf("s:%p (%s: 0x%012lx) -> %p\n", &src->entries[i], map_to_lvlname((size_t) &src->entries[i]), map_to_virt((size_t) &src->entries[i]), &dest->entries[i]);
|
||||||
|
dest->entries[i] = src->entries[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kputs("r\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int create_page_map(task_t* task, int copy)
|
int create_page_map(task_t* task, int copy)
|
||||||
{
|
{
|
||||||
size_t phys;
|
size_t phys;
|
||||||
|
|
Loading…
Add table
Reference in a new issue