Use more macros for the API.
* Constants
* Packing and unpacking return values
* Avoid hack of shifting vcpu indicies
Change-Id: I965d01fb561eeb437be9804588fa8a8bfc69d486
diff --git a/driver/linux b/driver/linux
index 5570423..b3a61b5 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit 5570423fa47f8559d85b4db39a93ba3afba05cad
+Subproject commit b3a61b5fe4faf0f1111c203e385b1f100ecadc74
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index e8391f6..2195113 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -19,12 +19,6 @@
/* Keep macro alignment */
/* clang-format off */
-/* Return values for vcpu_run() hypervisor call. */
-#define HF_VCPU_YIELD 0x00
-#define HF_VCPU_WAIT_FOR_INTERRUPT 0x01
-#define HF_VCPU_WAKE_UP 0x02
-#define HF_VCPU_RESPONSE_READY 0x03
-
/* TODO: Define constants below according to spec. */
#define HF_VCPU_RUN 0xff00
#define HF_VM_GET_COUNT 0xff01
@@ -35,6 +29,19 @@
#define HF_RPC_ACK 0xff06
#define HF_RPC_REPLY 0xff07
+/* Return codes for hf_vcpu_run(). */
+#define HF_VCPU_RUN_YIELD 0x00
+#define HF_VCPU_RUN_WAIT_FOR_INTERRUPT 0x01
+#define HF_VCPU_RUN_WAKE_UP 0x02
+#define HF_VCPU_RUN_RESPONSE_READY 0x03
+
+/* Construct and destruct the hf_vcpu_run() response. */
+#define HF_VCPU_RUN_RESPONSE(code, data) ((code & 0xff) | (data << 8))
+#define HF_VCPU_RUN_CODE(ret) (ret & 0xff)
+#define HF_VCPU_RUN_DATA(ret) (ret >> 8)
+
+#define HF_RPC_REQUEST_MAX_SIZE 4096
+
/* clang-format on */
/**
diff --git a/src/api.c b/src/api.c
index 4176941..947982c 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1,10 +1,16 @@
#include "hf/api.h"
+#include <assert.h>
+
#include "hf/std.h"
#include "hf/vm.h"
#include "vmapi/hf/call.h"
+static_assert(HF_RPC_REQUEST_MAX_SIZE == PAGE_SIZE,
+ "Currently, a page is mapped for the send and receive buffers so "
+ "the maximum request is the size of a page.");
+
struct vm secondary_vm[MAX_VMS];
uint32_t secondary_vm_count;
struct vm primary_vm;
@@ -66,28 +72,28 @@
/* Only the primary VM can switch vcpus. */
if (cpu()->current->vm != &primary_vm) {
- return HF_VCPU_WAIT_FOR_INTERRUPT;
+ return HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0);
}
if (vm_idx >= secondary_vm_count) {
- return HF_VCPU_WAIT_FOR_INTERRUPT;
+ return HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0);
}
vm = secondary_vm + vm_idx;
if (vcpu_idx >= vm->vcpu_count) {
- return HF_VCPU_WAIT_FOR_INTERRUPT;
+ return HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0);
}
vcpu = vm->vcpus + vcpu_idx;
sl_lock(&vcpu->lock);
if (vcpu->state != vcpu_state_ready) {
- ret = HF_VCPU_WAIT_FOR_INTERRUPT;
+ ret = HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0);
} else {
vcpu->state = vcpu_state_running;
vm_set_current(vm);
*next = vcpu;
- ret = HF_VCPU_YIELD;
+ ret = HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_YIELD, 0);
}
sl_unlock(&vcpu->lock);
@@ -100,8 +106,9 @@
*/
struct vcpu *api_wait_for_interrupt(void)
{
- return api_switch_to_primary(HF_VCPU_WAIT_FOR_INTERRUPT,
- vcpu_state_blocked_interrupt);
+ return api_switch_to_primary(
+ HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0),
+ vcpu_state_blocked_interrupt);
}
/**
@@ -230,7 +237,7 @@
if (!to->rpc.recv_waiter) {
to->rpc.state = rpc_state_pending;
- ret = 0;
+ ret = to->vcpu_count;
} else {
struct vcpu *to_vcpu = to->rpc.recv_waiter;
@@ -246,7 +253,7 @@
arch_regs_set_retval(&to_vcpu->regs, size);
sl_unlock(&to_vcpu->lock);
- ret = to_vcpu - to->vcpus + 1;
+ ret = to_vcpu - to->vcpus;
}
}
@@ -298,8 +305,10 @@
* Inidicate to primary VM that this vcpu blocked waiting for an
* interrupt.
*/
- arch_regs_set_retval(&(*next)->regs,
- HF_VCPU_WAIT_FOR_INTERRUPT);
+ arch_regs_set_retval(
+ &(*next)->regs,
+ HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT,
+ 0));
ret = 0;
}
sl_unlock(&vm->lock);
@@ -368,8 +377,9 @@
* Switch back to primary VM so that it is aware that a response was
* received. But we leave the current vcpu still runnable.
*/
- *next = api_switch_to_primary((size << 8) | HF_VCPU_RESPONSE_READY,
- vcpu_state_ready);
+ *next = api_switch_to_primary(
+ HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_RESPONSE_READY, size),
+ vcpu_state_ready);
return 0;
}
diff --git a/src/arch/aarch64/handler.c b/src/arch/aarch64/handler.c
index d79ac4c..82ae461 100644
--- a/src/arch/aarch64/handler.c
+++ b/src/arch/aarch64/handler.c
@@ -214,7 +214,8 @@
/* TODO: Only switch if we know the interrupt was not for the secondary
* VM. */
/* Switch back to primary VM, interrupts will be handled there. */
- return api_switch_to_primary(HF_VCPU_YIELD, vcpu_state_ready);
+ return api_switch_to_primary(HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_YIELD, 0),
+ vcpu_state_ready);
}
struct vcpu *sync_lower_exception(uint64_t esr)