1/* 2 * Copyright (c) 2015, Google Inc. All rights reserved 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files 6 * (the "Software"), to deal in the Software without restriction, 7 * including without limitation the rights to use, copy, modify, merge, 8 * publish, distribute, sublicense, and/or sell copies of the Software, 9 * and to permit persons to whom the Software is furnished to do so, 10 * subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <asm.h> 25#include <arch/asm_macros.h> 26#include <err.h> 27 28.syntax unified 29 30/** 31 * int mmutest_arch_rodata_pnx(void) - Test that rodata section is mapped pnx 32 * 33 * Returns ERR_FAULT if rodata is not executable. 34 * Return 0 if rodata is executable. 35 */ 36.section .rodata 37.align 2 38FUNCTION(mmutest_arch_rodata_pnx) 39 set_fault_handler .Lmmutest_fault 40 mov r0, #0 41 42 bx lr 43 44/** 45 * int mmutest_arch_data_pnx(void) - Test that data section is mapped pnx 46 * 47 * Returns ERR_FAULT if data is not executable. 48 * Return 0 if data is executable. 49 */ 50.section .data 51.align 2 52FUNCTION(mmutest_arch_data_pnx) 53 set_fault_handler .Lmmutest_fault 54 mov r0, #0 55 56 bx lr 57.section .text 58 59/** 60 * int mmutest_arch_rodata_ro(void) - Test that rodata section is mapped read-only 61 * 62 * Returns ERR_FAULT if rodata is not writeable 63 * Returns 1 if write to rodata is silently dropped 64 * Returns 0 if rodata is writable 65 */ 66FUNCTION(mmutest_arch_rodata_ro) 67 ldr r0, =.Ltest_rodata_long 68 mov r1, #0 69 70 set_fault_handler .Lmmutest_fault 71 str r1, [r0] 72 73 ldr r0, [r0] 74 bx lr 75 76.section .rodata 77.Ltest_rodata_long: 78 .long 0x1 79 80.section .text 81 82/** 83 * int mmutest_arch_store_uint32(uint32_t *ptr, bool user) - Test if ptr is writeable 84 * @ptr: Memory location to test 85 * @user: Use unpriviledged store 86 * 87 * Returns ERR_FAULT if ptr is not writeable 88 * Returns ERR_GENERIC if ptr is not readable 89 * Returns 2 if write does not fault, but data is lost on readback from memory 90 * Returns 1 if write does not fault, but data is lost on readback from cache 91 * Returns 0 if ptr is writable 92 */ 93FUNCTION(mmutest_arch_store_uint32) 94 cmp r1, #0 95 96 set_fault_handler .Lmmutest_setup_fault 97 ldreq r1, [r0] 98 99 set_fault_handler .Lmmutest_setup_fault 100 ldrtne r1, [r0] 101 102 mvn r1, r1 103 104 set_fault_handler .Lmmutest_fault 105 streq r1, [r0] 106 107 set_fault_handler .Lmmutest_fault 108 strtne r1, [r0] 109 110 dmb 111 112 ldr r2, [r0] 113 cmp r1, r2 114 movne r0, #1 115 bxne lr 116 117 push {r0, r1, r2, lr} 118 mov r1, #4 119 blx arch_clean_invalidate_cache_range 120 pop {r0, r1, r2, lr} 121 122 ldr r2, [r0] 123 cmp r1, r2 124 moveq r0, #0 125 movne r0, #2 126 127 bx lr 128 129/** 130 * int mmutest_arch_nop(int ret) - Return ret 131 * 132 * Returns ret if run from executable page. 133 * Does not return if run from non-executable page. 134 */ 135FUNCTION(mmutest_arch_nop) 136 bx lr 137FUNCTION(mmutest_arch_nop_end) 138 139.Lmmutest_setup_fault: 140 mov r0, #ERR_GENERIC 141 bx lr 142 143.Lmmutest_fault: 144 mov r0, #ERR_FAULT 145 bx lr 146