1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include <assert.h> 14#include <sel4/sel4.h> 15 16#include "../helpers.h" 17 18static int test_retype(env_t env) 19{ 20 int error; 21 int i; 22 vka_object_t untyped; 23 vka_object_t cnode; 24 25 error = vka_alloc_cnode_object(&env->vka, 2, &cnode); 26 test_error_eq(error, 0); 27 28 error = vka_alloc_untyped(&env->vka, seL4_TCBBits + 3, &untyped); 29 test_error_eq(error, 0); 30 31 /* Try to insert 0. */ 32 error = seL4_Untyped_Retype(untyped.cptr, 33 seL4_TCBObject, 0, 34 env->cspace_root, cnode.cptr, seL4_WordBits, 35 1, 0); 36 test_error_eq(error, seL4_RangeError); 37 38 /* Check we got useful min/max error codes. */ 39 test_eq(seL4_GetMR(0), 1ul); 40 test_eq(seL4_GetMR(1), (unsigned long)CONFIG_RETYPE_FAN_OUT_LIMIT); 41 42 /* Try to drop two caps in, at the end of the cnode, overrunning it. */ 43 error = seL4_Untyped_Retype(untyped.cptr, 44 seL4_TCBObject, 0, 45 env->cspace_root, cnode.cptr, seL4_WordBits, 46 (1 << 2) - 1, 2); 47 test_error_eq(error, seL4_RangeError); 48 49 /* Drop some caps in. This should be successful. */ 50 for (i = 0; i < (1 << 2); i++) { 51 error = seL4_Untyped_Retype(untyped.cptr, 52 seL4_TCBObject, 0, 53 env->cspace_root, cnode.cptr, seL4_WordBits, 54 i, 1); 55 test_error_eq(error, seL4_NoError); 56 } 57 58 /* Try to drop one in beyond the end of the cnode. */ 59 error = seL4_Untyped_Retype(untyped.cptr, 60 seL4_TCBObject, 0, 61 env->cspace_root, cnode.cptr, seL4_WordBits, 62 i, 2); 63 test_error_eq(error, seL4_RangeError); 64 65 /* Try putting caps over the top. */ 66 for (i = 0; i < (1 << 2); i++) { 67 error = seL4_Untyped_Retype(untyped.cptr, 68 seL4_TCBObject, 0, 69 env->cspace_root, cnode.cptr, seL4_WordBits, 70 i, 1); 71 test_error_eq(error, seL4_DeleteFirst); 72 } 73 74 /* Delete them all. */ 75 for (i = 0; i < (1 << 2); i++) { 76 error = seL4_CNode_Delete(cnode.cptr, i, 2); 77 test_error_eq(error, seL4_NoError); 78 } 79 80 /* Try to insert too many. */ 81 error = seL4_Untyped_Retype(untyped.cptr, 82 seL4_TCBObject, 0, 83 env->cspace_root, cnode.cptr, seL4_WordBits, 84 0, 1U << 31); 85 test_error_eq(error, seL4_RangeError); 86 87 error = seL4_Untyped_Retype(untyped.cptr, 88 seL4_TCBObject, 0, 89 env->cspace_root, cnode.cptr, seL4_WordBits, 90 0, (1 << 2) + 1); 91 test_error_eq(error, seL4_RangeError); 92 93 /* Insert them in one fell swoop but one. */ 94 error = seL4_Untyped_Retype(untyped.cptr, 95 seL4_TCBObject, 0, 96 env->cspace_root, cnode.cptr, seL4_WordBits, 97 0, (1 << 2) - 1); 98 test_error_eq(error, seL4_NoError); 99 100 /* Try inserting over the top. Only the last should succeed. */ 101 for (i = 0; i < (1 << 2); i++) { 102 error = seL4_Untyped_Retype(untyped.cptr, 103 seL4_TCBObject, 0, 104 env->cspace_root, cnode.cptr, seL4_WordBits, 105 i, 1); 106 if (i == (1 << 2) - 1) { 107 test_error_eq(error, seL4_NoError); 108 } else { 109 test_error_eq(error, seL4_DeleteFirst); 110 } 111 } 112 113 vka_free_object(&env->vka, &untyped); 114 vka_free_object(&env->vka, &cnode); 115 return sel4test_get_result(); 116} 117DEFINE_TEST(RETYPE0000, "Retype test", test_retype, true) 118 119static int 120test_incretype(env_t env) 121{ 122 int error; 123 vka_object_t untyped; 124 int size_bits; 125 126 /* Find an untyped of some size. */ 127 for (size_bits = 13; size_bits > 0; size_bits--) { 128 error = vka_alloc_untyped(&env->vka, size_bits, &untyped); 129 if (error == 0) { 130 break; 131 } 132 } 133 test_error_eq(error, 0); 134 test_assert(untyped.cptr != 0); 135 136 /* Try retyping anything bigger than the object into it. */ 137 int i; 138 for (i = 40; i > 0; i--) { 139 error = seL4_Untyped_Retype(untyped.cptr, 140 seL4_CapTableObject, size_bits - seL4_SlotBits + i, 141 env->cspace_root, env->cspace_root, seL4_WordBits, 142 0, 1); 143 test_assert(error); 144 } 145 146 /* Try retyping an object of the correct size in. */ 147 error = seL4_Untyped_Retype(untyped.cptr, 148 seL4_CapTableObject, size_bits - seL4_SlotBits + 0, 149 env->cspace_root, env->cspace_root, seL4_WordBits, 150 0, 1); 151 test_error_eq(error, seL4_NoError); 152 153 /* clean up */ 154 vka_free_object(&env->vka, &untyped); 155 156 return sel4test_get_result(); 157} 158DEFINE_TEST(RETYPE0001, "Incremental retype test", test_incretype, true) 159 160static int 161test_incretype2(env_t env) 162{ 163 int error; 164 seL4_Word slot[17]; 165 vka_object_t untyped; 166 167 /* Get a bunch of free slots. */ 168 for (int i = 0; i < sizeof(slot) / sizeof(slot[0]); i++) { 169 error = vka_cspace_alloc(&env->vka, &slot[i]); 170 test_error_eq(error, 0); 171 } 172 173 /* And an untyped big enough to allocate 16 4-k pages into. */ 174 error = vka_alloc_untyped(&env->vka, 16, &untyped); 175 test_error_eq(error, 0); 176 test_assert(untyped.cptr != 0); 177 178 /* Try allocating precisely 16 pages. These should all work. */ 179 int i; 180 for (i = 0; i < 16; i++) { 181 error = seL4_Untyped_Retype(untyped.cptr, 182 seL4_ARCH_4KPage, 0, 183 env->cspace_root, env->cspace_root, seL4_WordBits, 184 slot[i], 1); 185 test_error_eq(error, seL4_NoError); 186 } 187 188 /* An obscenely large allocation should fail (note that's 2^(2^20)). */ 189 error = seL4_Untyped_Retype(untyped.cptr, 190 seL4_ARCH_4KPage, 0, 191 env->cspace_root, env->cspace_root, seL4_WordBits, 192 slot[i], 1024 * 1024); 193 test_error_eq(error, seL4_RangeError); 194 195 /* Allocating to an existing slot should fail. */ 196 error = seL4_Untyped_Retype(untyped.cptr, 197 seL4_ARCH_4KPage, 0, 198 env->cspace_root, env->cspace_root, seL4_WordBits, 199 slot[0], 8); 200 test_error_eq(error, seL4_DeleteFirst); 201 202 /* Allocating another item should also fail as the untyped is full. */ 203 error = seL4_Untyped_Retype(untyped.cptr, 204 seL4_ARCH_4KPage, 0, 205 env->cspace_root, env->cspace_root, seL4_WordBits, 206 slot[i++], 1); 207 test_error_eq(error, seL4_NotEnoughMemory); 208 209 vka_free_object(&env->vka, &untyped); 210 211 return sel4test_get_result(); 212} 213DEFINE_TEST(RETYPE0002, "Incremental retype test #2", test_incretype2, true) 214