From f41cdc51e2d27d257e8d45247b0be49df4baf8a4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 26 Oct 2011 16:47:15 +0800 Subject: [PATCH] Kernel/armv7 - Bugfixing, implemented protection fully, but broke a couple of earlier things --- Kernel/arch/armv7/mm_virt.c | 88 +++++++++++++++++++++++++++++++++---- Kernel/arch/armv7/proc.S | 6 ++- Kernel/arch/armv7/start.S | 67 ++++++++++++++++------------ 3 files changed, 122 insertions(+), 39 deletions(-) diff --git a/Kernel/arch/armv7/mm_virt.c b/Kernel/arch/armv7/mm_virt.c index a49febd1..2c0a2bd7 100644 --- a/Kernel/arch/armv7/mm_virt.c +++ b/Kernel/arch/armv7/mm_virt.c @@ -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) diff --git a/Kernel/arch/armv7/proc.S b/Kernel/arch/armv7/proc.S index 52dcb64a..44ce9eea 100644 --- a/Kernel/arch/armv7/proc.S +++ b/Kernel/arch/armv7/proc.S @@ -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 diff --git a/Kernel/arch/armv7/start.S b/Kernel/arch/armv7/start.S index 8b19ede2..95bcd473 100644 --- a/Kernel/arch/armv7/start.S +++ b/Kernel/arch/armv7/start.S @@ -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 -- 2.20.1