Update spci_msg_send to new SPCI beta API.
This removes the header in the message buffers, as the header data is now
passed in the SPCI_MSG_SEND parameters.
Bug: 141469322
Change-Id: I3a61f5470fd95ba2d47df33f5c96466ba286af85
diff --git a/inc/hf/api.h b/inc/hf/api.h
index ebc6b20..8c6328c 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -54,14 +54,15 @@
spci_vcpu_index_t target_vcpu_idx, uint32_t intid,
struct vcpu *current, struct vcpu **next);
-spci_return_t api_spci_msg_send(uint32_t attributes, struct vcpu *current,
- struct vcpu **next);
+struct spci_value api_spci_msg_send(spci_vm_id_t sender_vm_id,
+ spci_vm_id_t receiver_vm_id, uint32_t size,
+ uint32_t attributes, struct vcpu *current,
+ struct vcpu **next);
struct spci_value api_spci_msg_recv(bool block, struct vcpu *current,
struct vcpu **next);
void api_yield(struct vcpu *current, struct vcpu **next);
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,
- uint32_t memory_to_attributes,
- enum spci_memory_share share);
+struct spci_value api_spci_share_memory(
+ struct vm_locked to_locked, struct vm_locked from_locked,
+ struct spci_memory_region *memory_region, uint32_t memory_to_attributes,
+ enum spci_memory_share share);
diff --git a/inc/hf/spci_internal.h b/inc/hf/spci_internal.h
index 8f2a500..e046233 100644
--- a/inc/hf/spci_internal.h
+++ b/inc/hf/spci_internal.h
@@ -68,11 +68,11 @@
return (struct spci_value){.func = SPCI_ERROR_32, .arg1 = error_code};
}
-spci_return_t spci_msg_handle_architected_message(
+struct spci_value spci_msg_handle_architected_message(
struct vm_locked to_locked, struct vm_locked from_locked,
const struct spci_architected_message_header
*architected_message_replica,
- struct spci_message *from_msg_replica, struct spci_message *to_msg);
+ uint32_t size);
bool spci_msg_check_transition(struct vm *to, struct vm *from,
enum spci_memory_share share,
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
index 7ea1e12..4762a2e 100644
--- a/inc/hf/vm.h
+++ b/inc/hf/vm.h
@@ -60,8 +60,17 @@
struct mailbox {
enum mailbox_state state;
- struct spci_message *recv;
- const struct spci_message *send;
+ void *recv;
+ const void *send;
+
+ /** The ID of the VM which sent the message currently in `recv`. */
+ spci_vm_id_t recv_sender;
+
+ /** The size of the message currently in `recv`. */
+ uint32_t recv_size;
+
+ /** The attributes of the message currently in `recv`. */
+ uint32_t recv_attributes;
/**
* List of wait_entry structs representing VMs that want to be notified
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index a920a58..b3db3fc 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -115,14 +115,26 @@
* If the recipient's receive buffer is busy, it can optionally register the
* caller to be notified when the recipient's receive buffer becomes available.
*
- * Returns SPCI_SUCCESS if the message is sent, an error code otherwise:
- * - INVALID_PARAMETER: one or more of the parameters do not conform.
+ * Attributes may include:
+ * - SPCI_MSG_SEND_NOTIFY, to notify the caller when it should try again.
+ * - SPCI_MSG_SEND_LEGACY_MEMORY, to send a legacy architected memory sharing
+ * message.
+ *
+ * Returns SPCI_SUCCESS if the message is sent, or an error code otherwise:
+ * - INVALID_PARAMETERS: one or more of the parameters do not conform.
* - BUSY: the message could not be delivered either because the mailbox
- * was full or the target VM does not yet exist.
+ * was full or the target VM is not yet set up.
*/
-static inline int64_t spci_msg_send(uint32_t attributes)
+static inline struct spci_value spci_msg_send(spci_vm_id_t sender_vm_id,
+ spci_vm_id_t target_vm_id,
+ uint32_t size,
+ uint32_t attributes)
{
- return hf_call(SPCI_MSG_SEND_32, attributes, 0, 0);
+ return spci_call((struct spci_value){
+ .func = SPCI_MSG_SEND_32,
+ .arg1 = ((uint64_t)sender_vm_id << 16) | target_vm_id,
+ .arg3 = size,
+ .arg4 = attributes});
}
/**
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 125380b..e878ffe 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -61,23 +61,16 @@
};
/* SPCI function specific constants. */
+#define SPCI_MSG_RECV_BLOCK 0x1
#define SPCI_MSG_RECV_BLOCK_MASK 0x1
-#define SPCI_MSG_SEND_NOTIFY_MASK 0x1
-
-#define SPCI_MESSAGE_ARCHITECTED 0x0
-#define SPCI_MESSAGE_IMPDEF 0x1
-#define SPCI_MESSAGE_IMPDEF_MASK 0x1
#define SPCI_MSG_SEND_NOTIFY 0x1
-#define SPCI_MSG_RECV_BLOCK 0x1
+#define SPCI_MSG_SEND_NOTIFY_MASK 0x1
+#define SPCI_MSG_SEND_LEGACY_MEMORY 0x2
+#define SPCI_MSG_SEND_LEGACY_MEMORY_MASK 0x2
/* The maximum length possible for a single message. */
-#define SPCI_MSG_PAYLOAD_MAX (HF_MAILBOX_SIZE - sizeof(struct spci_message))
-
-#define spci_get_lend_descriptor(message)\
- ((struct spci_memory_lend *)(((uint8_t *) message)\
- + sizeof(struct spci_message)\
- + sizeof(struct spci_architected_message_header)))
+#define SPCI_MSG_PAYLOAD_MAX HF_MAILBOX_SIZE
enum spci_lend_access {
SPCI_LEND_RO_NX,
@@ -208,42 +201,10 @@
return args.arg3;
}
-/** SPCI common message header. */
-struct spci_message {
- /*
- * TODO: version is part of SPCI alpha2 but will be
- * removed in the next spec revision hence we are not
- * including it in the header.
- */
-
- /**
- * flags[0]:
- * 0: Architected message payload;
- * 1: Implementation defined message payload.
- * flags[15:1] reserved (MBZ).
- */
- uint16_t flags;
-
- /*
- * TODO: Padding is present to ensure controlled offset
- * of the length field. SPCI spec must be updated
- * to reflect this (TBD).
- */
- uint16_t reserved_1;
-
- uint32_t length;
- spci_vm_id_t target_vm_id;
- spci_vm_id_t source_vm_id;
-
- /*
- * TODO: Padding is present to ensure that the field
- * payload alignment is 64B. SPCI spec must be updated
- * to reflect this.
- */
- uint32_t reserved_2;
-
- uint8_t payload[];
-};
+static inline uint32_t spci_msg_send_attributes(struct spci_value args)
+{
+ return args.arg4;
+}
struct spci_architected_message_header {
uint16_t type;
@@ -281,73 +242,23 @@
};
/* TODO: Move all the functions below this line to a support library. */
-/**
- * Fill all the fields, except for the flags, in the SPCI message common header.
- */
-static inline void spci_common_header_init(struct spci_message *message,
- uint32_t message_length,
- spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id)
+
+static inline struct spci_memory_lend *spci_get_lend_descriptor(void *message)
{
- message->length = message_length;
- message->target_vm_id = target_vm_id;
- message->source_vm_id = source_vm_id;
-
- /*
- * TODO: Reserved fields in the common message header will be
- * defined as MBZ in next SPCI spec updates.
- */
- message->reserved_1 = 0;
- message->reserved_2 = 0;
-}
-
-/**
- * Set the SPCI implementation defined message header fields.
- */
-static inline void spci_message_init(struct spci_message *message,
- uint32_t message_length,
- spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id)
-{
- spci_common_header_init(message, message_length, target_vm_id,
- source_vm_id);
-
- message->flags = SPCI_MESSAGE_IMPDEF;
-}
-
-/**
- * Obtain a pointer to the architected header in the spci_message.
- *
- * Note: the argument "message" has const qualifier. This qualifier
- * is meant to forbid changes in information enclosed in the
- * struct spci_message. The spci_architected_message_header, for which
- * a pointer is returned in this function, is not part of spci_message.
- * Its information is meant to be changed and hence the returned pointer
- * does not have const type qualifier.
- */
-static inline struct spci_architected_message_header *
-spci_get_architected_message_header(const struct spci_message *message)
-{
- return (struct spci_architected_message_header *)message->payload;
+ return (struct spci_memory_lend
+ *)((struct spci_architected_message_header *)message)
+ ->payload;
}
/**
* Helper method to fill in the information about the architected message.
*/
-static inline void spci_architected_message_init(struct spci_message *message,
- uint32_t message_length,
- spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id,
+static inline void spci_architected_message_init(void *message,
enum spci_memory_share type)
{
- struct spci_architected_message_header *architected_header;
-
- spci_common_header_init(message, message_length, target_vm_id,
- source_vm_id);
- message->flags = SPCI_MESSAGE_ARCHITECTED;
-
/* Fill the architected header. */
- architected_header = spci_get_architected_message_header(message);
+ struct spci_architected_message_header *architected_header =
+ (struct spci_architected_message_header *)message;
architected_header->type = type;
architected_header->reserved[0] = 0;
architected_header->reserved[1] = 0;
@@ -356,10 +267,10 @@
/** Obtain a pointer to the start of the memory region in the donate message. */
static inline struct spci_memory_region *spci_get_donated_memory_region(
- struct spci_message *message)
+ void *message)
{
struct spci_architected_message_header *architected_header =
- spci_get_architected_message_header(message);
+ (struct spci_architected_message_header *)message;
return (struct spci_memory_region *)architected_header->payload;
}
@@ -396,64 +307,61 @@
}
/** Construct the SPCI donate memory region message. */
-static inline void spci_memory_donate(
- struct spci_message *message, spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id,
+static inline uint32_t spci_memory_donate_init(
+ void *message,
struct spci_memory_region_constituent *region_constituents,
uint32_t num_elements, uint32_t handle)
{
- int32_t message_length;
+ uint32_t message_length;
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(message);
message_length = sizeof(struct spci_architected_message_header);
/* Fill in the details on the common message header. */
- spci_architected_message_init(message, message_length, target_vm_id,
- source_vm_id, SPCI_MEMORY_DONATE);
+ spci_architected_message_init(message, SPCI_MEMORY_DONATE);
/* Create single memory region. */
- message->length += spci_memory_region_add(
+ message_length += spci_memory_region_add(
memory_region, handle, region_constituents, num_elements);
+ return message_length;
}
/**
* Construct the SPCI memory region relinquish message.
* A set of memory regions can be given back to the owner.
*/
-static inline void spci_memory_relinquish(
- struct spci_message *message, spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id,
+static inline uint32_t spci_memory_relinquish_init(
+ void *message,
struct spci_memory_region_constituent *region_constituents,
uint64_t num_elements, uint32_t handle)
{
- int32_t message_length;
+ uint32_t message_length;
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(message);
message_length = sizeof(struct spci_architected_message_header);
/* Fill in the details on the common message header. */
- spci_architected_message_init(message, message_length, target_vm_id,
- source_vm_id, SPCI_MEMORY_RELINQUISH);
+ spci_architected_message_init(message, SPCI_MEMORY_RELINQUISH);
/* Create single memory region. */
- message->length += spci_memory_region_add(
+ message_length += spci_memory_region_add(
memory_region, handle, region_constituents, num_elements);
+ return message_length;
}
/**
* Construct the SPCI memory region lend message.
*/
-static inline void spci_memory_lend(
- struct spci_message *message, spci_vm_id_t target_vm_id,
- spci_vm_id_t source_vm_id,
+static inline uint32_t spci_memory_lend_init(
+ void *message,
struct spci_memory_region_constituent *region_constituents,
uint64_t num_elements, uint32_t handle, enum spci_lend_access access,
enum spci_lend_type type, enum spci_lend_cacheability cacheability,
enum spci_lend_shareability shareability)
{
- int32_t message_length;
+ uint32_t message_length;
struct spci_memory_region *memory_region;
const struct spci_memory_lend lend_init = {0};
@@ -469,8 +377,7 @@
sizeof(struct spci_memory_lend);
/* Fill in the details on the common message header. */
- spci_architected_message_init(message, message_length, target_vm_id,
- source_vm_id, SPCI_MEMORY_LEND);
+ spci_architected_message_init(message, SPCI_MEMORY_LEND);
lend_descriptor->flags = SPCI_LEND_KEEP_MAPPED;
@@ -484,6 +391,7 @@
shareability);
/* Create single memory region. */
- message->length += spci_memory_region_add(
+ message_length += spci_memory_region_add(
memory_region, handle, region_constituents, num_elements);
+ return message_length;
}
diff --git a/inc/vmapi/hf/types.h b/inc/vmapi/hf/types.h
index 1612099..687dafa 100644
--- a/inc/vmapi/hf/types.h
+++ b/inc/vmapi/hf/types.h
@@ -21,6 +21,8 @@
#include <linux/types.h>
+#define INT32_C(c) c
+
typedef phys_addr_t hf_ipaddr_t;
#else