Conform to the mailbox API.
Messages can be sent between any VMs so the scheduler needs to be able
to wake vcpus from any VM.
Bug: 116705004
Change-Id: I71ae829087849dcc515a7e5f21a335d360050e30
diff --git a/main.c b/main.c
index b80c3db..efa00cc 100644
--- a/main.c
+++ b/main.c
@@ -95,24 +95,33 @@
/* Wake up another vcpu. */
case HF_VCPU_RUN_WAKE_UP:
{
- int32_t target = HF_VCPU_RUN_DATA(ret);
- struct hf_vm *vm = vcpu->vm;
- if (target < vm->vcpu_count)
- wake_up_process(vm->vcpu[target].task);
+ uint32_t vm_id = HF_VCPU_RUN_VM_ID(ret);
+ uint32_t vcpu = HF_VCPU_RUN_DATA(ret);
+ struct hf_vm *vm;
+ if (vm_id > hf_vm_count)
+ break;
+ vm = &hf_vms[vm_id - 1];
+ if (vcpu < vm->vcpu_count) {
+ wake_up_process(vm->vcpu[vcpu].task);
+ } else if (vcpu == HF_INVALID_VCPU) {
+ /* TODO: pick one to interrupt. */
+ pr_warning("No vcpu to wake.");
+ }
}
break;
/* Response available. */
- case HF_VCPU_RUN_RESPONSE_READY:
+ case HF_VCPU_RUN_MESSAGE:
{
- size_t i, count = HF_VCPU_RUN_DATA(ret);
+ size_t i;
+ uint32_t count = HF_VCPU_RUN_DATA(ret);
const char *buf = page_address(hf_recv_page);
- pr_info("Received response (%zu bytes): ",
- count);
+ pr_info("Received response from vm %u (%u bytes): ",
+ vcpu->vm->id, count);
for (i = 0; i < count; i++)
printk(KERN_CONT "%c", buf[i]);
printk(KERN_CONT "\n");
- hf_rpc_ack();
+ hf_mailbox_clear();
}
break;
}
@@ -186,30 +195,32 @@
int64_t ret;
struct hf_vm *vm;
- count = min_t(size_t, count, HF_RPC_REQUEST_MAX_SIZE);
+ count = min_t(size_t, count, HF_MAILBOX_SIZE);
/* Copy data to send buffer. */
memcpy(page_address(hf_send_page), buf, count);
vm = &hf_vms[0];
- ret = hf_rpc_request(vm->id, count);
+ ret = hf_mailbox_send(vm->id, count);
if (ret < 0)
return -EAGAIN;
- if (ret > vm->vcpu_count)
+ if (ret == HF_INVALID_VCPU) {
+ /*
+ * TODO: We need to interrupt some vcpu because none are waiting
+ * for data.
+ */
+ pr_warning("No vcpu to receive message.");
+ return -ENOSYS;
+ }
+
+ if (ret >= vm->vcpu_count)
return -EINVAL;
- if (ret == vm->vcpu_count) {
- /*
- * TODO: We need to interrupt some CPU because none is actually
- * waiting for data.
- */
- } else {
- /* Wake up the vcpu that is going to process the data. */
- /* TODO: There's a race where thread may get wake up before it
- * goes to sleep. Fix this. */
- wake_up_process(vm->vcpu[ret].task);
- }
+ /* Wake up the vcpu that is going to process the data. */
+ /* TODO: There's a race where thread may get wake up before it
+ * goes to sleep. Fix this. */
+ wake_up_process(vm->vcpu[ret].task);
return count;
}