blob: b3634fc106fe66ae942084d1d2494e4b103d32d5 (
plain)
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
|
// COW pagefault handler
#include "types.h"
#include "riscv.h"
#include "defs.h"
int
cow_handler(pagetable_t pagetable, uint64 va)
{
// you can't really write to rediculous pointers
if(va >= MAXVA || PGROUNDDOWN(va) == 0)
return -1;
pte_t *pte = walk(pagetable, va, 0);
if(pte == 0 || (*pte & PTE_V) == 0 || (*pte & PTE_U) == 0)
return -1;
if(*pte & PTE_C){
uint64 pa_orig = PTE2PA(*pte);
uint64 pa_new = (uint64)kalloc();
if(pa_new == 0){
printf("cow pagefault: kalloc failed\n");
return -1;
}
// copy the page and add write permission
memmove((void*)pa_new, (void*)pa_orig, PGSIZE);
uint64 flags = (PTE_FLAGS(*pte) | PTE_W) & ~PTE_C;
*pte = PA2PTE(pa_new) | flags;
kfree((void*)pa_orig);
} else if ((*pte & PTE_W) == 0)
return -1;
return 0;
}
|