ANDROID: gunyah: Sync with latest "virt: gunyah: Add resource tickets"

Align resource tickets with the Gunyah v13 pathces posted to kernel.org:

https://lore.kernel.org/all/20230509204801.2824351-19-quic_eberman@quicinc.com/

Bug: 279506910
Change-Id: Ie08544786045b338c332b3a35c125fcb9a77b697
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
This commit is contained in:
Elliot Berman
2023-04-14 16:37:35 -07:00
committed by Carlos Llamas
parent 5e0785329a
commit 084d70e264
4 changed files with 46 additions and 34 deletions

View File

@@ -54,7 +54,7 @@ static void irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, p
add_wait_queue(wqh, &irq_ctx->wait);
}
static int gh_irqfd_populate(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc)
static bool gh_irqfd_populate(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc)
{
struct gh_irqfd *irqfd = container_of(ticket, struct gh_irqfd, ticket);
u64 enable_mask = GH_BELL_NONBLOCK;
@@ -64,7 +64,7 @@ static int gh_irqfd_populate(struct gh_vm_resource_ticket *ticket, struct gh_res
if (irqfd->ghrsc) {
pr_warn("irqfd%d already got a Gunyah resource. Check if multiple resources with same label were configured.\n",
irqfd->ticket.label);
return -1;
return false;
}
irqfd->ghrsc = ghrsc;
@@ -75,7 +75,7 @@ static int gh_irqfd_populate(struct gh_vm_resource_ticket *ticket, struct gh_res
irqfd->ticket.label);
}
return 0;
return true;
}
static void gh_irqfd_unpopulate(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc)

View File

@@ -323,14 +323,16 @@ static const struct file_operations gh_vcpu_fops = {
.mmap = gh_vcpu_mmap,
};
static int gh_vcpu_populate(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc)
static bool gh_vcpu_populate(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc)
{
struct gh_vcpu *vcpu = container_of(ticket, struct gh_vcpu, ticket);
int ret;
mutex_lock(&vcpu->run_lock);
if (vcpu->rsc) {
ret = -1;
pr_warn("vcpu%d already got a Gunyah resource. Check if multiple resources with same label were configured.\n",
vcpu->ticket.label);
ret = -EEXIST;
goto out;
}
@@ -344,7 +346,7 @@ static int gh_vcpu_populate(struct gh_vm_resource_ticket *ticket, struct gh_reso
out:
mutex_unlock(&vcpu->run_lock);
return ret;
return !ret;
}
static void gh_vcpu_unpopulate(struct gh_vm_resource_ticket *ticket,

View File

@@ -190,11 +190,11 @@ EXPORT_SYMBOL_GPL(gh_vm_function_unregister);
int gh_vm_add_resource_ticket(struct gh_vm *ghvm, struct gh_vm_resource_ticket *ticket)
{
struct gh_vm_resource_ticket *iter;
struct gh_resource *ghrsc;
struct gh_resource *ghrsc, *rsc_iter;
int ret = 0;
mutex_lock(&ghvm->resources_lock);
list_for_each_entry(iter, &ghvm->resource_tickets, list) {
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;
@@ -206,10 +206,10 @@ int gh_vm_add_resource_ticket(struct gh_vm *ghvm, struct gh_vm_resource_ticket *
goto out;
}
list_add(&ticket->list, &ghvm->resource_tickets);
list_add(&ticket->vm_list, &ghvm->resource_tickets);
INIT_LIST_HEAD(&ticket->resources);
list_for_each_entry(ghrsc, &ghvm->resources, list) {
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);
@@ -232,7 +232,7 @@ void gh_vm_remove_resource_ticket(struct gh_vm *ghvm, struct gh_vm_resource_tick
}
module_put(ticket->owner);
list_del(&ticket->list);
list_del(&ticket->vm_list);
mutex_unlock(&ghvm->resources_lock);
}
EXPORT_SYMBOL_GPL(gh_vm_remove_resource_ticket);
@@ -242,12 +242,17 @@ static void gh_vm_add_resource(struct gh_vm *ghvm, struct gh_resource *ghrsc)
struct gh_vm_resource_ticket *ticket;
mutex_lock(&ghvm->resources_lock);
list_for_each_entry(ticket, &ghvm->resource_tickets, list) {
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)) {
if (ticket->populate(ticket, ghrsc))
list_add(&ghrsc->list, &ticket->resources);
goto found;
}
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);
@@ -255,6 +260,26 @@ found:
mutex_unlock(&ghvm->resources_lock);
}
static void gh_vm_clean_resources(struct gh_vm *ghvm)
{
struct gh_vm_resource_ticket *ticket, *titer;
struct gh_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);
gh_vm_remove_resource_ticket(ghvm, ticket);
}
}
list_for_each_entry_safe(ghrsc, riter, &ghvm->resources, list) {
gh_rm_free_resource(ghrsc);
}
mutex_unlock(&ghvm->resources_lock);
}
static int _gh_vm_io_handler_compare(const struct rb_node *node, const struct rb_node *parent)
{
struct gh_vm_io_handler *n = container_of(node, struct gh_vm_io_handler, node);
@@ -417,8 +442,6 @@ static void gh_vm_stop(struct gh_vm *ghvm)
static void gh_vm_free(struct work_struct *work)
{
struct gh_vm *ghvm = container_of(work, struct gh_vm, free_work);
struct gh_vm_resource_ticket *ticket, *titer;
struct gh_resource *ghrsc, *riter;
struct gh_vm_mem *mapping, *tmp;
int ret;
@@ -429,20 +452,7 @@ static void gh_vm_free(struct work_struct *work)
case GH_RM_VM_STATUS_INIT_FAILED:
case GH_RM_VM_STATUS_EXITED:
gh_vm_remove_functions(ghvm);
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, list) {
dev_warn(ghvm->parent, " %pS\n", ticket->populate);
gh_vm_remove_resource_ticket(ghvm, ticket);
}
}
list_for_each_entry_safe(ghrsc, riter, &ghvm->resources, list) {
gh_rm_free_resource(ghrsc);
}
mutex_unlock(&ghvm->resources_lock);
gh_vm_clean_resources(ghvm);
/* vm_status == LOAD if user creates VM, but then destroys it
* without ever trying to start it. In that case, we have only

View File

@@ -85,13 +85,13 @@ void gh_vm_function_unregister(struct gh_vm_function *f);
MODULE_ALIAS_GH_VM_FUNCTION(_type, _idx)
struct gh_vm_resource_ticket {
struct list_head list; /* for gh_vm's resources list */
struct list_head resources; /* for gh_resources's list */
struct list_head vm_list; /* for gh_vm's resource tickets list */
struct list_head resources; /* resources associated with this ticket */
enum gh_resource_type resource_type;
u32 label;
struct module *owner;
int (*populate)(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc);
bool (*populate)(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc);
void (*unpopulate)(struct gh_vm_resource_ticket *ticket, struct gh_resource *ghrsc);
};