1/** 2 * \file 3 * \brief remote 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 <barrelfish/barrelfish.h> 16#include <if/test_defs.h> 17 18#include "test.h" 19 20__attribute__((unused)) 21static void debug_capref(const char *prefix, struct capref cap) 22{ 23 char buf[128]; 24 debug_print_capref(buf, 128, cap); 25 printf("%s capref = %s\n", prefix, buf); 26} 27 28enum server_op { 29 SERVER_OP_CREATE_COPY, 30 // Create a BASE_PAGE_SIZEd Frame cap of last page in RAM 31 SERVER_OP_RETYPE_1, 32 // Try to create a BASE_PAGE_SIZEd Frame cap of first page in RAM 33 SERVER_OP_RETYPE_2, 34}; 35 36enum client_op { 37 // do a retype on client while server holds copies of cap but no 38 // descendants 39 CLIENT_OP_RETYPE_1, 40 // Do retype (overlapping and non-overlapping) on client while server 41 // holds copies of cap and Frame of last page in region 42 CLIENT_OP_RETYPE_2, 43 // Exit client 44 CLIENT_OP_EXIT, 45}; 46 47//{{{1 Server-side cap operations 48 49struct server_state { 50 struct capref ram; 51 struct capref copy; 52 struct capref frame1; 53}; 54 55void init_server(struct test_binding *b) 56{ 57 b->st = malloc(sizeof(struct server_state)); 58 assert(b->st); 59 if (!b->st) { 60 USER_PANIC("state malloc() in server"); 61 } 62} 63 64void server_do_test(struct test_binding *b, uint32_t test, struct capref cap) 65{ 66 errval_t err; 67 struct server_state *st = b->st; 68 69 switch(test) { 70 case SERVER_OP_CREATE_COPY: 71 // First call: store RAM cap in our state 72 st->ram = cap; 73 printf("server: creating a copy\n"); 74 err = slot_alloc(&st->copy); 75 PANIC_IF_ERR(err, "slot alloc for copy in server"); 76 77 err = cap_copy(st->copy, cap); 78 PANIC_IF_ERR(err, "copy in server"); 79 80 err = test_basic__tx(b, NOP_CONT, CLIENT_OP_RETYPE_1); 81 PANIC_IF_ERR(err, "server: triggering 1st retype on client"); 82 break; 83 84 case SERVER_OP_RETYPE_1: 85 printf("server: retype last page\n"); 86 87 server_test_retype(st->copy, &st->frame1, RAM_SIZE - BASE_PAGE_SIZE, 88 BASE_PAGE_SIZE, 1, SYS_ERR_OK); 89 90 printf("server: triggering 2nd set of retypes in client\n"); 91 err = test_basic__tx(b, NOP_CONT, CLIENT_OP_RETYPE_2); 92 PANIC_IF_ERR(err, "server: triggering 2nd set of retypes on client"); 93 break; 94 95 case SERVER_OP_RETYPE_2: 96 printf("server: retype first frame, expected to fail\n"); 97 err = cap_delete(st->frame1); 98 PANIC_IF_ERR(err, "cap delete for result of first retype"); 99 100 server_test_retype(st->copy, &st->frame1, 0, BASE_PAGE_SIZE, 1, 101 SYS_ERR_REVOKE_FIRST); 102 103 err = test_basic__tx(b, NOP_CONT, CLIENT_OP_EXIT); 104 printf("distops_retype: test done\n"); 105 printf("server: exit\n"); 106 exit(0); 107 108 default: 109 USER_PANIC("server: Unknown test %"PRIu32"\n", test); 110 } 111} 112 113//{{{1 Client-side cap operations 114 115struct client_state { 116 struct capref ram; 117 struct capref frame; 118}; 119 120void init_client(struct test_binding *b) 121{ 122 errval_t err; 123 124 // Allocate client state struct 125 b->st = malloc(sizeof(struct client_state)); 126 assert(b->st); 127 if (!b->st) { 128 USER_PANIC("state malloc() in client"); 129 } 130 struct client_state *cst = b->st; 131 132 // Allocate RAM cap 133 err = ram_alloc(&cst->ram, RAM_BITS); 134 PANIC_IF_ERR(err, "in client: ram_alloc"); 135 136 // Trigger Server 137 err = test_caps__tx(b, NOP_CONT, SERVER_OP_CREATE_COPY, cst->ram, NULL_CAP); 138 PANIC_IF_ERR(err, "in client: sending cap to server"); 139} 140 141void client_do_test(struct test_binding *b, uint32_t test, struct capref cap) 142{ 143 errval_t err; 144 struct client_state *st = b->st; 145 assert(st); 146 147 switch(test) { 148 // Do retype while copies exist on other core 149 case CLIENT_OP_RETYPE_1: 150 printf("client: retype #1\n"); 151 printf(" retype first page: should succeed\n"); 152 client_test_retype(st->ram, NULL, 0, BASE_PAGE_SIZE, 1, SYS_ERR_OK); 153 err = test_basic__tx(b, NOP_CONT, SERVER_OP_RETYPE_1); 154 PANIC_IF_ERR(err, "client: trigger first retype on server"); 155 break; 156 157 case CLIENT_OP_RETYPE_2: 158 printf("client: retype #2\n"); 159 printf(" retype last page: should fail\n"); 160 client_test_retype(st->ram, NULL, RAM_SIZE - BASE_PAGE_SIZE, BASE_PAGE_SIZE, 1, 161 SYS_ERR_REVOKE_FIRST); 162 163 printf(" retype first page: should succeed\n"); 164 client_test_retype(st->ram, &st->frame, 0, BASE_PAGE_SIZE, 1, SYS_ERR_OK); 165 166 printf(" retype 2nd last page: should succeed\n"); 167 client_test_retype(st->ram, NULL, RAM_SIZE - 2*BASE_PAGE_SIZE, 168 BASE_PAGE_SIZE, 1, SYS_ERR_OK); 169 170 err = test_basic__tx(b, NOP_CONT, SERVER_OP_RETYPE_2); 171 PANIC_IF_ERR(err, "client: trigger 2nd set of retypes on server"); 172 break; 173 174 case CLIENT_OP_EXIT: 175 printf("client: exit\n"); 176 exit(0); 177 178 default: 179 USER_PANIC("client: Unknown test %"PRIu32"\n", test); 180 } 181} 182