 Chromium Code Reviews
 Chromium Code Reviews Issue 10919162:
  [MIPS] Implementation of sel_ldr for MIPS architecture.  (Closed) 
  Base URL: http://src.chromium.org/native_client/trunk/src/native_client/
    
  
    Issue 10919162:
  [MIPS] Implementation of sel_ldr for MIPS architecture.  (Closed) 
  Base URL: http://src.chromium.org/native_client/trunk/src/native_client/| Index: src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c | 
| diff --git a/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c b/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..d91e6c90dcfec80e5d794b572f7f6673c0e7b1db | 
| --- /dev/null | 
| +++ b/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c | 
| @@ -0,0 +1,134 @@ | 
| +/* | 
| + * Copyright 2012 The Native Client Authors. All rights reserved. | 
| + * Use of this source code is governed by a BSD-style license that can | 
| + * be found in the LICENSE file. | 
| + */ | 
| + | 
| +#include "native_client/src/include/nacl_platform.h" | 
| +#include "native_client/src/shared/platform/nacl_check.h" | 
| +#include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" | 
| +#include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 
| +#include "native_client/src/trusted/service_runtime/sel_addrspace.h" | 
| +#include "native_client/src/trusted/service_runtime/sel_ldr.h" | 
| +#include "native_client/src/trusted/service_runtime/sel_memory.h" | 
| + | 
| + | 
| +/* NOTE: This routine is almost identical to the x86_32 version. | 
| + */ | 
| +NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) { | 
| + int result; | 
| + void *tmp_mem = (void *) NACL_TRAMPOLINE_START; | 
| + | 
| + CHECK(NULL != mem); | 
| + | 
| + /* | 
| + * On Mips, we also cheat slightly: we add two pages to the requested | 
| + * allocation! This accomodates the guard region we require at the | 
| + * top end of untrusted memory. | 
| + */ | 
| + addrsp_size += NACL_ADDRSPACE_UPPER_GUARD_SIZE; | 
| + | 
| + NaClAddrSpaceBeforeAlloc(addrsp_size); | 
| + | 
| + /* | 
| + * On 32 bit Linux, a 1 gigabyte block of address space may be reserved at | 
| + * the zero-end of the address space during process creation, to address | 
| + * sandbox layout requirements on Mips and performance issues on Intel ATOM. | 
| + * Look for this pre-reserved block and if found, pass its address to the | 
| + * page allocation function. | 
| + */ | 
| + if (!NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { | 
| + /* On Mips, we should always have prereserved sandbox memory. */ | 
| + NaClLog(LOG_ERROR, "NaClAllocateSpace:" | 
| + " Could not find correct amount of prereserved memory" | 
| + " (looked for 0x%016"NACL_PRIxS" bytes).\n", | 
| + addrsp_size); | 
| + return LOAD_NO_MEMORY; | 
| + } | 
| + | 
| + /* | 
| + * When creating a zero-based sandbox, we do not allocate the first 64K of | 
| + * pages beneath the trampolines, because -- on Linux at least -- we cannot. | 
| + * Instead, we allocate starting at the trampolines, and then coerce the | 
| + * "mem" out parameter. | 
| + */ | 
| + CHECK(*mem == NULL); | 
| + addrsp_size -= NACL_TRAMPOLINE_START; | 
| + result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size); | 
| + | 
| + if (0 != result) { | 
| + NaClLog(2, | 
| + "NaClAllocateSpace: NaCl_page_alloc_at_addr 0x%08"NACL_PRIxPTR | 
| + " failed\n", | 
| + (uintptr_t) tmp_mem); | 
| + return LOAD_NO_MEMORY; | 
| + } | 
| + NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", | 
| + (uintptr_t) *mem, | 
| + addrsp_size); | 
| + | 
| + return LOAD_OK; | 
| +} | 
| + | 
| +/* | 
| + * In the Mips sandboxing scheme we put the NaCl module at low virtual | 
| + * address -- and thus there can only ever be one running NaCl app per | 
| + * sel_ldr process -- to simplify the address masking etc needed for | 
| + * the sandboxing. All memory below ((uintptr_t) 1) << nap->addr_bits | 
| + * is accessible to the NaCl app, and modulo page protection, | 
| + * potentially writable. Page protection is, of course, used to | 
| + * prevent writing to text and rodata, including the trusted | 
| + * trampoline code thunks. To simplify write sandboxing, some | 
| + * additional guard pages outside of the address space is needed, so | 
| + * that we don't have to additionally check the effective address | 
| + * obtained by register-relative addressing modes. | 
| + */ | 
| +NaClErrorCode NaClMprotectGuards(struct NaClApp *nap) { | 
| 
Mark Seaborn
2012/09/08 02:43:14
This is gone from the ARM version.  Please remove
 
petarj
2012/09/11 16:58:13
Done.
 | 
| + int err; | 
| + void *guard_base = (void *) (((uintptr_t) 1) << nap->addr_bits); | 
| + /* | 
| + * In Mips implementation kernel does not allow us to mmap address space at | 
| + * address 0x0, so we mmap it at the start of a trampoline region. | 
| + * Therefore, there is not need to mprotect at the start_addr. | 
| + * | 
| + * However, we do create a vmmap entry to describe it. | 
| + */ | 
| + NaClLog(3, | 
| + ("NULL detection region start 0x%08"NACL_PRIxPTR", " | 
| + "size 0x%08x, end 0x%08"NACL_PRIxPTR"\n"), | 
| + 0, NACL_SYSCALL_START_ADDR, | 
| + NACL_SYSCALL_START_ADDR); | 
| + | 
| + NaClVmmapAdd(&nap->mem_map, | 
| + nap->mem_start >> NACL_PAGESHIFT, | 
| + NACL_SYSCALL_START_ADDR >> NACL_PAGESHIFT, | 
| + PROT_NONE, | 
| + NACL_VMMAP_ENTRY_ANONYMOUS); | 
| + | 
| + /* | 
| + * We need to create a two-page guard region at the base of | 
| + * trusted memory, for write sandboxing. | 
| + */ | 
| + NaClLog(4, "NaClMprotectGuards: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", | 
| + (uintptr_t) guard_base, | 
| + (size_t) NACL_ADDRSPACE_UPPER_GUARD_SIZE); | 
| + if ((err = NaCl_mprotect(guard_base, | 
| + NACL_ADDRSPACE_UPPER_GUARD_SIZE, | 
| + PROT_NONE)) != 0) { | 
| + NaClLog(LOG_ERROR, ("NaClMemoryProtection: failed to protect lower guard " | 
| + "on trusted memory space (error %d)\n"), | 
| + err); | 
| + return LOAD_MPROTECT_FAIL; | 
| + } | 
| + | 
| + /* | 
| + * NB: the pages just mapped are OUTSIDE of the address space of the | 
| + * NaCl module. We should not track them in the Vmmap structure, | 
| + * since that's to track addressable memory for mapping and unmapping. | 
| + * | 
| + * This means that because these pages are implicit and not tracked, | 
| + * we should have a hook to tear down these pages as part of the | 
| + * NaClApp dtor. | 
| + */ | 
| + return LOAD_OK; | 
| +} |