1/** 2 * \file 3 * \brief New retype test 4 */ 5 6/* 7 * Copyright (c) 2016, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <barrelfish/barrelfish.h> 17 18// adapted from usr/monitor/capops/internal.h 19#define GOTO_IF_ERR(err, label) do { \ 20 if (err_is_fail(err)) { \ 21 printf("...fail: %s\n", err_getstring(err)); \ 22 result = 1; \ 23 goto label; \ 24 } \ 25} while (0) 26 27static bool quiet = false; 28 29#define OUT(fmt...) \ 30do { \ 31 if (!quiet) { \ 32 printf(fmt); \ 33 } \ 34} while(0) 35 36//{{{1 setup & helpers 37static struct capref bunch_o_ram; 38static struct frame_identity bor_id; 39 40static void setup(size_t bytes) 41{ 42 errval_t err; 43 err = ram_alloc(&bunch_o_ram, log2ceil(bytes)); 44 assert(err_is_ok(err)); 45 err = frame_identify(bunch_o_ram, &bor_id); 46 assert(err_is_ok(err)); 47} 48 49static void cleanup(void) 50{ 51 errval_t err; 52 err = cap_revoke(bunch_o_ram); 53 assert(err_is_ok(err)); 54 err = cap_destroy(bunch_o_ram); 55 assert(err_is_ok(err)); 56} 57 58static void print_unexpected(char *info, genpaddr_t expected_base, 59 char *expected_size, genpaddr_t actual_base, 60 size_t actual_size) 61{ 62 printf("...fail: %sexpected %#"PRIxGENPADDR", %s; got %#"PRIxGENPADDR", %zu bytes\n", 63 info, expected_base, expected_size, actual_base, actual_size); 64} 65 66//{{{1 test_retype_single 67static int test_retype_single(void) 68{ 69 OUT("%s:\n", __FUNCTION__); 70 setup(LARGE_PAGE_SIZE); 71 72 int result = 0; 73 errval_t err; 74 struct frame_identity fi; 75 struct capref cap, cap2, cnram, cncap; 76 77 /* get slots for results */ 78 err = slot_alloc(&cap); 79 assert(err_is_ok(err)); 80 err = slot_alloc(&cap2); 81 assert(err_is_ok(err)); 82 err = slot_alloc(&cnram); 83 assert(err_is_ok(err)); 84 err = slot_alloc(&cncap); 85 assert(err_is_ok(err)); 86 87 /* allocate 4kB Frame at offset 0 of 2MB region */ 88 OUT(" allocate 4kB Frame at offset 0 of 2MB region: "); 89 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, BASE_PAGE_SIZE, 1); 90 GOTO_IF_ERR(err, out); 91 err = frame_identify(cap, &fi); 92 assert(err_is_ok(err)); 93 94 if (bor_id.base != fi.base || fi.bytes != BASE_PAGE_SIZE) { 95 print_unexpected("", bor_id.base, "4kB", fi.base, fi.bytes); 96 result = 1; 97 goto out; 98 } 99 OUT("...ok\n"); 100 101 /* allocate 16kB RAM at offset 4kB of 2MB region */ 102 OUT(" allocate 16kB RAM at offset 4kB of 2MB region: "); 103 err = cap_retype(cap2, bunch_o_ram, BASE_PAGE_SIZE, ObjType_RAM, BASE_PAGE_SIZE * 4, 1); 104 GOTO_IF_ERR(err, out); 105 err = frame_identify(cap2, &fi); 106 assert(err_is_ok(err)); 107 108 if (bor_id.base + BASE_PAGE_SIZE != fi.base || fi.bytes != 4*BASE_PAGE_SIZE) { 109 print_unexpected("", bor_id.base + BASE_PAGE_SIZE, "16kB", fi.base, fi.bytes); 110 result = 1; 111 goto out; 112 } 113 OUT("...ok\n"); 114 115#if 0 // this test does not make sense with twolevel cspace layout 116 /* split 16kB into 4kB CNode, and 3x4kB Frame */ 117 OUT(" split 16kB into 4kB CNode, and 3x4kB Frame: "); 118 err = cap_retype(cnram, cap2, 0, ObjType_RAM, BASE_PAGE_SIZE, 1); 119 GOTO_IF_ERR(err, out); 120 err = cnode_create_from_mem(cncap, cnram, &tmp.cnode, DEFAULT_CNODE_BITS); 121 GOTO_IF_ERR(err, out); 122 tmp.slot = 0; 123 124 err = cap_retype(tmp, cap2, BASE_PAGE_SIZE, ObjType_Frame, BASE_PAGE_SIZE, 3); 125 GOTO_IF_ERR(err, out); 126 // offset of slot 0 is 8kB --> addrs should be (2+slot) * BASE_PAGE_SIZE 127 for (tmp.slot = 0; tmp.slot <= 2; tmp.slot++) { 128 err = invoke_frame_identify(tmp, &fi); 129 assert(err_is_ok(err)); 130 if (bor_id.base + (2+tmp.slot)*BASE_PAGE_SIZE != fi.base || 131 fi.bytes != BASE_PAGE_SIZE) 132 { 133 char buf[16]; 134 snprintf(buf, 16, "slot %d: ", tmp.slot); 135 print_unexpected(buf, bor_id.base + (2+tmp.slot) * BASE_PAGE_SIZE, 136 "4kB", fi.base, fi.bytes); 137 result = 1; 138 goto out; 139 } 140 } 141 142 OUT("...ok\n"); 143#endif 144 145 146out: 147 slot_free(cap); 148 slot_free(cap2); 149 slot_free(cnram); 150 slot_free(cncap); 151 /* this also cleans up any descendants of bunch_o_ram */ 152 cleanup(); 153 return result; 154} 155 156//{{{1 test_retype_multi 157static int test_retype_multi(void) 158{ 159 OUT("%s:\n", __FUNCTION__); 160 setup(LARGE_PAGE_SIZE); 161 162 int result = 0; 163 errval_t err; 164 struct frame_identity fi; 165 struct capref cap, cap2; 166 167 /* get slots for results */ 168 err = slot_alloc(&cap); 169 assert(err_is_ok(err)); 170 err = slot_alloc(&cap2); 171 assert(err_is_ok(err)); 172 173 /* allocate 4kB Frame at offset 0 of 2MB region */ 174 OUT(" allocate 4kB Frame at offset 0 of 2MB region: "); 175 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, BASE_PAGE_SIZE, 1); 176 GOTO_IF_ERR(err, out); 177 err = frame_identify(cap, &fi); 178 assert(err_is_ok(err)); 179 180 if (bor_id.base != fi.base || fi.bytes != BASE_PAGE_SIZE) { 181 print_unexpected("", bor_id.base, "4kB", fi.base, fi.bytes); 182 result = 1; 183 goto out; 184 } 185 OUT("...ok\n"); 186 187 /* allocate 16kB RAM at offset 4kB of 2MB region */ 188 OUT(" allocate 16kB RAM at offset 4kB of 2MB region: "); 189 err = cap_retype(cap2, bunch_o_ram, BASE_PAGE_SIZE, ObjType_RAM, BASE_PAGE_SIZE * 4, 1); 190 GOTO_IF_ERR(err, out); 191 err = frame_identify(cap2, &fi); 192 assert(err_is_ok(err)); 193 194 if (bor_id.base + BASE_PAGE_SIZE != fi.base || fi.bytes != 4*BASE_PAGE_SIZE) { 195 print_unexpected("", bor_id.base + BASE_PAGE_SIZE, "16kB", fi.base, fi.bytes); 196 result = 1; 197 goto out; 198 } 199 OUT("...ok\n"); 200 201 /* delete first cap and retype first 4k again */ 202 OUT(" deleting first 4kB descendant\n"); 203 err = cap_delete(cap); 204 assert(err_is_ok(err)); 205 206 OUT(" allocating first 4kB again: "); 207 err = cap_retype(cap, bunch_o_ram, 0, ObjType_RAM, BASE_PAGE_SIZE, 1); 208 GOTO_IF_ERR(err, out); 209 err = frame_identify(cap, &fi); 210 assert(err_is_ok(err)); 211 212 if (bor_id.base != fi.base || fi.bytes != BASE_PAGE_SIZE) { 213 print_unexpected("", bor_id.base, "4kB", fi.base, fi.bytes); 214 result = 1; 215 goto out; 216 } 217 OUT("...ok\n"); 218 219out: 220 slot_free(cap); 221 slot_free(cap2); 222 /* this also cleans up any descendants of bunch_o_ram */ 223 cleanup(); 224 return result; 225} 226 227//{{{1 test_retype_overlap 228static int test_retype_overlap(void) 229{ 230 errval_t err; 231 int result = 0; 232 struct capref cap, cap2; 233 //struct frame_identity fi; 234 235 err = slot_alloc(&cap); 236 assert(err_is_ok(err)); 237 err = slot_alloc(&cap2); 238 assert(err_is_ok(err)); 239 240 setup(LARGE_PAGE_SIZE); 241 OUT("overlap testing with 32 pages allocated at offset 0:\n"); 242 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, 32*BASE_PAGE_SIZE, 1); 243 assert(err_is_ok(err)); 244 245 OUT(" allocating 16 pages at offset 16 pages: "); 246 err = cap_retype(cap2, bunch_o_ram, 16*BASE_PAGE_SIZE, 247 ObjType_Frame, 16*BASE_PAGE_SIZE, 1); 248 if (err_no(err) != SYS_ERR_REVOKE_FIRST) { 249 OUT("...fail: %s\n", err_getstring(err)); 250 result = 1; 251 goto out; 252 } 253 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 254 255 OUT(" allocating 4kB at offset 31 pages: "); 256 err = cap_retype(cap2, bunch_o_ram, BASE_PAGE_SIZE, 257 ObjType_Frame, 31*BASE_PAGE_SIZE, 1); 258 if (err_no(err) != SYS_ERR_REVOKE_FIRST) { 259 OUT("...fail: %s\n", err_getstring(err)); 260 result = 1; 261 goto out; 262 } 263 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 264 265 OUT(" allocating 16kB at offset 31 pages: "); 266 err = cap_retype(cap2, bunch_o_ram, 4*BASE_PAGE_SIZE, 267 ObjType_Frame, 31*BASE_PAGE_SIZE, 1); 268 if (err_no(err) != SYS_ERR_REVOKE_FIRST) { 269 OUT("...fail: %s\n", err_getstring(err)); 270 result = 1; 271 goto out; 272 } 273 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 274 275 OUT(" allocating 32 pages at offset 0: "); 276 err = cap_retype(cap2, bunch_o_ram, 0, 277 ObjType_Frame, 32*BASE_PAGE_SIZE, 1); 278 if (err_no(err) != SYS_ERR_REVOKE_FIRST) { 279 OUT("...fail: %s\n", err_getstring(err)); 280 result = 1; 281 goto out; 282 } 283 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 284 285out: 286 slot_free(cap); 287 slot_free(cap2); 288 cleanup(); 289 return result; 290} 291 292//{{{1 test_non_aligned 293static int test_non_aligned(void) 294{ 295 errval_t err; 296 int result = 0; 297 struct capref cap; 298 299 err = slot_alloc(&cap); 300 assert(err_is_ok(err)); 301 302 setup(LARGE_PAGE_SIZE); 303 OUT(" offset 1024: "); 304 err = cap_retype(cap, bunch_o_ram, 1024, ObjType_Frame, 32*BASE_PAGE_SIZE, 1); 305 if (err_no(err) != SYS_ERR_RETYPE_INVALID_OFFSET) { 306 OUT("...fail: %s\n", err_getstring(err)); 307 result = 1; 308 goto out; 309 } 310 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 311 OUT(" offset >= object size: "); 312 err = cap_retype(cap, bunch_o_ram, LARGE_PAGE_SIZE, ObjType_Frame, 313 32*BASE_PAGE_SIZE, 1); 314 if (err_no(err) != SYS_ERR_RETYPE_INVALID_OFFSET) { 315 OUT("...fail: %s\n", err_getstring(err)); 316 result = 1; 317 goto out; 318 } 319 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 320 OUT(" offset + objects >= object size: "); 321 err = cap_retype(cap, bunch_o_ram, LARGE_PAGE_SIZE - 31*BASE_PAGE_SIZE, ObjType_Frame, 322 32*BASE_PAGE_SIZE, 1); 323 if (err_no(err) != SYS_ERR_RETYPE_INVALID_OFFSET) { 324 OUT("...fail: %s\n", err_getstring(err)); 325 result = 1; 326 goto out; 327 } 328 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 329 OUT(" object size 6kB: "); 330 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, 6144, 1); 331 if (err_no(err) != SYS_ERR_INVALID_SIZE) { 332 OUT("...fail: %s\n", err_getstring(err)); 333 result = 1; 334 goto out; 335 } 336 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 337 338 OUT(" objects do not fit into cap: "); 339 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, BASE_PAGE_SIZE, 513); 340 if (err_no(err) != SYS_ERR_RETYPE_INVALID_COUNT) { 341 OUT("...fail: %s\n", err_getstring(err)); 342 result = 1; 343 goto out; 344 } 345 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 346 347 OUT(" object larger than cap: "); 348 err = cap_retype(cap, bunch_o_ram, 0, ObjType_Frame, 513*BASE_PAGE_SIZE, 1); 349 if (err_no(err) != SYS_ERR_INVALID_SIZE) { 350 OUT("...fail: %s\n", err_getstring(err)); 351 result = 1; 352 goto out; 353 } 354 OUT("...ok: retype fails with '%s'\n", err_getstring(err)); 355 356out: 357 slot_free(cap); 358 cleanup(); 359 return result; 360} 361 362//{{{1 main 363int main(int argc, char *argv[]) 364{ 365 if (argc >= 2) { 366 quiet = !strncmp(argv[1], "quiet", 5); 367 } 368 int result = 0; 369 OUT("0: Non-overlapping retype test, no deletion\n"); 370 result |= test_retype_single() << 0; 371 OUT("1: Non-overlapping retype test, with deletions\n"); 372 result |= test_retype_multi() << 1; 373 OUT("2: Overlapping retype test\n"); 374 result |= test_retype_overlap() << 2; 375 OUT("3: Non-aligned retype test\n"); 376 result |= test_non_aligned() << 3; 377 378 printf("retype: result: %x\n", result); 379 380 return result; 381} 382