Return SPCI_MEM_* rather than SPCI_MSG_SEND for push memory sharing.
Bug: 132420445
Change-Id: I80cb9832f90899eeb57af2cf209f0fa5f2fc1ca9
diff --git a/src/api.c b/src/api.c
index 143a624..5170a41 100644
--- a/src/api.c
+++ b/src/api.c
@@ -367,11 +367,25 @@
*/
static struct spci_value spci_msg_recv_return(const struct vm *receiver)
{
- return (struct spci_value){
- .func = SPCI_MSG_SEND_32,
- .arg1 = (receiver->mailbox.recv_sender << 16) | receiver->id,
- .arg3 = receiver->mailbox.recv_size,
- .arg4 = receiver->mailbox.recv_attributes};
+ switch (receiver->mailbox.recv_func) {
+ case SPCI_MSG_SEND_32:
+ return (struct spci_value){
+ .func = SPCI_MSG_SEND_32,
+ .arg1 = (receiver->mailbox.recv_sender << 16) |
+ receiver->id,
+ .arg3 = receiver->mailbox.recv_size};
+ case SPCI_MEM_DONATE_32:
+ case SPCI_MEM_LEND_32:
+ case SPCI_MEM_SHARE_32:
+ case HF_SPCI_MEM_RELINQUISH:
+ return (struct spci_value){.func = receiver->mailbox.recv_func,
+ .arg4 = receiver->mailbox.recv_size};
+ default:
+ /* This should never be reached, but return an error in case. */
+ dlog("Tried to return an invalid message function %#x\n",
+ receiver->mailbox.recv_func);
+ return spci_error(SPCI_DENIED);
+ }
}
/**
@@ -905,11 +919,11 @@
/* Messages for the primary VM are delivered directly. */
if (to.vm->id == HF_PRIMARY_VM_ID) {
/*
- * Only tell the primary VM the size if the message is for it,
- * to avoid leaking data about messages for other VMs.
+ * Only tell the primary VM the size and other details if the
+ * message is for it, to avoid leaking data about messages for
+ * other VMs.
*/
- primary_ret.arg3 = to.vm->mailbox.recv_size;
- primary_ret.arg4 = to.vm->mailbox.recv_attributes;
+ primary_ret = spci_msg_recv_return(to.vm);
to.vm->mailbox.state = MAILBOX_STATE_READ;
*next = api_switch_to_primary(current, primary_ret,
@@ -992,7 +1006,7 @@
memcpy_s(to->mailbox.recv, SPCI_MSG_PAYLOAD_MAX, from_msg, size);
to->mailbox.recv_size = size;
to->mailbox.recv_sender = sender_vm_id;
- to->mailbox.recv_attributes = 0;
+ to->mailbox.recv_func = SPCI_MSG_SEND_32;
ret = (struct spci_value){.func = SPCI_SUCCESS_32};
deliver_msg(to_locked, sender_vm_id, current, next);
@@ -1407,7 +1421,7 @@
}
}
-struct spci_value api_spci_mem_send(uint32_t share_type, ipaddr_t address,
+struct spci_value api_spci_mem_send(uint32_t share_func, ipaddr_t address,
uint32_t page_count,
uint32_t remaining_fragment_count,
uint32_t length, uint32_t handle,
@@ -1487,7 +1501,7 @@
ret = spci_msg_handle_architected_message(
vm_to_from_lock.vm1, vm_to_from_lock.vm2, memory_region, length,
- share_type, &api_page_pool);
+ share_func, &api_page_pool);
if (ret.func == SPCI_SUCCESS_32) {
deliver_msg(vm_to_from_lock.vm1, from->id, current, next);
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index b1b3b59..231bbe4 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -320,11 +320,13 @@
static bool spci_handler(struct spci_value *args, struct vcpu **next)
{
+ uint32_t func = args->func & ~SMCCC_CONVENTION_MASK;
+
/*
* NOTE: When adding new methods to this handler update
* api_spci_features accordingly.
*/
- switch (args->func & ~SMCCC_CONVENTION_MASK) {
+ switch (func) {
case SPCI_VERSION_32:
*args = api_spci_version();
return true;
@@ -367,28 +369,12 @@
current(), next);
return true;
case SPCI_MEM_DONATE_32:
- *args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_DONATE,
- ipa_init(args->arg1), args->arg2,
- args->arg3, args->arg4, args->arg5,
- current(), next);
- return true;
case SPCI_MEM_LEND_32:
- *args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_LEND,
- ipa_init(args->arg1), args->arg2,
- args->arg3, args->arg4, args->arg5,
- current(), next);
- return true;
case SPCI_MEM_SHARE_32:
- *args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_SHARE,
- ipa_init(args->arg1), args->arg2,
- args->arg3, args->arg4, args->arg5,
- current(), next);
- return true;
case HF_SPCI_MEM_RELINQUISH:
- *args = api_spci_mem_send(
- SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH,
- ipa_init(args->arg1), args->arg2, args->arg3,
- args->arg4, args->arg5, current(), next);
+ *args = api_spci_mem_send(func, ipa_init(args->arg1),
+ args->arg2, args->arg3, args->arg4,
+ args->arg5, current(), next);
return true;
}
diff --git a/src/spci_architected_message.c b/src/spci_architected_message.c
index 9d9c6c0..dd24aee 100644
--- a/src/spci_architected_message.c
+++ b/src/spci_architected_message.c
@@ -71,7 +71,7 @@
*
*/
static bool spci_msg_check_transition(struct vm *to, struct vm *from,
- uint32_t share_type,
+ uint32_t share_func,
uint32_t *orig_from_mode,
struct spci_memory_region *memory_region,
uint32_t memory_to_attributes,
@@ -267,23 +267,23 @@
return false;
}
- switch (share_type) {
- case SPCI_MSG_SEND_LEGACY_MEMORY_DONATE:
+ switch (share_func) {
+ case SPCI_MEM_DONATE_32:
mem_transition_table = donate_transitions;
transition_table_size = size_donate_transitions;
break;
- case SPCI_MSG_SEND_LEGACY_MEMORY_LEND:
+ case SPCI_MEM_LEND_32:
mem_transition_table = lend_transitions;
transition_table_size = size_lend_transitions;
break;
- case SPCI_MSG_SEND_LEGACY_MEMORY_SHARE:
+ case SPCI_MEM_SHARE_32:
mem_transition_table = share_transitions;
transition_table_size = size_share_transitions;
break;
- case SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH:
+ case HF_SPCI_MEM_RELINQUISH:
mem_transition_table = relinquish_transitions;
transition_table_size = size_relinquish_transitions;
break;
@@ -452,7 +452,7 @@
static struct spci_value spci_share_memory(
struct vm_locked to_locked, struct vm_locked from_locked,
struct spci_memory_region *memory_region, uint32_t memory_to_attributes,
- uint32_t share_type, struct mpool *api_page_pool)
+ uint32_t share_func, struct mpool *api_page_pool)
{
struct vm *to = to_locked.vm;
struct vm *from = from_locked.vm;
@@ -483,7 +483,7 @@
* in the memory exchange, ensure that all constituents of a memory
* region being shared are at the same state.
*/
- if (!spci_msg_check_transition(to, from, share_type, &orig_from_mode,
+ if (!spci_msg_check_transition(to, from, share_func, &orig_from_mode,
memory_region, memory_to_attributes,
&from_mode, &to_mode)) {
return spci_error(SPCI_INVALID_PARAMETERS);
@@ -567,7 +567,7 @@
static struct spci_value spci_validate_call_share_memory(
struct vm_locked to_locked, struct vm_locked from_locked,
struct spci_memory_region *memory_region, uint32_t memory_share_size,
- uint32_t share_type, struct mpool *api_page_pool)
+ uint32_t share_func, struct mpool *api_page_pool)
{
uint32_t memory_to_attributes;
uint32_t attributes_size;
@@ -603,14 +603,14 @@
return spci_error(SPCI_INVALID_PARAMETERS);
}
- switch (share_type) {
- case SPCI_MSG_SEND_LEGACY_MEMORY_DONATE:
- case SPCI_MSG_SEND_LEGACY_MEMORY_LEND:
- case SPCI_MSG_SEND_LEGACY_MEMORY_SHARE:
+ switch (share_func) {
+ case SPCI_MEM_DONATE_32:
+ case SPCI_MEM_LEND_32:
+ case SPCI_MEM_SHARE_32:
memory_to_attributes = spci_memory_attrs_to_mode(
memory_region->attributes[0].memory_attributes);
break;
- case SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH:
+ case HF_SPCI_MEM_RELINQUISH:
memory_to_attributes = MM_MODE_R | MM_MODE_W | MM_MODE_X;
break;
default:
@@ -619,7 +619,7 @@
}
return spci_share_memory(to_locked, from_locked, memory_region,
- memory_to_attributes, share_type,
+ memory_to_attributes, share_func,
api_page_pool);
}
@@ -631,11 +631,10 @@
struct spci_value spci_msg_handle_architected_message(
struct vm_locked to_locked, struct vm_locked from_locked,
struct spci_memory_region *memory_region, uint32_t size,
- uint32_t attributes, struct mpool *api_page_pool)
+ uint32_t share_func, struct mpool *api_page_pool)
{
- uint32_t share_type = attributes & SPCI_MSG_SEND_LEGACY_MEMORY_MASK;
struct spci_value ret = spci_validate_call_share_memory(
- to_locked, from_locked, memory_region, size, share_type,
+ to_locked, from_locked, memory_region, size, share_func,
api_page_pool);
/* Copy data to the destination Rx. */
@@ -652,7 +651,7 @@
memory_region, size);
to_locked.vm->mailbox.recv_size = size;
to_locked.vm->mailbox.recv_sender = from_locked.vm->id;
- to_locked.vm->mailbox.recv_attributes = share_type;
+ to_locked.vm->mailbox.recv_func = share_func;
}
return ret;