diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c
index f2f776edecb8..6e590f2a8cfa 100644
--- a/drivers/virt/gunyah/rsc_mgr.c
+++ b/drivers/virt/gunyah/rsc_mgr.c
@@ -105,6 +105,13 @@ struct gh_rsc_mgr {
 static struct gh_rsc_mgr *__rsc_mgr;
 SRCU_NOTIFIER_HEAD_STATIC(gh_rm_notifier);
 
+/* Needs to be out of the gh_rsc_mgr struct as platform_ops might probe before
+ * rsc mgr probes. We can't defer the platform_ops because it might be that
+ * Linux is not a Gunyah guest.
+ */
+static struct gunyah_rm_platform_ops *rm_platform_ops;
+static DECLARE_RWSEM(rm_platform_ops_lock);
+
 static struct gh_rm_connection *gh_rm_alloc_connection(u32 msg_id, u8 type)
 {
 	struct gh_rm_connection *connection;
@@ -498,6 +505,51 @@ int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size,
 	return ret;
 }
 
+int gh_rm_platform_pre_mem_share(struct gh_rm_mem_parcel *mem_parcel)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->pre_mem_share)
+		ret = rm_platform_ops->pre_mem_share(mem_parcel);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+
+int gh_rm_platform_post_mem_reclaim(struct gh_rm_mem_parcel *mem_parcel)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->post_mem_reclaim)
+		ret = rm_platform_ops->post_mem_reclaim(mem_parcel);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+
+int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops)
+{
+	int ret = 0;
+
+	down_write(&rm_platform_ops_lock);
+	if (!rm_platform_ops)
+		rm_platform_ops = platform_ops;
+	else
+		ret = -EEXIST;
+	up_write(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gh_rm_register_platform_ops);
+
+void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops)
+{
+	down_write(&rm_platform_ops_lock);
+	if (rm_platform_ops == platform_ops)
+		rm_platform_ops = NULL;
+	up_write(&rm_platform_ops_lock);
+}
+EXPORT_SYMBOL_GPL(gh_rm_unregister_platform_ops);
+
 int gh_rm_register_notifier(struct notifier_block *nb)
 {
 	return srcu_notifier_chain_register(&gh_rm_notifier, nb);
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index f6ed58405ef4..49becf82edf7 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -130,6 +130,9 @@ struct gh_vm_set_boot_context_req {
 int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size,
 		void **resp_buf, size_t *resp_buff_size);
 
+int gh_rm_platform_pre_mem_share(struct gh_rm_mem_parcel *mem_parcel);
+int gh_rm_platform_post_mem_reclaim(struct gh_rm_mem_parcel *mem_parcel);
+
 struct gh_rm_device {
 	struct device dev;
 	const char *name;
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
index 17f88c3d5726..c7e3bb975640 100644
--- a/drivers/virt/gunyah/rsc_mgr_rpc.c
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -120,6 +120,10 @@ static int gh_rm_mem_lend_common(u32 message_id, struct gh_rm_mem_parcel *p)
 	if (initial_n_mem_entries > GH_RM_MAX_MEM_ENTRIES)
 		initial_n_mem_entries = GH_RM_MAX_MEM_ENTRIES;
 
+	ret = gh_rm_platform_pre_mem_share(p);
+	if (ret)
+		return ret;
+
 	/* The format of the message goes:
 	 * request header
 	 * ACL entries (which VMs get what kind of access to this memory parcel)
@@ -163,6 +167,7 @@ static int gh_rm_mem_lend_common(u32 message_id, struct gh_rm_mem_parcel *p)
 
 	if (resp_size != sizeof(u32)) {
 		ret = -EIO;
+		gh_rm_platform_post_mem_reclaim(p);
 		goto out;
 	}
 
@@ -234,6 +239,8 @@ int gh_rm_mem_reclaim(struct gh_rm_mem_parcel *parcel)
 	if (resp_size)
 		pr_warn("Received unexpected payload for MEM_RECLAIM: %lu\n", resp_size);
 
+	ret = gh_rm_platform_post_mem_reclaim(parcel);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(gh_rm_mem_reclaim);
diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h
index 78d516032f6a..6e5e67e96688 100644
--- a/include/linux/gunyah_rsc_mgr.h
+++ b/include/linux/gunyah_rsc_mgr.h
@@ -119,7 +119,6 @@ struct gh_rm_hyp_resource {
 } __packed;
 
 ssize_t gh_rm_get_hyp_resources(u16 vmid, struct gh_rm_hyp_resource **resources);
-int gh_rm_get_vmid(u16 *vmid);
 
 #define GH_RM_BOOT_CONTEXT_REG_SET_REGISTERS	0
 #define GH_RM_BOOT_CONTEXT_REG_SET_PC		1
@@ -143,4 +142,15 @@ void gh_rm_driver_unregister(struct gh_rm_driver *ghrm_drv);
 #define module_gh_rm_driver(ghrm_drv) \
 	module_driver(ghrm_drv, gh_rm_driver_register, gh_rm_driver_unregister)
 
+#if IS_ENABLED(CONFIG_GUNYAH)
+int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops);
+void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops);
+int gh_rm_get_vmid(u16 *vmid);
+#else
+static inline int gh_rm_register_platform_ops(struct gunyah_rm_platform_ops *platform_ops)
+	{ return 0; }
+static inline void gh_rm_unregister_platform_ops(struct gunyah_rm_platform_ops *platform_ops) { }
+static inline int gh_rm_get_vmid(u16 *vmid) { return -ENODEV; }
+#endif
+
 #endif
