mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
ANDROID: gunyah: Sync with latest "virt: gunyah: Add ioeventfd"
Align ioeventfd handling to Gunyah v13 patches: https://lore.kernel.org/all/20230509204801.2824351-24-quic_eberman@quicinc.com/ Bug: 279506910 Change-Id: I8d66d83bee284eacb4bc9d76d3cbfd52785d9661 Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
This commit is contained in:
committed by
Carlos Llamas
parent
1b9d0e44a7
commit
2220f8190a
@@ -35,13 +35,17 @@ static struct gh_vm_io_handler_ops io_ops = {
|
||||
static long gh_ioeventfd_bind(struct gh_vm_function_instance *f)
|
||||
{
|
||||
const struct gh_fn_ioeventfd_arg *args = f->argp;
|
||||
struct eventfd_ctx *ctx = NULL;
|
||||
struct gh_ioeventfd *iofd;
|
||||
struct eventfd_ctx *ctx;
|
||||
int ret;
|
||||
|
||||
if (f->arg_size != sizeof(*args))
|
||||
return -EINVAL;
|
||||
|
||||
/* All other flag bits are reserved for future use */
|
||||
if (args->flags & ~GH_IOEVENTFD_FLAGS_DATAMATCH)
|
||||
return -EINVAL;
|
||||
|
||||
/* must be natural-word sized, or 0 to ignore length */
|
||||
switch (args->len) {
|
||||
case 0:
|
||||
@@ -55,15 +59,11 @@ static long gh_ioeventfd_bind(struct gh_vm_function_instance *f)
|
||||
}
|
||||
|
||||
/* check for range overflow */
|
||||
if (args->addr + args->len < args->addr)
|
||||
if (overflows_type(args->addr + args->len, u64))
|
||||
return -EINVAL;
|
||||
|
||||
/* ioeventfd with no length can't be combined with DATAMATCH */
|
||||
if (!args->len && (args->flags & GH_IOEVENTFD_DATAMATCH))
|
||||
return -EINVAL;
|
||||
|
||||
/* All other flag bits are reserved for future use */
|
||||
if (args->flags & ~GH_IOEVENTFD_DATAMATCH)
|
||||
if (!args->len && (args->flags & GH_IOEVENTFD_FLAGS_DATAMATCH))
|
||||
return -EINVAL;
|
||||
|
||||
ctx = eventfd_ctx_fdget(args->fd);
|
||||
@@ -81,7 +81,7 @@ static long gh_ioeventfd_bind(struct gh_vm_function_instance *f)
|
||||
|
||||
iofd->ctx = ctx;
|
||||
|
||||
if (args->flags & GH_IOEVENTFD_DATAMATCH) {
|
||||
if (args->flags & GH_IOEVENTFD_FLAGS_DATAMATCH) {
|
||||
iofd->io_handler.datamatch = true;
|
||||
iofd->io_handler.len = args->len;
|
||||
iofd->io_handler.data = args->datamatch;
|
||||
@@ -126,5 +126,5 @@ static bool gh_ioevent_compare(const struct gh_vm_function_instance *f,
|
||||
DECLARE_GH_VM_FUNCTION_INIT(ioeventfd, GH_FN_IOEVENTFD, 3,
|
||||
gh_ioeventfd_bind, gh_ioevent_unbind,
|
||||
gh_ioevent_compare);
|
||||
MODULE_DESCRIPTION("Gunyah ioeventfds");
|
||||
MODULE_DESCRIPTION("Gunyah ioeventfd VM Function");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -294,9 +294,16 @@ static int _gh_vm_io_handler_compare(const struct rb_node *node, const struct rb
|
||||
return -1;
|
||||
if (n->len > p->len)
|
||||
return 1;
|
||||
if (n->datamatch < p->datamatch)
|
||||
/* one of the io handlers doesn't have datamatch and the other does.
|
||||
* For purposes of comparison, that makes them identical since the
|
||||
* one that doesn't have datamatch will cover the same handler that
|
||||
* does.
|
||||
*/
|
||||
if (n->datamatch != p->datamatch)
|
||||
return 0;
|
||||
if (n->data < p->data)
|
||||
return -1;
|
||||
if (n->datamatch > p->datamatch)
|
||||
if (n->data > p->data)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -319,7 +326,8 @@ static struct gh_vm_io_handler *gh_vm_mgr_find_io_hdlr(struct gh_vm *ghvm, u64 a
|
||||
struct gh_vm_io_handler key = {
|
||||
.addr = addr,
|
||||
.len = len,
|
||||
.datamatch = data,
|
||||
.datamatch = true,
|
||||
.data = data,
|
||||
};
|
||||
struct rb_node *node;
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ struct gh_fn_irqfd_arg {
|
||||
__u32 padding;
|
||||
};
|
||||
|
||||
#define GH_IOEVENTFD_DATAMATCH (1UL << 0)
|
||||
#define GH_IOEVENTFD_FLAGS_DATAMATCH (1UL << 0)
|
||||
|
||||
/**
|
||||
* struct gh_fn_ioeventfd_arg - Arguments to create an ioeventfd function
|
||||
|
||||
Reference in New Issue
Block a user