@@ -39,6 +39,9 @@ EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
#define GUNYAH_HYPERCALL_HYP_IDENTIFY GUNYAH_HYPERCALL(0x8000)
#define GUNYAH_HYPERCALL_MSGQ_SEND GUNYAH_HYPERCALL(0x801B)
#define GUNYAH_HYPERCALL_MSGQ_RECV GUNYAH_HYPERCALL(0x801C)
+#define GUNYAH_HYPERCALL_ADDRSPACE_MAP GUNYAH_HYPERCALL(0x802B)
+#define GUNYAH_HYPERCALL_ADDRSPACE_UNMAP GUNYAH_HYPERCALL(0x802C)
+#define GUNYAH_HYPERCALL_MEMEXTENT_DONATE GUNYAH_HYPERCALL(0x8061)
#define GUNYAH_HYPERCALL_VCPU_RUN GUNYAH_HYPERCALL(0x8065)
/* clang-format on */
@@ -114,6 +117,90 @@ enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
}
EXPORT_SYMBOL_GPL(gunyah_hypercall_msgq_recv);
+/**
+ * gunyah_hypercall_addrspace_map() - Add memory to an address space from a memory extent
+ * @capid: Address space capability ID
+ * @extent_capid: Memory extent capability ID
+ * @vbase: location in address space
+ * @extent_attrs: Attributes for the memory
+ * @flags: Flags for address space mapping
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to map; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_addrspace_map(u64 capid, u64 extent_capid, u64 vbase,
+ u32 extent_attrs, u32 flags, u64 offset, u64 size)
+{
+ struct arm_smccc_1_2_regs args = {
+ .a0 = GUNYAH_HYPERCALL_ADDRSPACE_MAP,
+ .a1 = capid,
+ .a2 = extent_capid,
+ .a3 = vbase,
+ .a4 = extent_attrs,
+ .a5 = flags,
+ .a6 = offset,
+ .a7 = size,
+ /* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+ .a8 = 0,
+ };
+ struct arm_smccc_1_2_regs res;
+
+ arm_smccc_1_2_hvc(&args, &res);
+
+ return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_addrspace_map);
+
+/**
+ * gunyah_hypercall_addrspace_unmap() - Remove memory from an address space
+ * @capid: Address space capability ID
+ * @extent_capid: Memory extent capability ID
+ * @vbase: location in address space
+ * @flags: Flags for address space mapping
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to map; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_addrspace_unmap(u64 capid, u64 extent_capid, u64 vbase,
+ u32 flags, u64 offset, u64 size)
+{
+ struct arm_smccc_1_2_regs args = {
+ .a0 = GUNYAH_HYPERCALL_ADDRSPACE_UNMAP,
+ .a1 = capid,
+ .a2 = extent_capid,
+ .a3 = vbase,
+ .a4 = flags,
+ .a5 = offset,
+ .a6 = size,
+ /* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+ .a7 = 0,
+ };
+ struct arm_smccc_1_2_regs res;
+
+ arm_smccc_1_2_hvc(&args, &res);
+
+ return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_addrspace_unmap);
+
+/**
+ * gunyah_hypercall_memextent_donate() - Donate memory from one memory extent to another
+ * @options: donate options
+ * @from_capid: Memory extent capability ID to donate from
+ * @to_capid: Memory extent capability ID to donate to
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to donate; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_memextent_donate(u32 options, u64 from_capid, u64 to_capid,
+ u64 offset, u64 size)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_MEMEXTENT_DONATE, options, from_capid, to_capid,
+ offset, size, 0, &res);
+
+ return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_memextent_donate);
+
/**
* gunyah_hypercall_vcpu_run() - Donate CPU time to a vcpu
* @capid: capability ID of the vCPU to run
@@ -33,4 +33,25 @@ static inline int arch_gunyah_fill_irq_fwspec_params(u32 virq,
return 0;
}
+enum arch_gunyah_memtype {
+ /* clang-format off */
+ GUNYAH_MEMTYPE_DEVICE_nGnRnE = 0,
+ GUNYAH_DEVICE_nGnRE = 1,
+ GUNYAH_DEVICE_nGRE = 2,
+ GUNYAH_DEVICE_GRE = 3,
+
+ GUNYAH_NORMAL_NC = 0b0101,
+ GUNYAH_NORMAL_ONC_IWT = 0b0110,
+ GUNYAH_NORMAL_ONC_IWB = 0b0111,
+ GUNYAH_NORMAL_OWT_INC = 0b1001,
+ GUNYAH_NORMAL_WT = 0b1010,
+ GUNYAH_NORMAL_OWT_IWB = 0b1011,
+ GUNYAH_NORMAL_OWB_INC = 0b1101,
+ GUNYAH_NORMAL_OWB_IWT = 0b1110,
+ GUNYAH_NORMAL_WB = 0b1111,
+ /* clang-format on */
+};
+
+#define ARCH_GUNYAH_DEFAULT_MEMTYPE GUNYAH_NORMAL_WB
+
#endif
@@ -273,6 +273,62 @@ enum gunyah_error gunyah_hypercall_msgq_send(u64 capid, size_t size, void *buff,
enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
size_t *recv_size, bool *ready);
+#define GUNYAH_ADDRSPACE_SELF_CAP 0
+
+enum gunyah_pagetable_access {
+ /* clang-format off */
+ GUNYAH_PAGETABLE_ACCESS_NONE = 0,
+ GUNYAH_PAGETABLE_ACCESS_X = 1,
+ GUNYAH_PAGETABLE_ACCESS_W = 2,
+ GUNYAH_PAGETABLE_ACCESS_R = 4,
+ GUNYAH_PAGETABLE_ACCESS_RX = 5,
+ GUNYAH_PAGETABLE_ACCESS_RW = 6,
+ GUNYAH_PAGETABLE_ACCESS_RWX = 7,
+ /* clang-format on */
+};
+
+/* clang-format off */
+#define GUNYAH_MEMEXTENT_MAPPING_USER_ACCESS GENMASK_ULL(2, 0)
+#define GUNYAH_MEMEXTENT_MAPPING_KERNEL_ACCESS GENMASK_ULL(6, 4)
+#define GUNYAH_MEMEXTENT_MAPPING_TYPE GENMASK_ULL(23, 16)
+/* clang-format on */
+
+enum gunyah_memextent_donate_type {
+ /* clang-format off */
+ GUNYAH_MEMEXTENT_DONATE_TO_CHILD = 0,
+ GUNYAH_MEMEXTENT_DONATE_TO_PARENT = 1,
+ GUNYAH_MEMEXTENT_DONATE_TO_SIBLING = 2,
+ GUNYAH_MEMEXTENT_DONATE_TO_PROTECTED = 3,
+ GUNYAH_MEMEXTENT_DONATE_FROM_PROTECTED = 4,
+ /* clang-format on */
+};
+
+enum gunyah_addrspace_map_flag_bits {
+ /* clang-format off */
+ GUNYAH_ADDRSPACE_MAP_FLAG_PARTIAL = 0,
+ GUNYAH_ADDRSPACE_MAP_FLAG_PRIVATE = 1,
+ GUNYAH_ADDRSPACE_MAP_FLAG_VMMIO = 2,
+ GUNYAH_ADDRSPACE_MAP_FLAG_NOSYNC = 31,
+ /* clang-format on */
+};
+
+enum gunyah_error gunyah_hypercall_addrspace_map(u64 capid, u64 extent_capid,
+ u64 vbase, u32 extent_attrs,
+ u32 flags, u64 offset,
+ u64 size);
+enum gunyah_error gunyah_hypercall_addrspace_unmap(u64 capid, u64 extent_capid,
+ u64 vbase, u32 flags,
+ u64 offset, u64 size);
+
+/* clang-format off */
+#define GUNYAH_MEMEXTENT_OPTION_TYPE_MASK GENMASK_ULL(7, 0)
+#define GUNYAH_MEMEXTENT_OPTION_NOSYNC BIT(31)
+/* clang-format on */
+
+enum gunyah_error gunyah_hypercall_memextent_donate(u32 options, u64 from_capid,
+ u64 to_capid, u64 offset,
+ u64 size);
+
struct gunyah_hypercall_vcpu_run_resp {
union {
enum {