All of lore.kernel.org
 help / color / mirror / Atom feed
From: Elliot Berman <quic_eberman@quicinc.com>
To: Alex Elder <elder@linaro.org>,
	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	Murali Nalajal <quic_mnalajal@quicinc.com>,
	Trilok Soni <quic_tsoni@quicinc.com>,
	Srivatsa Vaddagiri <quic_svaddagi@quicinc.com>,
	Carl van Schaik <quic_cvanscha@quicinc.com>,
	Philip Derrin <quic_pderrin@quicinc.com>,
	Prakruthi Deepak Heragu <quic_pheragu@quicinc.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Konrad Dybcio <konrad.dybcio@linaro.org>,
	Bjorn Andersson <andersson@kernel.org>,
	Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
	"Fuad Tabba" <tabba@google.com>,
	Sean Christopherson <seanjc@google.com>,
	"Andrew Morton" <akpm@linux-foundation.org>
Cc: <linux-arm-msm@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>, <linux-mm@kvack.org>,
	Elliot Berman <quic_eberman@quicinc.com>
Subject: [PATCH v17 12/35] virt: gunyah: Add resource tickets
Date: Thu, 22 Feb 2024 15:16:35 -0800	[thread overview]
Message-ID: <20240222-gunyah-v17-12-1e9da6763d38@quicinc.com> (raw)
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>

Some VM functions need to acquire Gunyah resources. For instance, Gunyah
vCPUs are exposed to the host as a resource. The Gunyah vCPU function
will register a resource ticket and be able to interact with the
hypervisor once the resource ticket is filled.

Resource tickets are the mechanism for functions to acquire ownership of
Gunyah resources. Gunyah functions can be created before the VM's
resources are created and made available to Linux. A resource ticket
identifies a type of resource and a label of a resource which the ticket
holder is interested in.

