mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
committed by
Carlos Llamas
parent
5e0785329a
commit
084d70e264
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user