Skip to content

Commit

Permalink
kvm: factor out core eventfd assign/deassign logic
Browse files Browse the repository at this point in the history
This patch factors out core eventfd assign/deassign logic and leaves
the argument checking and bus index selection to callers.

Cc: [email protected]
Cc: Gleb Natapov <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Signed-off-by: Jason Wang <[email protected]>
Reviewed-by: Cornelia Huck <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
jasowang authored and bonzini committed Sep 15, 2015
1 parent 8453fec commit 85da11c
Showing 1 changed file with 50 additions and 35 deletions.
85 changes: 50 additions & 35 deletions virt/kvm/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,40 +771,14 @@ static enum kvm_bus ioeventfd_bus_from_flags(__u32 flags)
return KVM_MMIO_BUS;
}

static int
kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
enum kvm_bus bus_idx,
struct kvm_ioeventfd *args)
{
enum kvm_bus bus_idx;
struct _ioeventfd *p;
struct eventfd_ctx *eventfd;
int ret;

bus_idx = ioeventfd_bus_from_flags(args->flags);
/* must be natural-word sized, or 0 to ignore length */
switch (args->len) {
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
return -EINVAL;
}

/* check for range overflow */
if (args->addr + args->len < args->addr)
return -EINVAL;

/* check for extra flags that we don't understand */
if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
return -EINVAL;

/* ioeventfd with no length can't be combined with DATAMATCH */
if (!args->len &&
args->flags & (KVM_IOEVENTFD_FLAG_PIO |
KVM_IOEVENTFD_FLAG_DATAMATCH))
return -EINVAL;
struct eventfd_ctx *eventfd;
struct _ioeventfd *p;
int ret;

eventfd = eventfd_ctx_fdget(args->fd);
if (IS_ERR(eventfd))
Expand Down Expand Up @@ -873,14 +847,13 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
}

static int
kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
struct kvm_ioeventfd *args)
{
enum kvm_bus bus_idx;
struct _ioeventfd *p, *tmp;
struct eventfd_ctx *eventfd;
int ret = -ENOENT;

bus_idx = ioeventfd_bus_from_flags(args->flags);
eventfd = eventfd_ctx_fdget(args->fd);
if (IS_ERR(eventfd))
return PTR_ERR(eventfd);
Expand Down Expand Up @@ -918,6 +891,48 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
return ret;
}

static int kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
enum kvm_bus bus_idx = ioeventfd_bus_from_flags(args->flags);

return kvm_deassign_ioeventfd_idx(kvm, bus_idx, args);
}

static int
kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
enum kvm_bus bus_idx;

bus_idx = ioeventfd_bus_from_flags(args->flags);
/* must be natural-word sized, or 0 to ignore length */
switch (args->len) {
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
return -EINVAL;
}

/* check for range overflow */
if (args->addr + args->len < args->addr)
return -EINVAL;

/* check for extra flags that we don't understand */
if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
return -EINVAL;

/* ioeventfd with no length can't be combined with DATAMATCH */
if (!args->len &&
args->flags & (KVM_IOEVENTFD_FLAG_PIO |
KVM_IOEVENTFD_FLAG_DATAMATCH))
return -EINVAL;

return kvm_assign_ioeventfd_idx(kvm, bus_idx, args);
}

int
kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
Expand Down

0 comments on commit 85da11c

Please sign in to comment.