Resources are created by Gunyah as configured in the VM's devicetree
configuration. Gunyah doesn't process the label and that makes it
possible for userspace to create multiple resources with the same label.
Resource ticket owners need to be prepared for populate to be called
multiple times if userspace created multiple resources with the same
label.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 135 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/virt/gunyah/vm_mgr.h |   7 +++
 include/linux/gunyah.h       |  40 +++++++++++++
 3 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 364a53cad643e..2cde4d501204a 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -15,6 +15,113 @@
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_vm_resource_ticket *iter;
+	struct gunyah_resource *ghrsc, *rsc_iter;
+	int ret = 0;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(iter, &ghvm->resource_tickets, vm_list) {
+		if (iter->resource_type == ticket->resource_type &&
+		    iter->label == ticket->label) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+
+	if (!try_module_get(ticket->owner)) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	list_add(&ticket->vm_list, &ghvm->resource_tickets);
+	INIT_LIST_HEAD(&ticket->resources);
+
+	list_for_each_entry_safe(ghrsc, rsc_iter, &ghvm->resources, list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_move(&ghrsc->list, &ticket->resources);
+		}
+	}
+out:
+	mutex_unlock(&ghvm->resources_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_add_resource_ticket);
+
+static void
+__gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				   struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_resource *ghrsc, *iter;
+
+	list_for_each_entry_safe(ghrsc, iter, &ticket->resources, list) {
+		ticket->unpopulate(ticket, ghrsc);
+		list_move(&ghrsc->list, &ghvm->resources);
+	}
+
+	module_put(ticket->owner);
+	list_del(&ticket->vm_list);
+}
+
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket)
+{
+	mutex_lock(&ghvm->resources_lock);
+	__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+	mutex_unlock(&ghvm->resources_lock);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_remove_resource_ticket);
+
+static void gunyah_vm_add_resource(struct gunyah_vm *ghvm,
+				   struct gunyah_resource *ghrsc)
+{
+	struct gunyah_vm_resource_ticket *ticket;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(ticket, &ghvm->resource_tickets, vm_list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_add(&ghrsc->list, &ticket->resources);
+			else
+				list_add(&ghrsc->list, &ghvm->resources);
+			/* unconditonal -- we prevent multiple identical
+			 * resource tickets so there will not be some other
+			 * ticket elsewhere in the list if populate() failed.
+			 */
+			goto found;
+		}
+	}
+	list_add(&ghrsc->list, &ghvm->resources);
+found:
+	mutex_unlock(&ghvm->resources_lock);
+}
+
+static void gunyah_vm_clean_resources(struct gunyah_vm *ghvm)
+{
+	struct gunyah_vm_resource_ticket *ticket, *titer;
+	struct gunyah_resource *ghrsc, *riter;
+
+	mutex_lock(&ghvm->resources_lock);
+	if (!list_empty(&ghvm->resource_tickets)) {
+		dev_warn(ghvm->parent, "Dangling resource tickets:\n");
+		list_for_each_entry_safe(ticket, titer, &ghvm->resource_tickets,
+					 vm_list) {
+			dev_warn(ghvm->parent, "  %pS\n", ticket->populate);
+			__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+		}
+	}
+
+	list_for_each_entry_safe(ghrsc, riter, &ghvm->resources, list) {
+		gunyah_rm_free_resource(ghrsc);
+	}
+	mutex_unlock(&ghvm->resources_lock);
+}
+
 static int gunyah_vm_rm_notification_status(struct gunyah_vm *ghvm, void *data)
 {
 	struct gunyah_rm_vm_status_payload *payload = data;
@@ -92,13 +199,18 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	init_rwsem(&ghvm->status_lock);
 	init_waitqueue_head(&ghvm->vm_status_wait);
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_NO_STATE;
+	mutex_init(&ghvm->resources_lock);
+	INIT_LIST_HEAD(&ghvm->resources);
+	INIT_LIST_HEAD(&ghvm->resource_tickets);
 
 	return ghvm;
 }
 
 static int gunyah_vm_start(struct gunyah_vm *ghvm)
 {
-	int ret;
+	struct gunyah_rm_hyp_resources *resources;
+	struct gunyah_resource *ghrsc;
+	int ret, i, n;
 
 	down_write(&ghvm->status_lock);
 	if (ghvm->vm_status != GUNYAH_RM_VM_STATUS_NO_STATE) {
@@ -134,6 +246,25 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 	}
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_READY;
 
+	ret = gunyah_rm_get_hyp_resources(ghvm->rm, ghvm->vmid, &resources);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to get hypervisor resources for VM: %d\n",
+			 ret);
+		goto err;
+	}
+
+	for (i = 0, n = le32_to_cpu(resources->n_entries); i < n; i++) {
+		ghrsc = gunyah_rm_alloc_resource(ghvm->rm,
+						 &resources->entries[i]);
+		if (!ghrsc) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		gunyah_vm_add_resource(ghvm, ghrsc);
+	}
+
 	ret = gunyah_rm_vm_start(ghvm->rm, ghvm->vmid);
 	if (ret) {
 		dev_warn(ghvm->parent, "Failed to start VM: %d\n", ret);
@@ -207,6 +338,8 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
 		gunyah_vm_stop(ghvm);
 
+	gunyah_vm_clean_resources(ghvm);
+
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_READY ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_INIT_FAILED) {
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index e6cc9aead0b67..0d291f7228859 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -26,6 +26,9 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @vm_status: Current state of the VM, as last reported by RM
  * @vm_status_wait: Wait queue for status @vm_status changes
  * @status_lock: Serializing state transitions
+ * @resource_lock: Serializing addition of resources and resource tickets
+ * @resources: List of &struct gunyah_resource that are associated with this VM
+ * @resource_tickets: List of &struct gunyah_vm_resource_ticket
  * @auth: Authentication mechanism to be used by resource manager when
  *        launching the VM
  *
@@ -39,9 +42,13 @@ struct gunyah_vm {
 	enum gunyah_rm_vm_status vm_status;
 	wait_queue_head_t vm_status_wait;
 	struct rw_semaphore status_lock;
+	struct mutex resources_lock;
+	struct list_head resources;
+	struct list_head resource_tickets;
 
 	struct device *parent;
 	enum gunyah_rm_vm_auth_mechanism auth;
+
 };
 
 #endif
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 45033bdb5e151..0017691002607 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/limits.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
@@ -30,9 +31,48 @@ struct gunyah_resource {
 	u64 capid;
 	unsigned int irq;
 
+	struct list_head list;
 	u32 rm_label;
 };
 
+struct gunyah_vm;
+
+/**
+ * struct gunyah_vm_resource_ticket - Represents a ticket to reserve access to VM resource(s)
+ * @vm_list: for @gunyah_vm->resource_tickets
+ * @resources: List of resource(s) associated with this ticket
+ *             (members are from @gunyah_resource->list)
+ * @resource_type: Type of resource this ticket reserves
+ * @label: Label of the resource from resource manager this ticket reserves.
+ * @owner: owner of the ticket
+ * @populate: callback provided by the ticket owner and called when a resource is found that
+ *            matches @resource_type and @label. Note that this callback could be called
+ *            multiple times if userspace created mutliple resources with the same type/label.
+ *            This callback may also have significant delay after gunyah_vm_add_resource_ticket()
+ *            since gunyah_vm_add_resource_ticket() could be called before the VM starts.
+ * @unpopulate: callback provided by the ticket owner and called when the ticket owner should no
+ *              longer use the resource provided in the argument. When unpopulate() returns,
+ *              the ticket owner should not be able to use the resource any more as the resource
+ *              might being freed.
+ */
+struct gunyah_vm_resource_ticket {
+	struct list_head vm_list;
+	struct list_head resources;
+	enum gunyah_resource_type resource_type;
+	u32 label;
+
+	struct module *owner;
+	bool (*populate)(struct gunyah_vm_resource_ticket *ticket,
+			 struct gunyah_resource *ghrsc);
+	void (*unpopulate)(struct gunyah_vm_resource_ticket *ticket,
+			   struct gunyah_resource *ghrsc);
+};
+
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket);
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket);
+
 /******************************************************************************/
 /* Common arch-independent definitions for Gunyah hypercalls                  */
 #define GUNYAH_CAPID_INVAL U64_MAX

