22,6 → 22,9 |
* |
* This will return a pointer to the task to which the phone |
* is connected. It will lock the task, making sure it exists. |
* |
* Interrupts must be already disabled. |
* |
* (TODO: make sure the udebug-cleanup of the task hasn't |
* started yet) |
*/ |
30,13 → 33,10 |
answerbox_t *box; |
task_t *ta; |
task_id_t taskid; |
ipl_t ipl; |
|
ipl = interrupts_disable(); |
spinlock_lock(&phone->lock); |
if (phone->state != IPC_PHONE_CONNECTED) { |
spinlock_unlock(&phone->lock); |
interrupts_restore(ipl); |
return NULL; |
} |
|
54,13 → 54,11 |
ta = task_find_by_id(taskid); |
if (ta == NULL) { |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
return NULL; |
} |
|
spinlock_lock(&ta->lock); |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
|
return ta; |
} |
132,10 → 130,10 |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
t = list_get_instance(cur, thread_t, th_link); |
|
spinlock_lock(&t->lock); |
spinlock_lock(&t->debug_lock); |
if ((t->flags & THREAD_FLAG_USPACE) != 0) |
t->debug_active = true; |
spinlock_unlock(&t->lock); |
spinlock_unlock(&t->debug_lock); |
} |
|
spinlock_unlock(&ta->lock); |
154,6 → 152,7 |
|
thread_t *t; |
link_t *cur; |
int flags; |
|
klog_printf("udebug_rp_end()"); |
|
175,8 → 174,13 |
|
spinlock_lock(&t->lock); |
|
flags = t->flags; |
|
spinlock_lock(&t->debug_lock); |
spinlock_unlock(&t->lock); |
|
/* Only process userspace threads */ |
if ((t->flags & THREAD_FLAG_USPACE) != 0) { |
if ((flags & THREAD_FLAG_USPACE) != 0) { |
/* Prevent any further debug activity in thread */ |
t->debug_active = false; |
|
198,11 → 202,15 |
* Debug_stop is already at initial value. |
* Yet this means the thread needs waking up. |
*/ |
|
/* |
* t's lock must not be held when calling |
* waitq_wakeup. |
*/ |
waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
} |
} |
|
spinlock_unlock(&t->lock); |
spinlock_unlock(&t->debug_lock); |
} |
|
ta->dt_state = UDEBUG_TS_INACTIVE; |
223,8 → 231,12 |
thread_t *t; |
task_t *ta; |
ipl_t ipl; |
int rc; |
|
klog_printf("debug_go()"); |
|
ipl = interrupts_disable(); |
|
ta = get_lock_callee_task(phone); |
spinlock_unlock(&ta->lock); |
// TODO: don't lock ta |
231,15 → 243,40 |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
if (!thread_exists(t)) { |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
spinlock_lock(&t->debug_lock); |
|
/* Verify that thread t may be operated on */ |
rc = verify_thread(t, ta); |
if (rc != EOK) { |
spinlock_unlock(&t->debug_lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return rc; |
} |
|
/* |
* Since t->debug_active == true and t->debug_lock is held, |
* we can safely release threads_lock and t will continue |
* to exist (and will stay in debug_active state) |
*/ |
spinlock_unlock(&threads_lock); |
|
t->debug_go_call = call; |
t->debug_stop = false; |
|
/* |
* Neither t's lock nor threads_lock may be held during wakeup |
*/ |
waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
|
spinlock_unlock(&threads_lock); |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
|
return 0; /* no backsend */ |
256,6 → 293,7 |
|
klog_printf("debug_args_read()"); |
|
ipl = interrupts_disable(); |
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
spinlock_unlock(&ta->lock); |
262,23 → 300,37 |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
|
/* Verify that thread t exists and may be operated on */ |
if (!thread_exists(t)) { |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
spinlock_lock(&t->debug_lock); |
|
/* Verify that thread t may be operated on */ |
rc = verify_thread(t, ta); |
if (rc != EOK) { |
spinlock_unlock(&t->debug_lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return rc; |
} |
|
/* |
* We can now safely release threads_lock as debug_active == true |
* and t->debug_lock is held. |
*/ |
spinlock_unlock(&threads_lock); |
|
//FIXME: additionally we need to verify that we are inside a syscall |
|
/* Copy to a local buffer before releasing the lock */ |
memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t)); |
|
spinlock_unlock(&threads_lock); |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
|
/* Now copy to userspace */ |
318,14 → 370,29 |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
/* Verify that thread t exists and may be operated on */ |
if (!thread_exists(t)) { |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
spinlock_lock(&t->debug_lock); |
|
/* Verify that thread t may be operated on */ |
rc = verify_thread(t, ta); |
if (rc != EOK) { |
spinlock_unlock(&t->debug_lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return rc; |
} |
|
/* |
* We can now safely release threads_lock as debug_active == true |
* and t->debug_lock is held. |
*/ |
spinlock_unlock(&threads_lock); |
|
state = t->uspace_state; |
if (state == NULL) { |
spinlock_unlock(&threads_lock); |
336,7 → 403,7 |
|
/* Copy to a local buffer so that we can release the lock */ |
memcpy(&state_copy, state, sizeof(state_copy)); |
spinlock_unlock(&threads_lock); |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
|
uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
345,7 → 412,6 |
|
rc = copy_to_uspace(uspace_buffer, &state_copy, to_copy); |
if (rc != 0) { |
spinlock_unlock(&ta->lock); |
klog_printf("debug_regs_read() - copy failed"); |
return rc; |
} |
393,9 → 459,18 |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
/* Verify that thread t exists and may be operated on */ |
if (!thread_exists(t)) { |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
spinlock_lock(&t->debug_lock); |
|
/* Verify that thread t may be operated on */ |
rc = verify_thread(t, ta); |
if (rc != EOK) { |
spinlock_unlock(&t->debug_lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return rc; |
403,7 → 478,7 |
|
state = t->uspace_state; |
if (state == NULL) { |
spinlock_unlock(&threads_lock); |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
klog_printf("debug_regs_write() - istate not available"); |
return EBUSY; |
411,7 → 486,7 |
|
memcpy(t->uspace_state, &data_copy, sizeof(t->uspace_state)); |
|
spinlock_unlock(&threads_lock); |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
|
/* Set answer values */ |