Kernel/armv7 - Bugfixing, implemented protection fully, but broke a couple of earlier...
authorJohn Hodge <[email protected]>
Wed, 26 Oct 2011 08:47:15 +0000 (16:47 +0800)
committerJohn Hodge <[email protected]>
Wed, 26 Oct 2011 08:47:15 +0000 (16:47 +0800)
Kernel/arch/armv7/mm_virt.c
Kernel/arch/armv7/proc.S
Kernel/arch/armv7/start.S

index a49febd..2c0a2bd 100644 (file)
@@ -14,7 +14,7 @@
 #define AP_KRW_ONLY    1       // Kernel page
 #define AP_KRO_ONLY    5       // Kernel RO page
 #define AP_RW_BOTH     3       // Standard RW
-#define AP_RO_BOTH     6       // COW Page
+#define AP_RO_BOTH     7       // COW Page
 #define AP_RO_USER     2       // User RO Page
 #define PADDR_MASK_LVL1        0xFFFFFC00
 
@@ -119,11 +119,11 @@ int MM_int_AllocateCoarse(tVAddr VAddr, int Domain)
 
        if( VAddr < 0x80000000 ) {
 //             Log("USRFRACTAL(%p) = %p", VAddr, &USRFRACTAL(VAddr));
-               USRFRACTAL(VAddr) = paddr | 3;
+               USRFRACTAL(VAddr) = paddr | 0x13;
        }
        else {
 //             Log("FRACTAL(%p) = %p", VAddr, &FRACTAL(table1, VAddr));
-               FRACTAL(table1, VAddr) = paddr | 3;
+               FRACTAL(table1, VAddr) = paddr | 0x13;
        }
 
        // TLBIALL 
@@ -423,7 +423,7 @@ tPAddr MM_Allocate(tVAddr VAddr)
                pi.AP = AP_RW_BOTH;
        else
                pi.AP = AP_KRW_ONLY;
