Basic memory sharing.

The introduces the basic functionality for memory sharing. The API used
to invoke memory sharing is a placeholder while we decide on what the
proper interface should look like.

Change-Id: Ia5c2c224119d896b3fc2294b0828626ec325e1e7
diff --git a/inc/vmapi/hf/abi.h b/inc/vmapi/hf/abi.h
index 451de41..4716f01 100644
--- a/inc/vmapi/hf/abi.h
+++ b/inc/vmapi/hf/abi.h
@@ -94,6 +94,26 @@
 	uint32_t size;
 };
 
+enum hf_share {
+	/**
+	 * Relinquish ownership and access to the memory and pass them to the
+	 * recipient.
+	 */
+	HF_MEMORY_GIVE,
+
+	/**
+	 * Retain ownership of the memory but relinquish access to the
+	 * recipient.
+	 */
+	HF_MEMORY_LEND,
+
+	/**
+	 * Retain ownership and access but additionally allow access to the
+	 * recipient.
+	 */
+	HF_MEMORY_SHARE,
+};
+
 /**
  * Encode an hf_vcpu_run_return struct in the 64-bit packing ABI.
  */
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 8014f8c..b0345e2 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -37,6 +37,7 @@
 #define HF_INTERRUPT_ENABLE     0xff0b
 #define HF_INTERRUPT_GET        0xff0c
 #define HF_INTERRUPT_INJECT     0xff0d
+#define HF_SHARE_MEMORY         0xff0e
 
 /** The amount of data that can be sent to a mailbox. */
 #define HF_MAILBOX_SIZE 4096
@@ -223,3 +224,18 @@
 	return hf_call(HF_INTERRUPT_INJECT, target_vm_id, target_vcpu_idx,
 		       intid);
 }
+
+/**
+ * Shares a region of memory with another VM.
+ *
+ * Returns 0 on success or -1 if the sharing was not allowed or failed.
+ *
+ * TODO: replace this with a better API once we have decided what that should
+ *       look like.
+ */
+static inline int64_t hf_share_memory(uint32_t vm_id, hf_ipaddr_t addr,
+				      size_t size, enum hf_share share)
+{
+	return hf_call(HF_SHARE_MEMORY, (((uint64_t)vm_id) << 32) | share, addr,
+		       size);
+}