Use API return structs.
These hide the ABI details and give a cleaner interface.
Change-Id: Icd2b27b438b39c128df60572dc047cffce18971b
diff --git a/main.c b/main.c
index efa00cc..739a95e 100644
--- a/main.c
+++ b/main.c
@@ -46,7 +46,7 @@
static int hf_vcpu_thread(void *data)
{
struct hf_vcpu *vcpu = data;
- int64_t ret;
+ struct hf_vcpu_run_return ret;
hrtimer_init(&vcpu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
vcpu->timer.function = &hf_vcpu_timer_expired;
@@ -66,20 +66,7 @@
/* Call into Hafnium to run vcpu. */
ret = hf_vcpu_run(vcpu->vm->id, vcpu->vcpu_index);
- /* A negative return value indicates that this vcpu needs to
- * sleep for the given number of nanoseconds.
- */
- if (ret < 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop())
- break;
- hrtimer_start(&vcpu->timer, -ret, HRTIMER_MODE_REL);
- schedule();
- hrtimer_cancel(&vcpu->timer);
- continue;
- }
-
- switch (HF_VCPU_RUN_CODE(ret)) {
+ switch (ret.code) {
/* Yield (forcibly or voluntarily). */
case HF_VCPU_RUN_YIELD:
break;
@@ -95,15 +82,13 @@
/* Wake up another vcpu. */
case HF_VCPU_RUN_WAKE_UP:
{
- 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)
+ if (ret.wake_up.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) {
+ vm = &hf_vms[ret.wake_up.vm_id - 1];
+ if (ret.wake_up.vcpu < vm->vcpu_count) {
+ wake_up_process(vm->vcpu[ret.wake_up.vcpu].task);
+ } else if (ret.wake_up.vcpu == HF_INVALID_VCPU) {
/* TODO: pick one to interrupt. */
pr_warning("No vcpu to wake.");
}
@@ -113,17 +98,25 @@
/* Response available. */
case HF_VCPU_RUN_MESSAGE:
{
- size_t i;
- uint32_t count = HF_VCPU_RUN_DATA(ret);
+ uint32_t i;
const char *buf = page_address(hf_recv_page);
pr_info("Received response from vm %u (%u bytes): ",
- vcpu->vm->id, count);
- for (i = 0; i < count; i++)
+ vcpu->vm->id, ret.message.size);
+ for (i = 0; i < ret.message.size; i++)
printk(KERN_CONT "%c", buf[i]);
printk(KERN_CONT "\n");
hf_mailbox_clear();
}
break;
+
+ case HF_VCPU_RUN_SLEEP:
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop())
+ break;
+ hrtimer_start(&vcpu->timer, ret.sleep.ns, HRTIMER_MODE_REL);
+ schedule();
+ hrtimer_cancel(&vcpu->timer);
+ break;
}
}