void sl_siglines_free_line(struct sl_siglines* sglns, sl_sigline_t line) { BUG_ON(!is_direction_sender(sglns->dir)); BUG_ON(!is_line_valid(sglns, line)); uint32_t i = line / NBITS_PER_UINT64; uint32_t j = line % NBITS_PER_UINT64; set_bit(&sglns->free_lines[i], j); }
int sl_siglines_revoke_signal(struct sl_siglines* sglns, sl_sigline_t line) { BUG_ON(!is_direction_sender(sglns->dir)); BUG_ON(!is_line_valid(sglns, line)); uint32_t i = line / NBITS_PER_UINT64; uint32_t j = line % NBITS_PER_UINT64; return test_and_clear_bit(&sglns->event_lines[i], j) == 0; }
int sl_siglines_clone(struct sl_siglines* sglns, struct sl_siglines* untrusted, sl_sighandler_t handler) { PANIC_ON(!sgx_is_outside_enclave(untrusted, sizeof(*untrusted))); sgx_lfence(); sl_siglines_dir_t dir = untrusted->dir; PANIC_ON((dir != SL_SIGLINES_DIR_T2U) && (dir != SL_SIGLINES_DIR_U2T)); BUG_ON(sglns == NULL); sglns->dir = dir; BUG_ON(is_direction_sender(dir) && (handler != NULL)); uint32_t num_lines = untrusted->num_lines; if ((num_lines <= 0) || ((num_lines % NBITS_PER_UINT64) != 0)) return -EINVAL; sglns->num_lines = num_lines; uint32_t nlong = num_lines / NBITS_PER_UINT64; BUG_ON(untrusted->event_lines == NULL); uint64_t* event_lines_u = untrusted->event_lines; PANIC_ON(!sgx_is_outside_enclave(event_lines_u, sizeof(uint64_t) * nlong)); sgx_lfence(); sglns->event_lines = event_lines_u; uint64_t* free_lines = NULL; if (is_direction_sender(dir)) { free_lines = malloc(sizeof(uint64_t) * nlong); if (free_lines == NULL) return -ENOMEM; for (uint32_t i = 0; i < nlong; i++) free_lines[i] = (uint64_t)(-1);// 1's -> free } sglns->free_lines = free_lines; sglns->handler = handler; return 0; }
int sl_siglines_trigger_signal(struct sl_siglines* sglns, sl_sigline_t line) { BUG_ON(!is_direction_sender(sglns->dir)); BUG_ON(!is_line_valid(sglns, line)); uint32_t i = line / NBITS_PER_UINT64; uint32_t j = line % NBITS_PER_UINT64; set_bit(&sglns->event_lines[i], j); return 0; }
sl_sigline_t sl_siglines_alloc_line(struct sl_siglines* sglns) { BUG_ON(!is_direction_sender(sglns->dir)); uint32_t i, max_i = (sglns->num_lines / NBITS_PER_UINT64); uint64_t* bits_p; for (i = 0; i < max_i; i++) { bits_p = &sglns->free_lines[i]; int32_t j = extract_one_bit(bits_p); if (j < 0) continue; sl_sigline_t free_line = NBITS_PER_UINT64 * i + (uint32_t)j; return free_line; } return SL_INVALID_SIGLINE; }