Add support for new vcpu_run and mailbox_clear return values.
Change-Id: Ia5723b83f8c279d94a42abb2d46aa4dfc8a9e6b7
diff --git a/main.c b/main.c
index a49a4e2..bedc3f0 100644
--- a/main.c
+++ b/main.c
@@ -33,8 +33,6 @@
#define AF_HF AF_ECONET
#define PF_HF AF_HF
-#define MESSAGE_INT_ID 1
-
#define CONFIG_HAFNIUM_MAX_VMS 16
#define CONFIG_HAFNIUM_MAX_VCPUS 32
@@ -208,14 +206,15 @@
*
* It wakes up the thread if it's sleeping, or kicks it if it's already running.
*
- * If vCPU is HF_INVALID_VCPU, it injects a MESSAGE_INT_ID interrupt into a vCPU
- * belonging to the specified VM.
+ * If vCPU is HF_INVALID_VCPU, it injects an interrupt into a vCPU belonging to
+ * the specified VM.
*/
-static void hf_handle_wake_up_request(uint32_t vm_id, uint16_t vcpu)
+static void hf_handle_wake_up_request(uint32_t vm_id, uint16_t vcpu,
+ uint64_t int_id)
{
struct hf_vm *vm;
- if (vm_id > hf_vm_count) {
+ if (vm_id < 1 || vm_id > hf_vm_count) {
pr_warn("Request to wake up non-existent VM id: %u\n", vm_id);
return;
}
@@ -235,7 +234,7 @@
* we want to be smarter.
*/
vcpu = 0;
- ret = hf_interrupt_inject(vm_id, vcpu, MESSAGE_INT_ID);
+ ret = hf_interrupt_inject(vm_id, vcpu, int_id);
if (ret != 1) {
/* We don't need to wake up the vcpu. */
return;
@@ -253,6 +252,26 @@
}
/**
+ * Notify all waiters on the given VM.
+ */
+static void hf_notify_waiters(uint32_t vm_id)
+{
+ int64_t ret;
+
+ while ((ret = hf_mailbox_waiter_get(vm_id)) != -1) {
+ if (ret == HF_PRIMARY_VM_ID) {
+ /*
+ * TODO: Use this information when implementing per-vm
+ * queues.
+ */
+ } else {
+ hf_handle_wake_up_request(ret, HF_INVALID_VCPU,
+ HF_MAILBOX_WRITABLE_INTID);
+ }
+ }
+}
+
+/**
* This is the main loop of each vcpu.
*/
static int hf_vcpu_thread(void *data)
@@ -294,14 +313,16 @@
/* Wake up another vcpu. */
case HF_VCPU_RUN_WAKE_UP:
hf_handle_wake_up_request(ret.wake_up.vm_id,
- ret.wake_up.vcpu);
+ ret.wake_up.vcpu,
+ HF_MAILBOX_READBLE_INTID);
break;
/* Response available. */
case HF_VCPU_RUN_MESSAGE:
hf_handle_message(vcpu->vm, page_address(hf_recv_page),
ret.message.size);
- hf_mailbox_clear();
+ if (hf_mailbox_clear() == 1)
+ hf_notify_waiters(HF_PRIMARY_VM_ID);
break;
case HF_VCPU_RUN_SLEEP:
@@ -310,6 +331,11 @@
hf_vcpu_sleep(vcpu);
hrtimer_cancel(&vcpu->timer);
break;
+
+ /* Notify all waiters. */
+ case HF_VCPU_RUN_NOTIFY_WAITERS:
+ hf_notify_waiters(vcpu->vm->id);
+ break;
}
}
@@ -466,7 +492,7 @@
return -EAGAIN;
/* Wake some vcpu up to handle the new message. */
- hf_handle_wake_up_request(vm->id, ret);
+ hf_handle_wake_up_request(vm->id, ret, HF_MAILBOX_READBLE_INTID);
kfree_skb(skb);