1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| void fork_pte(uint64_t* target_pte, uint64_t* dest_pte) {
for (int i = 0; i < 512; i++) {
if (target_pte[i]) {
uint64_t* target_page = (uint64_t*)((target_pte[i] & PAGE_MASK) | KERNEL_VIRT_BASE);
uint64_t* dest_page = create_page(dest_pte, i);
memcpy((void*)dest_page, (void*)target_page, PAGE_SIZE);
}
}
}
void fork_pmd(uint64_t* target_pmd, uint64_t* dest_pmd) {
for (int i = 0; i < 512; i++) {
if (target_pmd[i]) {
uint64_t* target_pte = (uint64_t*)((target_pmd[i] & PAGE_MASK) | KERNEL_VIRT_BASE);
uint64_t* dest_pte = create_page_table(dest_pmd, i);
fork_pte(target_pte, dest_pte);
}
}
}
void fork_pud(uint64_t* target_pud, uint64_t* dest_pud) {
for (int i = 0; i < 512; i++) {
if (target_pud[i]) {
uint64_t* target_pmd = (uint64_t*)((target_pud[i] & PAGE_MASK) | KERNEL_VIRT_BASE);
uint64_t* dest_pmd = create_page_table(dest_pud, i);
fork_pmd(target_pmd, dest_pmd);
}
}
}
void fork_pgd(struct task_t* target, struct task_t* dest) {
uint64_t* target_pgd = (uint64_t*)((target->mm.pgd & PAGE_MASK) | KERNEL_VIRT_BASE);
uint64_t* dest_pgd = create_pgd(dest);
for (int i = 0; i < 512; i++) {
if (target_pgd[i]) {
uint64_t* target_pud = (uint64_t*)((target_pgd[i] & PAGE_MASK) | KERNEL_VIRT_BASE);
uint64_t* dest_pud = create_page_table(dest_pgd, i);
fork_pud(target_pud, dest_pud);
}
}
}
|