]> Zhao Yanbai Git Server - kernel.git/commitdiff
fix copy on write bug; jump to ring3
authorAceVest <zhaoyanbai@126.com>
Wed, 16 Jul 2014 17:55:12 +0000 (01:55 +0800)
committerAceVest <zhaoyanbai@126.com>
Wed, 16 Jul 2014 17:55:12 +0000 (01:55 +0800)
12 files changed:
boot/multiboot.S
include/page.h
include/system.h
kernel/exit.c
kernel/fork.c
kernel/init.c
kernel/innerint.c
kernel/irq.c
kernel/sched.c
kernel/syscall.S
kernel/syscall.c
mm/page.c

index ab7e631d632a0834ea1a26f69ba351479d8dc285..14e8129f7186b38290b820cbe3904258d5d71212 100644 (file)
@@ -114,7 +114,7 @@ main:
 
     # enable PG
     movl    %cr0,%eax
-    orl     $0x80000000,%eax
+    orl     $0x80010000,%eax
     movl    %eax,%cr0
 
 
index f4fbe552869ae5eb25d99759055003c2f1225ccb..ee926d48a38ca7d04d57b598d0583507a6ce0638 100644 (file)
@@ -17,8 +17,6 @@
 #ifndef _PAGE_H
 #define _PAGE_H
 
-
-
 #define PAGE_P      0x1
 #define PAGE_WR     0x2
 #define PAGE_US     0x4
@@ -102,7 +100,7 @@ typedef struct page
 void *page2va(page_t *page);
 page_t *va2page(unsigned long addr);
 
-#define pa2page(addr) va2page((unsigned long)pa2va(addr))
+#define pa2page(addr) va2page((unsigned long)pa2va(PAGE_ALIGN(addr)))
 
 static inline page_t *get_head_page(page_t *page) { return page->head_page; }
 
index f9dcb85047f64b96bbd935c1acbaa0fdf21d644b..7cbcdb998ccd5bafc2ac71da42f4e2adf3a96918 100644 (file)
@@ -83,11 +83,11 @@ static inline void free_phys_pages(void *p)
     free_virt_pages((void*)va2pa(p));
 }
 
-#define panic(msg) do {                                     \
-    asm("cli;");                                            \
-    printk("PANIC:\"%s\" file:%s function:%s line:%d\n",    \
-        msg, __FILE__, __FUNCTION__, __LINE__);             \
-    while(1);                                               \
+#define panic(msg, ...) do {                                    \
+    asm("cli;");                                                \
+    printk("PANIC:\" # msg # \" file:%s function:%s line:%d\n",        \
+        ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__);  \
+    while(1);                                                   \
 } while(0);
 
 extern char etext, edata, end;
index 791a63382d3b8f50d87bdb8d1bae6a68bae9edd7..432ffdda7dfd8cc9f6e3ca05f2001e97bb978075 100644 (file)
@@ -22,6 +22,7 @@ int sysc_exit(int status)
     /* 先简要实现 */
     current->state = TASK_EXITING;
 
+    task_union *t = current;
     
     schedule();
 
index a80fcabec71b92553ad747ca5449e4dd40c0554f..c406b8066a9ed196083734431f9f0aa53116cb3e 100644 (file)
@@ -29,8 +29,11 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
     if(tsk == NULL)
         panic("can not malloc PCB");
 
+    memcpy(tsk, current, sizeof(task_union));
+
     {
         tsk->cr3 = (unsigned long) alloc_one_page(0);
+        printl(MPL_TEST+1, "cr3 %08x", tsk->cr3);
         if(tsk->cr3 == 0)
             panic("failed init tsk cr3");
 
@@ -46,11 +49,17 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
         {
             unsigned long spde = (unsigned long) pde_src[i];
             unsigned long dpde = 0;
+
+            if(i>=768)
+            {
+                pde_dst[i] = pde_src[i];
+                continue;
+            }
+
             if(spde != 0)
                 dpde = PAGE_FLAGS(spde) | (unsigned long) va2pa(alloc_one_page(0));
             pde_dst[i] = dpde;
 
-
             pte_t *pte_src = pa2va(PAGE_ALIGN(spde));
             pte_t *pte_dst = pa2va(PAGE_ALIGN(dpde));
             for(j=0; j< PAGE_PTE_CNT; ++j)
@@ -64,8 +73,6 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
         }
     }
 
