From e72643c379ae946295b8906c3994cd852de0e4ee Mon Sep 17 00:00:00 2001 From: Linermao <LinermaoGemail@gmail.com> Date: Fri, 20 Dec 2024 14:49:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20copy=20on=20write=20?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=B7=B2=E7=9F=A5?= =?UTF-8?q?=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/defs.h | 7 ++++++- kernel/trap.c | 14 ++++++++++++-- kernel/vm.c | 15 +++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/kernel/defs.h b/kernel/defs.h index b1656f7..e01e6db 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -3,6 +3,7 @@ #include "types.h" #include "ipc_hash.h" +#include "riscv.h" #define ASSERT(x, info)\ do\ @@ -80,6 +81,10 @@ void kfree(void *); void kinit(void); void* kbuddy_alloc(uint32); void kbuddy_free(void *, uint32); +int kaddrefcnt(void*); +void* cowalloc(pagetable_t, uint64); +int krefcnt(void*); +int cowpage(pagetable_t, uint64); // log.c void initlog(int, struct superblock*); @@ -94,7 +99,7 @@ int piperead(struct pipe*, uint64, int); int pipewrite(struct pipe*, uint64, int); // printf.c -int printf(char*, ...) __attribute__ ((format (printf, 1, 2))); +int printf(char*, ...) __attribute__ ((format (printf, 1, 2))); void panic(char*) __attribute__((noreturn)); void printfinit(void); diff --git a/kernel/trap.c b/kernel/trap.c index 43ca6c5..e1420a4 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -72,9 +72,19 @@ usertrap(void) } else if(r_scause() == 13 || r_scause() == 15){ // åŠ è½½é¡µé¢ä¸Žä¿å˜é¡µé¢é”™è¯¯ uint64 va; va = r_stval(); - if (uvlazyalloc(p->pagetable, va) < 0) { + pte_t* pte = walk(p->pagetable, va, 0); + + if ((*pte & PTE_V) == 0){ + if (uvlazyalloc(p->pagetable, va) < 0) { + setkilled(p); + } + }else if (*pte & PTE_F){ + if (va >= p->sz || cowpage(p->pagetable, va) != 0 || cowalloc(p->pagetable, PGROUNDDOWN(va)) == 0){ + setkilled(p); + } + }else { setkilled(p); - } + } } else { // 错误则kill这个进程 diff --git a/kernel/vm.c b/kernel/vm.c index 084821c..87d1f69 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -256,10 +256,10 @@ int uvlazyalloc(pagetable_t pagetable, uint64 va){ va = PGROUNDDOWN(va); if (va > myproc()->sz) { - printf("va is greater than sz"); + printf("va is greater than sz\n"); return -1; }else if (va < myproc()->ustack_top){ - printf("va is less than ustack_top"); + printf("va is less than ustack_top\n"); return -1; } @@ -374,8 +374,17 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) if((*pte & PTE_V) == 0) // panic("uvmcopy: page not present"); continue; + pa = PTE2PA(*pte); flags = PTE_FLAGS(*pte); + + // 仅对å¯å†™é¡µé¢è®¾ç½®COWæ ‡è®° + if(flags & PTE_W) { + // ç¦ç”¨å†™å¹¶è®¾ç½®COW Forkæ ‡è®° + flags = (flags | PTE_F) & ~PTE_W; + *pte = PA2PTE(pa) | flags; + } + if((mem = kalloc()) == 0) goto err; memmove(mem, (char*)pa, PGSIZE); @@ -383,6 +392,8 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) kfree(mem); goto err; } + // å¢žåŠ å†…å˜çš„引用计数 + kaddrefcnt((char*)pa); } return 0; -- GitLab