-- 
2.34.1


WARNING: multiple messages have this Message-ID (diff)
From: Elliot Berman <quic_eberman@quicinc.com>
To: Alex Elder <elder@linaro.org>,
	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	Murali Nalajal <quic_mnalajal@quicinc.com>,
	Trilok Soni <quic_tsoni@quicinc.com>,
	Srivatsa Vaddagiri <quic_svaddagi@quicinc.com>,
	Carl van Schaik <quic_cvanscha@quicinc.com>,
	Philip Derrin <quic_pderrin@quicinc.com>,
	Prakruthi Deepak Heragu <quic_pheragu@quicinc.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Konrad Dybcio <konrad.dybcio@linaro.org>,
	Bjorn Andersson <andersson@kernel.org>,
	Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
	"Fuad Tabba" <tabba@google.com>,
	Sean Christopherson <seanjc@google.com>,
	"Andrew Morton" <akpm@linux-foundation.org>
Cc: <linux-arm-msm@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>, <linux-mm@kvack.org>,
	Elliot Berman <quic_eberman@quicinc.com>
Subject: [PATCH v17 12/35] virt: gunyah: Add resource tickets
Date: Thu, 22 Feb 2024 15:16:35 -0800	[thread overview]
Message-ID: <20240222-gunyah-v17-12-1e9da6763d38@quicinc.com> (raw)
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>

Some VM functions need to acquire Gunyah resources. For instance, Gunyah
vCPUs are exposed to the host as a resource. The Gunyah vCPU function
will register a resource ticket and be able to interact with the
hypervisor once the resource ticket is filled.

Resource tickets are the mechanism for functions to acquire ownership of
Gunyah resources. Gunyah functions can be created before the VM's
resources are created and made available to Linux. A resource ticket
identifies a type of resource and a label of a resource which the ticket
holder is interested in.