-    memcpy(tsk, current, sizeof(task_union));
-
     tsk->pid    = get_next_pid();
     tsk->ppid   = current->pid;
 
index 1ba0696480a98d540ab49ef96a866d8233480a27..debca5f280bd79d048946d11f994e7840b0e9ec1 100644 (file)
@@ -23,29 +23,49 @@ char __initdata kernel_init_stack[KRNL_INIT_STACK_SIZE] __attribute__ ((__aligne
 
 int debug_wait_queue_get();
 
+#if 0
 void ring3()
 {
+    int i = 0;
     while(1)
     {
+        i++;
+//        printk("fuck\n");
         systest();
     }
 }
+#else
+void ring3();
+#endif
 static char user_task_stack[PAGE_SIZE] __attribute__ ((__aligned__(PAGE_SIZE)));
 void user_task_entry()
 {
     printk("user_task_entry\n");
-    asm("movl $0x23,%%eax; \
-    movw %%ax,%%ds; \
-    movw %%ax,%%es; \
-    movw %%ax,%%fs; \
-    movw %%ax,%%gs; \
-    pushl $0x23; \
-    pushl %%ebx; \
-    pushl $0x282; \
-    pushl $0x1B; \
-    leal ring3,%%eax; \
-    pushl %%eax; \
+    //while(1);
+#if 1
+    asm("cli;");
+    asm("movl $0x23,%%eax;  \
+    movw %%ax,%%ds;         \
+    movw %%ax,%%es;         \
+    movw %%ax,%%fs;         \
+    movw %%ax,%%gs;         \
+    pushl $0x23;            \
+    pushl %%ebx;            \
+    pushl $0x202;           \
+    pushl $0x1B;            \
+    leal ring3,%%eax;       \
+    pushl %%eax;            \
     iret;"::"b"(user_task_stack+PAGE_SIZE));
+#else
+    asm("xorl   %eax,%eax;  \
+        sti;                \
+        pushfl;             \
+        movw    %cs,%ax;    \
+        pushl   %eax;       \
+        leal    ring3,%eax; \
+        pushl   %eax;       \
+        iret;");
+#endif
 }
 
 void init_task_entry()
@@ -55,9 +75,9 @@ void init_task_entry()
 
     while(1)
     {
-        printl(MPL_TASK_1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
-        //int v = debug_wait_queue_get();
-        //printk("task:%d wait queue get %d\n", id, v);
+        printl(MPL_TASK_1+id-1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
+        int v = debug_wait_queue_get();
+        printk("task:%d wait queue get %d\n", id, v);
     }
 }
 
@@ -72,9 +92,12 @@ void kernel_task(void *entry)
 
 void root_task_entry()
 {
-    //kernel_task(init_task_entry);
+
+    kernel_task(init_task_entry);
+    kernel_task(init_task_entry);
     kernel_task(user_task_entry);
 
+
     int cnt = 0;
     while(1)
     {
index b075708d7bbb49839474a7e3e91e0b091abbc899..1fce729cd6443bb911d5ed29fb5d7563f187b198 100644 (file)
@@ -94,6 +94,13 @@ void doPageFault(pt_regs_t regs)
 
     a = 0;
 
+    //printd("do page fault errcode %x addr %08x\n", errcode, addr);
+
+    if(errcode & PAGE_US)
+    {
+        panic("user program try to access a page and cause a protection fault. addr %08x", addr);
+    }
+
     if((errcode & PAGE_P) == 0)
     {
         extern void do_no_page(void *);
index 6ab45b2ee580fabbeee36dda385a764b59ee4b39..fdf72ddf0ebdb5f879b00efa7dae02316a30b96f 100644 (file)
@@ -58,7 +58,7 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs)
 
     unsigned long esp;
     asm("movl %%esp, %%eax":"=a"(esp));
-    printl(MPL_PREEMPT, "current %08x  preempt %d esp %08x", current, current->preempt_cnt, esp);
+    printl(MPL_PREEMPT, "current %08x  cr3 %08x preempt %d esp %08x", current, current->cr3, current->preempt_cnt, esp);
 
     p->chip->ack(irq);
     sti();
index ee480dad476dd3942903b36d590c6f2c212918cb..47114763c9205ccb589cf28bcd45f45ec210e2fc 100644 (file)
@@ -35,18 +35,6 @@ inline void load_cr3(task_union *tsk)
     LOAD_CR3(tsk->cr3);
 }
 
-void init_tsk_cr3(task_union * tsk)
-{
-    tsk->cr3 = (unsigned long) pa2va(get_phys_pages(1));
-
-    if(tsk->cr3 == 0)
-        panic("failed init tsk cr3");
-
-    memset((void *)tsk->cr3, 0, PAGE_SIZE);
-    memcpy((void *)tsk->cr3, (void*)system.page_dir, PAGE_SIZE);
-    tsk->cr3 = va2pa(tsk->cr3);
-}
-
 extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
 void init_root_tsk()
 {
@@ -170,8 +158,11 @@ unsigned long schedule()
     task_union *prev = current;
     task_union *next = sel;
 
-    if(prev != sel)
+    if(prev != next)
+    {
+        printd("select %08x\n", next);
         context_switch(prev, next);
+    }
 }
 
 void debug_sched()
index 0124d36cabb529e5bf93a908bc521ce298e9e38a..ef7801e09557478e71c804b0491da4d9ab1f2dde 100644 (file)
@@ -94,3 +94,28 @@ sysexit:
     popl    %edx;
     popl    %ecx;
     ret
+
+.global ring3
+ring3:
+    nop;
+    nop;
+
+    movl $(ring3_stack+100), %esp
+
+    movl $11, %eax;
+
+    pushl $1f;
+    pushl %ecx;
+    pushl %edx;
+    pushl %ebp;
+    movl %esp,%ebp;
+    sysenter;
+    1:
+
+    nop;
+    nop;
+
+    jmp ring3
+
+ring3_stack:
+    .byte   200
index 21570e76c1f6e5b9b438f4d113ece634f2be1465..a87f14c7064fdbb78d03d7e9dbb31e72e46837d3 100644 (file)
@@ -50,7 +50,7 @@ int sysc_pause()
 
 int sysc_test()
 {
-    static unsigned int cnt;
+    static unsigned int cnt=0;
     printl(MPL_TEST, "sysc_test %u", cnt++);
 }
 
index caf7514fc2b9e93e2a2a8ab006ea0e9354c01f2a..ab4d8d9b508e48ca2191612a0b89b4004fb35c61 100644 (file)
--- a/mm/page.c
+++ b/mm/page.c
@@ -54,7 +54,9 @@ void do_wp_page(void *addr)
     int npde = get_npd(addr);
     int npte = get_npt(addr);
 
-    unsigned long *pd = (u32 *)pa2va(current->cr3);
+    //unsigned long *pd = (u32 *)pa2va(current->cr3);
+    //unsigned long *pd = (u32 *)va2pa(current->cr3);
+    unsigned long *pd = (u32 *)(current->cr3);
     unsigned long *pt = NULL;
 
     pt = pa2va(PAGE_ALIGN(pd[npde]));
@@ -78,6 +80,8 @@ void do_wp_page(void *addr)
         if(0 == dst)
             panic("out of memory");
 
+        dst = va2pa(dst);
+
         pt[npte] = dst | flags;
 
         dst = (unsigned long)pa2va(PAGE_ALIGN(dst));
@@ -86,7 +90,10 @@ void do_wp_page(void *addr)
     }
     else
     {
+        //pd[npde] |= PAGE_WR;
         pt[npte] |= PAGE_WR;
+        //pd[npde] |= PAGE_US;
+        //pt[npte] |= PAGE_US;
     }
 
     load_cr3(current);