Using new-style return values for spci_version.
Bug: 132395846
Change-Id: I7d1a926b8dab526b3d8c3c6d06a8c136e5639e5e
diff --git a/driver/linux b/driver/linux
index d426b6c..4fef63d 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit d426b6cb6d2bdde5b7d6c140141f739378d2ca95
+Subproject commit 4fef63db09b5f9157496fa414bda628c4b9ef47b
diff --git a/inc/hf/api.h b/inc/hf/api.h
index e041c96..7dcdad3 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -21,6 +21,7 @@
#include "hf/vm.h"
#include "vmapi/hf/call.h"
+#include "vmapi/hf/spci.h"
void api_init(struct mpool *ppool);
spci_vm_id_t api_vm_get_id(const struct vcpu *current);
@@ -57,7 +58,7 @@
struct vcpu **next);
int32_t api_spci_msg_recv(bool block, struct vcpu *current, struct vcpu **next);
int32_t api_spci_yield(struct vcpu *current, struct vcpu **next);
-int32_t api_spci_version(void);
+struct spci_value api_spci_version(void);
spci_return_t api_spci_share_memory(struct vm_locked to_locked,
struct vm_locked from_locked,
struct spci_memory_region *memory_region,
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 9edc542..56bf012 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -47,6 +47,7 @@
* mechanism to call to the hypervisor.
*/
int64_t hf_call(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3);
+struct spci_value spci_call(struct spci_value args);
/**
* Returns the VM's own ID.
@@ -274,7 +275,7 @@
}
/** Obtains the Hafnium's version of the implemented SPCI specification. */
-static inline int64_t spci_version(void)
+static inline struct spci_value spci_version(void)
{
- return hf_call(SPCI_VERSION_32, 0, 0, 0);
+ return spci_call((struct spci_value){.func = SPCI_VERSION_32});
}
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 39fcaf1..0883038 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -182,6 +182,16 @@
/** Return type of SPCI functions. */
/* TODO: Reuse spci_return_t type on all SPCI functions declarations. */
typedef int32_t spci_return_t;
+struct spci_value {
+ uint64_t func;
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ uint64_t arg4;
+ uint64_t arg5;
+ uint64_t arg6;
+ uint64_t arg7;
+};
/** SPCI common message header. */
struct spci_message {
diff --git a/src/api.c b/src/api.c
index ff56751..a605ac4 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1653,7 +1653,7 @@
}
/** Returns the version of the implemented SPCI specification. */
-int32_t api_spci_version(void)
+struct spci_value api_spci_version(void)
{
/*
* Ensure that both major and minor revision representation occupies at
@@ -1664,8 +1664,11 @@
static_assert(0x10000 > SPCI_VERSION_MINOR,
"Minor revision representation take more than 16 bits.");
- return (SPCI_VERSION_MAJOR << SPCI_VERSION_MAJOR_OFFSET) |
- SPCI_VERSION_MINOR;
+ struct spci_value ret = {
+ .func = SPCI_SUCCESS_32,
+ .arg1 = (SPCI_VERSION_MAJOR << SPCI_VERSION_MAJOR_OFFSET) |
+ SPCI_VERSION_MINOR};
+ return ret;
}
int64_t api_debug_log(char c, struct vcpu *current)
diff --git a/src/arch/aarch64/hftest/hf_call.c b/src/arch/aarch64/hftest/hf_call.c
index ee591f1..c8cfabe 100644
--- a/src/arch/aarch64/hftest/hf_call.c
+++ b/src/arch/aarch64/hftest/hf_call.c
@@ -15,6 +15,7 @@
*/
#include "hf/call.h"
+#include "hf/spci.h"
#include "hf/types.h"
int64_t hf_call(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
@@ -34,3 +35,30 @@
return r0;
}
+
+struct spci_value spci_call(struct spci_value args)
+{
+ register uint64_t r0 __asm__("x0") = args.func;
+ register uint64_t r1 __asm__("x1") = args.arg1;
+ register uint64_t r2 __asm__("x2") = args.arg2;
+ register uint64_t r3 __asm__("x3") = args.arg3;
+ register uint64_t r4 __asm__("x4") = args.arg3;
+ register uint64_t r5 __asm__("x5") = args.arg3;
+ register uint64_t r6 __asm__("x6") = args.arg3;
+ register uint64_t r7 __asm__("x7") = args.arg3;
+
+ __asm__ volatile(
+ "hvc #0"
+ : /* Output registers, also used as inputs ('+' constraint). */
+ "+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4), "+r"(r5),
+ "+r"(r6), "+r"(r7));
+
+ return (struct spci_value){.func = r0,
+ .arg1 = r1,
+ .arg2 = r2,
+ .arg3 = r3,
+ .arg4 = r4,
+ .arg5 = r5,
+ .arg6 = r6,
+ .arg7 = r7};
+}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index e72d69e..154610a 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -303,33 +303,23 @@
return false;
}
-static bool spci_handler(uintreg_t func, uintreg_t arg1, uintreg_t arg2,
- uintreg_t arg3, uintreg_t arg4, uintreg_t arg5,
- uintreg_t arg6, uintreg_t arg7, uintreg_t *ret,
- struct vcpu **next)
+static bool spci_handler(struct spci_value *args, struct vcpu **next)
{
- (void)arg2;
- (void)arg3;
- (void)arg4;
- (void)arg5;
- (void)arg6;
- (void)arg7;
-
- switch (func & ~SMCCC_CONVENTION_MASK) {
+ switch (args->func & ~SMCCC_CONVENTION_MASK) {
case SPCI_VERSION_32:
- *ret = api_spci_version();
+ *args = api_spci_version();
return true;
case SPCI_YIELD_32:
- *ret = api_spci_yield(current(), next);
+ args->func = api_spci_yield(current(), next);
return true;
case SPCI_MSG_SEND_32:
- *ret = api_spci_msg_send(arg1, current(), next);
+ args->func = api_spci_msg_send(args->arg1, current(), next);
return true;
case SPCI_MSG_WAIT_32:
- *ret = api_spci_msg_recv(true, current(), next);
+ args->func = api_spci_msg_recv(true, current(), next);
return true;
case SPCI_MSG_POLL_32:
- *ret = api_spci_msg_recv(false, current(), next);
+ args->func = api_spci_msg_recv(false, current(), next);
return true;
}
@@ -390,28 +380,37 @@
struct vcpu *hvc_handler(struct vcpu *vcpu)
{
- uint32_t func = vcpu->regs.r[0];
- uintreg_t arg1 = vcpu->regs.r[1];
- uintreg_t arg2 = vcpu->regs.r[2];
- uintreg_t arg3 = vcpu->regs.r[3];
- uintreg_t arg4 = vcpu->regs.r[4];
- uintreg_t arg5 = vcpu->regs.r[5];
- uintreg_t arg6 = vcpu->regs.r[6];
- uintreg_t arg7 = vcpu->regs.r[7];
+ struct spci_value args = {
+ .func = vcpu->regs.r[0],
+ .arg1 = vcpu->regs.r[1],
+ .arg2 = vcpu->regs.r[2],
+ .arg3 = vcpu->regs.r[3],
+ .arg4 = vcpu->regs.r[4],
+ .arg5 = vcpu->regs.r[5],
+ .arg6 = vcpu->regs.r[6],
+ .arg7 = vcpu->regs.r[7],
+ };
struct vcpu *next = NULL;
- if (psci_handler(vcpu, func, arg1, arg2, arg3, &vcpu->regs.r[0],
- &next)) {
+ if (psci_handler(vcpu, args.func, args.arg1, args.arg2, args.arg3,
+ &vcpu->regs.r[0], &next)) {
return next;
}
- if (spci_handler(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
- &vcpu->regs.r[0], &next)) {
+ if (spci_handler(&args, &next)) {
+ vcpu->regs.r[0] = args.func;
+ vcpu->regs.r[1] = args.arg1;
+ vcpu->regs.r[2] = args.arg2;
+ vcpu->regs.r[3] = args.arg3;
+ vcpu->regs.r[4] = args.arg4;
+ vcpu->regs.r[5] = args.arg5;
+ vcpu->regs.r[6] = args.arg6;
+ vcpu->regs.r[7] = args.arg7;
update_vi(next);
return next;
}
- switch (func) {
+ switch (args.func) {
case HF_VM_GET_ID:
vcpu->regs.r[0] = api_vm_get_id(vcpu);
break;
@@ -421,17 +420,17 @@
break;
case HF_VCPU_GET_COUNT:
- vcpu->regs.r[0] = api_vcpu_get_count(arg1, vcpu);
+ vcpu->regs.r[0] = api_vcpu_get_count(args.arg1, vcpu);
break;
case HF_VCPU_RUN:
vcpu->regs.r[0] = hf_vcpu_run_return_encode(
- api_vcpu_run(arg1, arg2, vcpu, &next));
+ api_vcpu_run(args.arg1, args.arg2, vcpu, &next));
break;
case HF_VM_CONFIGURE:
- vcpu->regs.r[0] = api_vm_configure(ipa_init(arg1),
- ipa_init(arg2), vcpu, &next);
+ vcpu->regs.r[0] = api_vm_configure(
+ ipa_init(args.arg1), ipa_init(args.arg2), vcpu, &next);
break;
case HF_MAILBOX_CLEAR:
@@ -443,11 +442,12 @@
break;
case HF_MAILBOX_WAITER_GET:
- vcpu->regs.r[0] = api_mailbox_waiter_get(arg1, vcpu);
+ vcpu->regs.r[0] = api_mailbox_waiter_get(args.arg1, vcpu);
break;
case HF_INTERRUPT_ENABLE:
- vcpu->regs.r[0] = api_interrupt_enable(arg1, arg2, vcpu);
+ vcpu->regs.r[0] =
+ api_interrupt_enable(args.arg1, args.arg2, vcpu);
break;
case HF_INTERRUPT_GET:
@@ -455,18 +455,18 @@
break;
case HF_INTERRUPT_INJECT:
- vcpu->regs.r[0] =
- api_interrupt_inject(arg1, arg2, arg3, vcpu, &next);
+ vcpu->regs.r[0] = api_interrupt_inject(args.arg1, args.arg2,
+ args.arg3, vcpu, &next);
break;
case HF_SHARE_MEMORY:
- vcpu->regs.r[0] =
- api_share_memory(arg1 >> 32, ipa_init(arg2), arg3,
- arg1 & 0xffffffff, vcpu);
+ vcpu->regs.r[0] = api_share_memory(
+ args.arg1 >> 32, ipa_init(args.arg2), args.arg3,
+ args.arg1 & 0xffffffff, vcpu);
break;
case HF_DEBUG_LOG:
- vcpu->regs.r[0] = api_debug_log(arg1, vcpu);
+ vcpu->regs.r[0] = api_debug_log(args.arg1, vcpu);
break;
default:
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index 45cbd52..3ed4186 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -153,7 +153,9 @@
const int32_t current_version =
(major_revision << major_revision_offset) | minor_revision;
- EXPECT_EQ(spci_version(), current_version);
+ struct spci_value ret = spci_version();
+ EXPECT_EQ(ret.func, SPCI_SUCCESS_32);
+ EXPECT_EQ(ret.arg1, current_version);
}
/**