Resources are created by Gunyah as configured in the VM's devicetree
configuration. Gunyah doesn't process the label and that makes it
possible for userspace to create multiple resources with the same label.
Resource ticket owners need to be prepared for populate to be called
multiple times if userspace created multiple resources with the same
label.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 135 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/virt/gunyah/vm_mgr.h |   7 +++
 include/linux/gunyah.h       |  40 +++++++++++++
 3 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 364a53cad643e..2cde4d501204a 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -15,6 +15,113 @@
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_vm_resource_ticket *iter;
+	struct gunyah_resource *ghrsc, *rsc_iter;
+	int ret = 0;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(iter, &ghvm->resource_tickets, vm_list) {
+		if (iter->resource_type == ticket->resource_type &&
+		    iter->label == ticket->label) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+
+	if (!try_module_get(ticket->owner)) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	list_add(&ticket->vm_list, &ghvm->resource_tickets);
+	INIT_LIST_HEAD(&ticket->resources);
+
+	list_for_each_entry_safe(ghrsc, rsc_iter, &ghvm->resources, list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_move(&ghrsc->list, &ticket->resources);
+		}
+	}
+out:
+	mutex_unlock(&ghvm->resources_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_add_resource_ticket);
+
+static void
+__gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				   struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_resource *ghrsc, *iter;
+
+	list_for_each_entry_safe(ghrsc, iter, &ticket->resources, list) {
+		ticket->unpopulate(ticket, ghrsc);
+		list_move(&ghrsc->list, &ghvm->resources);
+	}
+
+	module_put(ticket->owner);
+	list_del(&ticket->vm_list);
+}
+
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket)
+{
+	mutex_lock(&ghvm->resources_lock);
+	__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+	mutex_unlock(&ghvm->resources_lock);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_remove_resource_ticket);
+
+static void gunyah_vm_add_resource(struct gunyah_vm *ghvm,
+				   struct gunyah_resource *ghrsc)
+{
+	struct gunyah_vm_resource_ticket *ticket;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(ticket, &ghvm->resource_tickets, vm_list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_add(&ghrsc->list, &ticket->resources);
+			else
+				list_add(&ghrsc->list, &ghvm->resources);
+			/* unconditonal -- we prevent multiple identical
+			 * resource tickets so there will not be some other
+			 * ticket elsewhere in the list if populate() failed.
+			 */
+			goto found;
+		}
+	}
+	list_add(&ghrsc->list, &ghvm->resources);
+found:
+	mutex_unlock(&ghvm->resources_lock);
+}
+
+static void gunyah_vm_clean_resources(struct gunyah_vm *ghvm)
+{
+	struct gunyah_vm_resource_ticket *ticket, *titer;
+	struct gunyah_resource *ghrsc, *riter;
+
+	mutex_lock(&ghvm->resources_lock);
+	if (!list_empty(&ghvm->resource_tickets)) {
+		dev_warn(ghvm->parent, "Dangling resource tickets:\n");
+		list_for_each_entry_safe(ticket, titer, &ghvm->resource_tickets,
+					 vm_list) {
+			dev_warn(ghvm->parent, "  %pS\n", ticket->populate);
+			__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+		}
+	}
+
+	list_for_each_entry_safe(ghrsc, riter, &ghvm->resources, list) {
+		gunyah_rm_free_resource(ghrsc);
+	}
+	mutex_unlock(&ghvm->resources_lock);
+}
+
 static int gunyah_vm_rm_notification_status(struct gunyah_vm *ghvm, void *data)
 {
 	struct gunyah_rm_vm_status_payload *payload = data;
@@ -92,13 +199,18 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	init_rwsem(&ghvm->status_lock);
 	init_waitqueue_head(&ghvm->vm_status_wait);
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_NO_STATE;
+	mutex_init(&ghvm->resources_lock);
+	INIT_LIST_HEAD(&ghvm->resources);
+	INIT_LIST_HEAD(&ghvm->resource_tickets);
 
 	return ghvm;
 }
 
 static int gunyah_vm_start(struct gunyah_vm *ghvm)
 {
-	int ret;
+	struct gunyah_rm_hyp_resources *resources;
+	struct gunyah_resource *ghrsc;
+	int ret, i, n;
 
 	down_write(&ghvm->status_lock);
 	if (ghvm->vm_status != GUNYAH_RM_VM_STATUS_NO_STATE) {
@@ -134,6 +246,25 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 	}
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_READY;
 
+	ret = gunyah_rm_get_hyp_resources(ghvm->rm, ghvm->vmid, &resources);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to get hypervisor resources for VM: %d\n",
+			 ret);
+		goto err;
+	}
+
+	for (i = 0, n = le32_to_cpu(resources->n_entries); i < n; i++) {
+		ghrsc = gunyah_rm_alloc_resource(ghvm->rm,
+						 &resources->entries[i]);
+		if (!ghrsc) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		gunyah_vm_add_resource(ghvm, ghrsc);
+	}
+
 	ret = gunyah_rm_vm_start(ghvm->rm, ghvm->vmid);
 	if (ret) {
 		dev_warn(ghvm->parent, "Failed to start VM: %d\n", ret);
@@ -207,6 +338,8 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
 		gunyah_vm_stop(ghvm);
 
+	gunyah_vm_clean_resources(ghvm);
+
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_READY ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_INIT_FAILED) {
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index e6cc9aead0b67..0d291f7228859 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -26,6 +26,9 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @vm_status: Current state of the VM, as last reported by RM
  * @vm_status_wait: Wait queue for status @vm_status changes
  * @status_lock: Serializing state transitions
+ * @resource_lock: Serializing addition of resources and resource tickets
+ * @resources: List of &struct gunyah_resource that are associated with this VM
+ * @resource_tickets: List of &struct gunyah_vm_resource_ticket
  * @auth: Authentication mechanism to be used by resource manager when
  *        launching the VM
  *
@@ -39,9 +42,13 @@ struct gunyah_vm {
 	enum gunyah_rm_vm_status vm_status;
 	wait_queue_head_t vm_status_wait;
 	struct rw_semaphore status_lock;
+	struct mutex resources_lock;
+	struct list_head resources;
+	struct list_head resource_tickets;
 
 	struct device *parent;
 	enum gunyah_rm_vm_auth_mechanism auth;
+
 };
 
 #endif
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 45033bdb5e151..0017691002607 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/limits.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
@@ -30,9 +31,48 @@ struct gunyah_resource {
 	u64 capid;
 	unsigned int irq;
 
+	struct list_head list;
 	u32 rm_label;
 };
 
+struct gunyah_vm;
+
+/**
+ * struct gunyah_vm_resource_ticket - Represents a ticket to reserve access to VM resource(s)
+ * @vm_list: for @gunyah_vm->resource_tickets
+ * @resources: List of resource(s) associated with this ticket
+ *             (members are from @gunyah_resource->list)
+ * @resource_type: Type of resource this ticket reserves
+ * @label: Label of the resource from resource manager this ticket reserves.
+ * @owner: owner of the ticket
+ * @populate: callback provided by the ticket owner and called when a resource is found that
+ *            matches @resource_type and @label. Note that this callback could be called
+ *            multiple times if userspace created mutliple resources with the same type/label.
+ *            This callback may also have significant delay after gunyah_vm_add_resource_ticket()
+ *            since gunyah_vm_add_resource_ticket() could be called before the VM starts.
+ * @unpopulate: callback provided by the ticket owner and called when the ticket owner should no
+ *              longer use the resource provided in the argument. When unpopulate() returns,
+ *              the ticket owner should not be able to use the resource any more as the resource
+ *              might being freed.
+ */
+struct gunyah_vm_resource_ticket {
+	struct list_head vm_list;
+	struct list_head resources;
+	enum gunyah_resource_type resource_type;
+	u32 label;
+
+	struct module *owner;
+	bool (*populate)(struct gunyah_vm_resource_ticket *ticket,
+			 struct gunyah_resource *ghrsc);
+	void (*unpopulate)(struct gunyah_vm_resource_ticket *ticket,
+			   struct gunyah_resource *ghrsc);
+};
+
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket);
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket);
+
 /******************************************************************************/
 /* Common arch-independent definitions for Gunyah hypercalls                  */
 #define GUNYAH_CAPID_INVAL U64_MAX

