static int _refill_pool(struct allocman *alloc, utspace_trickle_t *trickle, uint32_t size_bits) { uint32_t i; int error; struct utspace_trickle_node *node; uint32_t cookie; node = _make_node(alloc, &error); if (error) { return error; } /* Check if there are untypeds >= 5 size_bits from us */ for (i = size_bits + 5 > 31 ? 31 : size_bits + 5; i < 32; i++) { if (trickle->heads[i]) { i = size_bits + 5; break; } } if (i == 32) { /* Search for the biggest one near us */ for (i = size_bits + 5 > 31 ? 31 : size_bits + 5; i > size_bits; i--) { if (trickle->heads[i]) { break; } } } if (i != size_bits) { cookie = _utspace_trickle_alloc(alloc, trickle, i, seL4_UntypedObject, NULL, &error); if (!error) { struct utspace_trickle_node *parent = _cookie_to_node(cookie); uint32_t offset = _cookie_to_offset(cookie); node->ut = parent->ut; node->offset = parent->offset + (offset << (i)); if (parent->paddr) { node->paddr = parent->paddr + (offset << (i)); } else { node->paddr = 0; } node->parent_cookie = cookie; node->bitmap_bits = i - size_bits + 1; node->bitmap = _make_bitmap(node->bitmap_bits); node->next = node->prev = NULL; _insert_node(&trickle->heads[size_bits], node); return 0; } } _free_node(alloc, node); return 1; }
int proxy_vka_utspace_alloc(void *data, const cspacepath_t *dest, seL4_Word type, seL4_Word size_bits, uint32_t *res) { proxy_vka_t *vka = (proxy_vka_t*)data; int error; uint32_t cookie; ut_node_t *node = allocman_mspace_alloc(vka->allocman, sizeof(*node), &error); if (!node) { return -1; } if (type == seL4_IA32_4K && vka->have_mem && vka->vspace.map_pages_at_vaddr && !vka->recurse) { cookie = _utspace_trickle_alloc(vka->allocman, &vka->ram_ut_manager, seL4_PageBits, seL4_IA32_4K, dest, &error); if (error != 0) { vka->have_mem = 0; } else { node->frame = 1; node->cookie = cookie; /* briefly map this frame in so we can zero it. Avoid recursively allocating * for book keeping */ assert(!vka->recurse); vka->recurse = 1; error = vspace_map_pages_at_vaddr(&vka->vspace, (seL4_CPtr*)&dest->capPtr, NULL, vka->temp_map_address, 1, PAGE_BITS_4K, vka->temp_map_reservation); assert(!error); memset(vka->temp_map_address, 0, PAGE_SIZE_4K); vspace_unmap_pages(&vka->vspace, vka->temp_map_address, 1, PAGE_BITS_4K, VSPACE_PRESERVE); vka->recurse = 0; return 0; } } error = vka_utspace_alloc(&vka->regular_vka, dest, type, size_bits, &cookie); if (!error) { node->frame = 0; node->cookie = cookie; *res = (uint32_t)node; return 0; } allocman_mspace_free(vka->allocman, node, sizeof(*node)); return error; }