-       pi.bExecutable = 1;
+       pi.bExecutable = 0;
        if( MM_int_SetPageInfo(VAddr, &pi) ) {
                MM_DerefPhys(pi.PhysAddr);
                LEAVE('i', 0);
@@ -497,13 +497,15 @@ void MM_int_CloneTable(Uint32 *DestEnt, int Table)
        
        table = MM_AllocPhys();
        if(!table)      return ;
+
+       cur += 256*Table;
        
        tmp_map = (void*)MM_MapTemp(table);
        
        for( i = 0; i < 1024; i ++ )
        {
 //             Log_Debug("MMVirt", "cur[%i] (%p) = %x", Table*256+i, &cur[Table*256+i], cur[Table*256+i]);
-               switch(cur[Table*256+i] & 3)
+               switch(cur[i] & 3)
                {
                case 0: tmp_map[i] = 0; break;
                case 1:
@@ -515,12 +517,14 @@ void MM_int_CloneTable(Uint32 *DestEnt, int Table)
                case 3:
                        // Small page
                        // - If full RW
-                       if( (cur[Table*256] & 0x230) == 0x030 )
-                               cur[Table*256+i] |= 0x200;      // Set to full RO (Full RO=COW, User RO = RO)
-                       tmp_map[i] = cur[Table*256+i];
+                       Debug("%p cur[%i] & 0x230 = 0x%x", Table*256*0x1000, i, cur[i] & 0x230);
+                       if( (cur[i] & 0x230) == 0x030 )
+                               cur[i] |= 0x200;        // Set to full RO (Full RO=COW, User RO = RO)
+                       tmp_map[i] = cur[i];
                        break;
                }
        }
+       MM_FreeTemp( (tVAddr) tmp_map );
 
        DestEnt[0] = table + 0*0x400 + 1;
        DestEnt[1] = table + 1*0x400 + 1;
@@ -615,6 +619,7 @@ tPAddr MM_Clone(void)
                        void    *tmp_page;
                        
                        page = MM_AllocPhys();
+                       Log("page = %P", page);
                        table[j] = page | 0x813;
 
                        tmp_page = (void*)MM_MapTemp(page);
@@ -633,7 +638,72 @@ tPAddr MM_Clone(void)
 
 void MM_ClearUser(void)
 {
-       Log_KernelPanic("MMVirt", "TODO: Implement MM_ClearUser");
+        int    i, j;
+       Uint32  *cur = (void*)MM_TABLE0USER;
+       Uint32  *tab;
+       
+//     MM_DumpTables(0, 0x80000000);
+
+       for( i = 0; i < 0x800-4; i ++ )
+       {
+               switch( cur[i] & 3 )
+               {
+               case 0: break;  // Already unmapped
+               case 1: // Sub pages
+                       tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+                       for( j = 0; j < 1024; j ++ )
+                       {
+                               switch( tab[j] & 3 )
+                               {
+                               case 0: break;  // Unmapped
+                               case 1:
+                                       Log_Error("MMVirt", "TODO: Support large pages in MM_ClearUser");
+                                       break;
+                               case 2:
+                               case 3:
+                                       MM_DerefPhys( tab[j] & ~(PAGE_SIZE-1) );
+                                       break;
+                               }
+                       }
+                       MM_DerefPhys( cur[i] & ~(PAGE_SIZE-1) );
+                       cur[i+0] = 0;
+                       cur[i+1] = 0;
+                       cur[i+2] = 0;
+                       i += 3;
+                       break;
+               case 2:
+               case 3:
+                       Log_Error("MMVirt", "TODO: Implement sections/supersections in MM_ClearUser");
+                       break;
+               }
+               cur[i] = 0;
+       }
+       
+       // Clear out unused stacks
+       {
+               register Uint32 __SP asm("sp");
+                int    cur_stack_base = ((__SP & ~(MM_KSTACK_SIZE-1)) / PAGE_SIZE) % 1024;
+
+               tab = (void*)(MM_TABLE1USER + i*256*sizeof(Uint32));
+               
+               // First 512 is the Table1 mapping + 2 for Table0 mapping
+               for( j = 512+2; j < 1024; j ++ )
+               {
+                       // Skip current stack
+                       if( j == cur_stack_base ) {
+                               j += (MM_KSTACK_SIZE / PAGE_SIZE) - 1;
+                               continue ;
+                       }
+                       if( !(tab[j] & 3) )     continue;
+                       ASSERT( (tab[j] & 3) == 2 );
+                       MM_DerefPhys( tab[j] & ~(PAGE_SIZE) );
+                       tab[j] = 0;
+               }
+       }
+       
+
+       MM_DumpTables(0, 0x80000000);
+//     Log_KernelPanic("MMVirt", "TODO: Implement MM_ClearUser");
 }
 
 tVAddr MM_MapTemp(tPAddr PAddr)
index 52dcb64..44ce9ee 100644 (file)
@@ -54,6 +54,8 @@ SwitchTask:
        ldr r1, [sp,#4*10]
        tst r1, r1
        mcrne p15, 0, r1, c2, c0, 0     @ Set TTBR0 to r0
+       mov r1, #0
+       mcrne p15, 0, r1, c8, c7, 0     @ Invalidate all (HACK! But it fixes things)
 
        @ Restore SP
        mov sp, r0
@@ -85,8 +87,8 @@ Proc_CloneInt_new:
 @      mvn r1, #0
 @      bl MM_DumpTables
 
-       ldr r0, =csProc_CloneInt_NewTaskMessage
-       bl Log
+@      ldr r0, =csProc_CloneInt_NewTaskMessage
+@      bl Log
        
 @      cps #19
        mov r0, #0
index 8b19ede..95bcd47 100644 (file)
@@ -34,6 +34,10 @@ _start:
        orr r0, r0, #1 << 23
        mcr p15, 0, r0, c1, c0, 0
 
+       @ Enable access faults on domains 0 & 1
+       mov r0, #0x55   @ 01010101b
+       mcr p15, 0, r0, c3, c0, 0
+
        @
        @ Check for security extensions
        @
@@ -85,10 +89,15 @@ SVC_Handler:
        ldr r4, =SyscallHandler
        blx r4
        
+       ldr r0, =csSyscallPrintRetAddr
+       ldr r1, [sp,#9*4+5*4]
+       ldr r4, =Log
+       blx r4
+       
        pop {r2}        @ errno
        pop {r0,r1}     @ Ret/RetHi
        add sp, #2*4    @ Saved r2/r3
-       
+
        pop {r4-r12}
        rfeia sp!       @ Pop state (actually RFEFD)
 .arm_specifics:
@@ -176,12 +185,14 @@ csDataAbort_Fmt:
        .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
 csPrefetchAbort_Fmt:
        .asciz "Prefetch Abort at %p, IFSR=%x"
+csSyscallPrintRetAddr:
+       .asciz "Syscall ret to %p"
 
 .section .padata
 .globl kernel_table0
 
 kernel_table0:
-       .long 0x00000002        @ Identity map the first 1 MiB
+       .long 0x00000402        @ Identity map the first 1 MiB
        .rept 0x7FC - 1
                .long 0
        .endr
@@ -190,30 +201,30 @@ kernel_table0:
        .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
        .long user_table1_map + 0xC00 - KERNEL_BASE + 1
        @ 0x80000000 - User/Kernel split
-       .long 0x00000002        @ Map first 4 MiB to 2GiB
-       .long 0x00100002        @ 
-       .long 0x00200002        @ 
-       .long 0x00300002        @ 
+       .long 0x00000402        @ Map first 4 MiB to 2GiB (KRW only)
+       .long 0x00100402        @ 
+       .long 0x00200402        @ 
+       .long 0x00300402        @ 
        .rept 0xF00 - 0x800 - 4
                .long 0
        .endr
 #if PCI_PADDR
-       .long PCI_PADDR +  0*(1 << 20) + 2      @ Map PCI config space
-       .long PCI_PADDR +  1*(1 << 20) + 2
-       .long PCI_PADDR +  2*(1 << 20) + 2
-       .long PCI_PADDR +  3*(1 << 20) + 2
-       .long PCI_PADDR +  4*(1 << 20) + 2
-       .long PCI_PADDR +  5*(1 << 20) + 2
-       .long PCI_PADDR +  6*(1 << 20) + 2
-       .long PCI_PADDR +  7*(1 << 20) + 2
-       .long PCI_PADDR +  8*(1 << 20) + 2
-       .long PCI_PADDR +  9*(1 << 20) + 2
-       .long PCI_PADDR + 10*(1 << 20) + 2
-       .long PCI_PADDR + 11*(1 << 20) + 2
-       .long PCI_PADDR + 12*(1 << 20) + 2
-       .long PCI_PADDR + 13*(1 << 20) + 2
-       .long PCI_PADDR + 14*(1 << 20) + 2
-       .long PCI_PADDR + 15*(1 << 20) + 2
+       .long PCI_PADDR +  0*(1 << 20) + 0x402  @ Map PCI config space
+       .long PCI_PADDR +  1*(1 << 20) + 0x402
+       .long PCI_PADDR +  2*(1 << 20) + 0x402
+       .long PCI_PADDR +  3*(1 << 20) + 0x402
+       .long PCI_PADDR +  4*(1 << 20) + 0x402
+       .long PCI_PADDR +  5*(1 << 20) + 0x402
+       .long PCI_PADDR +  6*(1 << 20) + 0x402
+       .long PCI_PADDR +  7*(1 << 20) + 0x402
+       .long PCI_PADDR +  8*(1 << 20) + 0x402
+       .long PCI_PADDR +  9*(1 << 20) + 0x402
+       .long PCI_PADDR + 10*(1 << 20) + 0x402
+       .long PCI_PADDR + 11*(1 << 20) + 0x402
+       .long PCI_PADDR + 12*(1 << 20) + 0x402
+       .long PCI_PADDR + 13*(1 << 20) + 0x402
+       .long PCI_PADDR + 14*(1 << 20) + 0x402
+       .long PCI_PADDR + 15*(1 << 20) + 0x042
 #else
        .rept 16
                .long 0
@@ -244,18 +255,18 @@ user_table1_map:  @ Size = 4KiB (only 2KiB used)
        .rept 0x800/4-1
                .long 0
        .endr
-       .long user_table1_map - KERNEL_BASE + 0x10 + 3          @ ...1FF000 = 0x7FDFF000
+       .long user_table1_map - KERNEL_BASE + 0x13      @ ...1FF000 = 0x7FDFF000
        @ Kernel stack zone
-       .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3   @ ...200000 = 0x7FE00000
-       .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3   @ ...201000 = 0x7FE01000
+       .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13       @ ...200000 = 0x7FE00000
+       .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13       @ ...201000 = 0x7FE01000
        .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
                .long 0
        .endr
        #if MM_KSTACK_SIZE != 0x2000
        #error Kernel stack size not changed in start.S
        #endif
-       .long stack + 0x0000 - KERNEL_BASE + 0x10 + 3   @ Kernel Stack
-       .long stack + 0x1000 - KERNEL_BASE + 0x10 + 3   @ 
+       .long stack + 0x0000 - KERNEL_BASE + 0x13       @ Kernel Stack
+       .long stack + 0x1000 - KERNEL_BASE + 0x13       @ 
 
 .globl kernel_table1_map
 kernel_table1_map:     @ Size = 4KiB
@@ -272,7 +283,7 @@ kernel_table1_map:  @ Size = 4KiB
 @ Hardware mappings 
 .globl hwmap_table_0
 hwmap_table_0:
-       .long UART0_PADDR + (1 << 4) + 3        @ UART0
+       .long UART0_PADDR + (1 << 4) + 0x13     @ UART0
        .rept 1024 - 1
                .long 0
        .endr

UCC git Repository :: git.ucc.asn.au