-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2024-02-22 23:17 UTC|newest]

Thread overview: 150+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-22 23:16 [PATCH v17 00/35] Drivers for Gunyah hypervisor Elliot Berman
2024-02-22 23:16 ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 01/35] docs: gunyah: Introduce Gunyah Hypervisor Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-05 10:53   ` Pavan Kondeti
2024-03-05 10:53     ` Pavan Kondeti
2024-03-07 15:37   ` Srivatsa Vaddagiri
2024-03-07 15:37     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 02/35] dt-bindings: Add binding for gunyah hypervisor Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 03/35] gunyah: Common types and error codes for Gunyah hypercalls Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 04/35] virt: gunyah: Add hypercalls to identify Gunyah Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 05/35] virt: gunyah: Add hypervisor driver Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-23 21:10   ` Konrad Dybcio
2024-02-23 21:10     ` Konrad Dybcio
2024-02-23 22:58     ` Elliot Berman
2024-02-23 22:58       ` Elliot Berman
2024-02-23 23:46       ` Konrad Dybcio
2024-02-23 23:46         ` Konrad Dybcio
2024-03-07 15:38   ` Srivatsa Vaddagiri
2024-03-07 15:38     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 06/35] virt: gunyah: msgq: Add hypercalls to send and receive messages Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 07/35] gunyah: rsc_mgr: Add resource manager RPC core Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-07 15:38   ` Srivatsa Vaddagiri
2024-03-07 15:38     ` Srivatsa Vaddagiri
2024-03-07 16:41     ` Elliot Berman
2024-03-07 16:41       ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 08/35] gunyah: vm_mgr: Introduce basic VM Manager Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-07 15:39   ` Srivatsa Vaddagiri
2024-03-07 15:39     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 09/35] gunyah: rsc_mgr: Add VM lifecycle RPC Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-07 15:39   ` Srivatsa Vaddagiri
2024-03-07 15:39     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 10/35] gunyah: vm_mgr: Add VM start/stop Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-11  5:38   ` Srivatsa Vaddagiri
2024-03-11  5:38     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 11/35] virt: gunyah: Translate gh_rm_hyp_resource into gunyah_resource Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-11  5:39   ` Srivatsa Vaddagiri
2024-03-11  5:39     ` Srivatsa Vaddagiri
2024-03-11 17:19     ` Elliot Berman
2024-03-11 17:19       ` Elliot Berman
2024-04-05  3:10   ` Pavan Kondeti
2024-04-05  3:10     ` Pavan Kondeti
2024-04-05 15:18     ` Elliot Berman
2024-04-05 15:18       ` Elliot Berman
2024-02-22 23:16 ` Elliot Berman [this message]
2024-02-22 23:16   ` [PATCH v17 12/35] virt: gunyah: Add resource tickets Elliot Berman
2024-03-11  5:38   ` Srivatsa Vaddagiri
2024-03-11  5:38     ` Srivatsa Vaddagiri
2024-03-11 17:13     ` Elliot Berman
2024-03-11 17:13       ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 13/35] gunyah: vm_mgr: Add framework for VM Functions Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-13  9:20   ` Srivatsa Vaddagiri
2024-03-13  9:20     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 14/35] virt: gunyah: Add hypercalls for running a vCPU Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-13  9:21   ` Srivatsa Vaddagiri
2024-03-13  9:21     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 15/35] virt: gunyah: Add proxy-scheduled vCPUs Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-13  9:21   ` Srivatsa Vaddagiri
2024-03-13  9:21     ` Srivatsa Vaddagiri
2024-04-24  9:39   ` Srivatsa Vaddagiri
2024-04-24  9:39     ` Srivatsa Vaddagiri
2024-04-24 17:01     ` Elliot Berman
2024-04-24 17:01       ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 16/35] gunyah: Add hypercalls for demand paging Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-13 15:35   ` Srivatsa Vaddagiri
2024-03-13 15:35     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 17/35] gunyah: rsc_mgr: Add memory parcel RPC Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-14 14:02   ` Srivatsa Vaddagiri
2024-03-14 14:02     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 18/35] mm/interval_tree: Export iter_first/iter_next Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 19/35] arch/mm: Export direct {un,}map functions Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-23  7:09   ` Christoph Hellwig
2024-02-23  7:09     ` Christoph Hellwig
2024-02-24  0:37     ` Elliot Berman
2024-02-24  0:37       ` Elliot Berman
2024-02-26 11:06       ` Christoph Hellwig
2024-02-26 11:06         ` Christoph Hellwig
2024-02-26 11:53         ` David Hildenbrand
2024-02-26 11:53           ` David Hildenbrand
2024-02-26 17:27           ` Elliot Berman
2024-02-26 17:27             ` Elliot Berman
2024-02-27  9:49             ` David Hildenbrand
2024-02-27  9:49               ` David Hildenbrand
2024-03-01  1:35               ` Elliot Berman
2024-03-01  1:35                 ` Elliot Berman
2024-03-04 13:10       ` Quentin Perret
2024-03-04 13:10         ` Quentin Perret
2024-03-04 23:37         ` Elliot Berman
2024-03-04 23:37           ` Elliot Berman
2024-03-05 15:30           ` Quentin Perret
2024-03-05 15:30             ` Quentin Perret
2024-03-05 20:26             ` Elliot Berman
2024-03-05 20:26               ` Elliot Berman
2024-03-06 12:05               ` Quentin Perret
2024-03-06 12:05                 ` Quentin Perret
2024-03-08 19:55                 ` Elliot Berman
2024-03-08 19:55                   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 20/35] virt: gunyah: Add interfaces to map memory into guest address space Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 21/35] gunyah: rsc_mgr: Add platform ops on mem_lend/mem_reclaim Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 22/35] virt: gunyah: Add Qualcomm Gunyah platform ops Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 23/35] virt: gunyah: Implement guestmemfd Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 24/35] virt: gunyah: Add ioctl to bind guestmem to VMs Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 25/35] virt: gunyah: guestmem: Initialize RM mem parcels from guestmem Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 26/35] virt: gunyah: Share guest VM dtb configuration to Gunyah Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 27/35] gunyah: rsc_mgr: Add RPC to enable demand paging Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 28/35] virt: gunyah: Enable " Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 29/35] gunyah: rsc_mgr: Add RPC to set VM boot context Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-14 14:02   ` Srivatsa Vaddagiri
2024-03-14 14:02     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 30/35] virt: gunyah: Allow userspace to initialize context of primary vCPU Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-03-14 14:03   ` Srivatsa Vaddagiri
2024-03-14 14:03     ` Srivatsa Vaddagiri
2024-02-22 23:16 ` [PATCH v17 31/35] virt: gunyah: Add hypercalls for sending doorbell Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 32/35] virt: gunyah: Add irqfd interface Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 33/35] virt: gunyah: Add IO handlers Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 34/35] virt: gunyah: Add ioeventfd Elliot Berman
2024-02-22 23:16   ` Elliot Berman
2024-02-22 23:16 ` [PATCH v17 35/35] MAINTAINERS: Add Gunyah hypervisor drivers section Elliot Berman
2024-02-22 23:16   ` Elliot Berman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240222-gunyah-v17-12-1e9da6763d38@quicinc.com \
    --to=quic_eberman@quicinc.com \
    --cc=akpm@linux-foundation.org \
    --cc=andersson@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=elder@linaro.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=quic_cvanscha@quicinc.com \
    --cc=quic_mnalajal@quicinc.com \
    --cc=quic_pderrin@quicinc.com \
    --cc=quic_pheragu@quicinc.com \
    --cc=quic_svaddagi@quicinc.com \
    --cc=quic_tsoni@quicinc.com \
    --cc=robh+dt@kernel.org \
    --cc=seanjc@google.com \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tabba@google.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.