// SPDX-License-Identifier: GPL-2.0-only
/*
 * VMware VMCI Driver
 *
 * Copyright (C) 2012 VMware, Inc. All rights reserved.
 */

#include <linux/vmw_vmci_defs.h>
#include <linux/hash.h>
#include <linux/types.h>
#include <linux/rculist.h>
#include <linux/completion.h>

#include "vmci_resource.h"
#include "vmci_driver.h"


#define VMCI_RESOURCE_HASH_BITS         7
#define VMCI_RESOURCE_HASH_BUCKETS      (1 << VMCI_RESOURCE_HASH_BITS)

struct vmci_hash_table {
	spinlock_t lock;
	struct hlist_head entries[VMCI_RESOURCE_HASH_BUCKETS];
};

static struct vmci_hash_table vmci_resource_table = {
	.lock = __SPIN_LOCK_UNLOCKED(vmci_resource_table.lock),
};

static unsigned int vmci_resource_hash(struct vmci_handle handle)
{
	return hash_32(handle.resource, VMCI_RESOURCE_HASH_BITS);
}

/*
 * Gets a resource (if one exists) matching given handle from the hash table.
 */
static struct vmci_resource *vmci_resource_lookup(struct vmci_handle handle,
						  enum vmci_resource_type type)
{
	struct vmci_resource *r, *resource = NULL;
	unsigned int idx = vmci_resource_hash(handle);

	rcu_read_lock();
	hlist_for_each_entry_rcu(r,
				 &vmci_resource_table.entries[idx], node) {
		u32 cid = r->handle.context;
		u32 rid = r->handle.resource;

		if (r->type == type &&
		    rid == handle.resource &&
		    (cid == handle.context || cid == VMCI_INVALID_ID ||
		     handle.context == VMCI_INVALID_ID)) {
			resource = r;
			break;
		}
	}
	rcu_read_unlock();

	return resource;
}

/*
 * Find an unused resource ID and return it. The first
 * VMCI_RESERVED_RESOURCE_ID_MAX are reserved so we start from
 * its value + 1.
 * Returns VMCI resource id on success, VMCI_INVALID_ID on failure.
 */
static u32 vmci_resource_find_id(u32 context_id,
				 enum vmci_resource_type resource_type)
{
	static u32 resource_id = VMCI_RESERVED_RESOURCE_ID_MAX + 1;
	u32 old_rid = resource_id;
	u32 current_rid;

	/*
	 * Generate a unique resource ID.  Keep on trying until we wrap around
	 * in the RID space.
	 */
	do {
		struct vmci_handle handle;

		current_rid = resource_id;
		resource_id++;
		if (unlikely(resource_id == VMCI_INVALID_ID)) {
			/* Skip the reserved rids. */
			resource_id = VMCI_RESERVED_RESOURCE_ID_MAX + 1;
		}

		handle = vmci_make_handle(context_id, current_rid);
		if (!vmci_resource_lookup(handle, resource_type))
			return current_rid;
	} while (resource_id != old_rid);

	return VMCI_INVALID_ID;
}


int vmci_resource_add(struct vmci_resource *resource,
		      enum vmci_resource_type resource_type,
		      struct vmci_handle handle)

{
	unsigned int idx;
	int result;

	spin_lock(&vmci_resource_table.lock);

	if (handle.resource == VMCI_INVALID_ID) {
		handle.resource = vmci_resource_find_id(handle.context,
			resource_type);
		if (handle.resource == VMCI_INVALID_ID) {
			result = VMCI_ERROR_NO_HANDLE;
			goto out;
		}
	} else if (vmci_resource_lookup(handle, resource_type)) {
		result = VMCI_ERROR_ALREADY_EXISTS;
		goto out;
	}

	resource->handle = handle;
	resource->type = resource_type;
	INIT_HLIST_NODE(&resource->node);
	kref_init(&resource->kref);
	init_completion(&resource->done);

	idx = vmci_resource_hash(resource->handle);
	hlist_add_head_rcu(&resource->node, &vmci_resource_table.entries[idx]);

	result = VMCI_SUCCESS;

out:
	spin_unlock(&vmci_resource_table.lock);
	return result;
}

void vmci_resource_remove(struct vmci_resource *resource)
{
	struct vmci_handle handle = resource->handle;
	unsigned int idx = vmci_resource_hash(handle);
	struct vmci_resource *r;

	/* Remove resource from hash table. */
	spin_lock(&vmci_resource_table.lock);

	hlist_for_each_entry(r, &vmci_resource_table.entries[idx], node) {
		if (vmci_handle_is_equal(r->handle, resource->handle)) {
			hlist_del_init_rcu(&r->node);
			break;
		}
	}

	spin_unlock(&vmci_resource_table.lock);
	synchronize_rcu();

	vmci_resource_put(resource);
	wait_for_completion(&resource->done);
}

struct vmci_resource *
vmci_resource_by_handle(struct vmci_handle resource_handle,
			enum vmci_resource_type resource_type)
{
	struct vmci_resource *r, *resource = NULL;

	rcu_read_lock();

	r = vmci_resource_lookup(resource_handle, resource_type);
	if (r &&
	    (resource_type == r->type ||
	     resource_type == VMCI_RESOURCE_TYPE_ANY)) {
		resource = vmci_resource_get(r);
	}

	rcu_read_unlock();

	return resource;
}

/*
 * Get a reference to given resource.
 */
struct vmci_resource *vmci_resource_get(struct vmci_resource *resource)
{
	kref_get(&resource->kref);

	return resource;
}

static void vmci_release_resource(struct kref *kref)
{
	struct vmci_resource *resource =
		container_of(kref, struct vmci_resource, kref);

	/* Verify the resource has been unlinked from hash table */
	WARN_ON(!hlist_unhashed(&resource->node));

	/* Signal that container of this resource can now be destroyed */
	complete(&resource->done);
}

/*
 * Resource's release function will get called if last reference.
 * If it is the last reference, then we are sure that nobody else
 * can increment the count again (it's gone from the resource hash
 * table), so there's no need for locking here.
 */
int vmci_resource_put(struct vmci_resource *resource)
{
	/*
	 * We propagate the information back to caller in case it wants to know
	 * whether entry was freed.
	 */
	return kref_put(&resource->kref, vmci_release_resource) ?
		VMCI_SUCCESS_ENTRY_DEAD : VMCI_SUCCESS;
}

struct vmci_handle vmci_resource_handle(struct vmci_resource *resource)
{
	return resource->handle;
}
