lkml.org 
[lkml]   [2009]   [Jun]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [KVM PATCH v8 3/3] KVM: add iosignalfd support
    On Mon, Jun 22, 2009 at 08:56:28AM -0400, Gregory Haskins wrote:
    > Michael S. Tsirkin wrote:
    > > On Mon, Jun 22, 2009 at 08:13:48AM -0400, Gregory Haskins wrote:
    > >
    > >>>> + * notification when the memory has been touched.
    > >>>> + * --------------------------------------------------------------------
    > >>>> + */
    > >>>> +
    > >>>> +/*
    > >>>> + * Design note: We create one PIO/MMIO device (iosignalfd_group) which
    > >>>> + * aggregates one or more iosignalfd_items. Each item points to exactly one
    > >>>>
    > > ^^ ^^
    > >
    > >>>> + * eventfd, and can be registered to trigger on any write to the group
    > >>>> + * (wildcard), or to a write of a specific value. If more than one item is to
    > >>>>
    > > ^^
    > >
    > >>>> + * be supported, the addr/len ranges must all be identical in the group. If a
    > >>>>
    > > ^^
    > >
    > >>>> + * trigger value is to be supported on a particular item, the group range must
    > >>>> + * be exactly the width of the trigger.
    > >>>>
    > >>>>
    > >>> Some duplicate spaces in the text above, apparently at random places.
    > >>>
    > >>>
    > >>>
    > >> -ENOPARSE ;)
    > >>
    > >> Can you elaborate?
    > >>
    > >
    > >
    > > Marked with ^^
    > >
    > Heh...well, the first one ("aggregates one") is just a plain typo.
    > The others are just me showing my age, perhaps:
    >
    > http://desktoppub.about.com/cs/typespacing/a/onetwospaces.htm
    >
    > Whether right or wrong, I think I use two-spaces-after-a-period
    > everywhere.

    Ah, I see now. Naturally it is really up to you.

    > I can fix these if they bother you, but I suspect just
    > about every comment I've written has them too. ;)
    >
    > -Greg

    It doesn't bother me as such. But you seem to care about such things :).
    If you do care, other comments in kvm don't seem to be like this and
    people won't remember to add spaces in comments, though.

    >
    > >
    > >>>> + */
    > >>>> +
    > >>>> +struct _iosignalfd_item {
    > >>>> + struct list_head list;
    > >>>> + struct file *file;
    > >>>> + u64 match;
    > >>>> + struct rcu_head rcu;
    > >>>> + int wildcard:1;
    > >>>> +};
    > >>>> +
    > >>>> +struct _iosignalfd_group {
    > >>>> + struct list_head list;
    > >>>> + u64 addr;
    > >>>> + size_t length;
    > >>>> + size_t count;
    > >>>> + struct list_head items;
    > >>>> + struct kvm_io_device dev;
    > >>>> + struct rcu_head rcu;
    > >>>> +};
    > >>>> +
    > >>>> +static inline struct _iosignalfd_group *
    > >>>> +to_group(struct kvm_io_device *dev)
    > >>>> +{
    > >>>> + return container_of(dev, struct _iosignalfd_group, dev);
    > >>>> +}
    > >>>> +
    > >>>> +static void
    > >>>> +iosignalfd_item_free(struct _iosignalfd_item *item)
    > >>>> +{
    > >>>> + fput(item->file);
    > >>>> + kfree(item);
    > >>>> +}
    > >>>> +
    > >>>> +static void
    > >>>> +iosignalfd_item_deferred_free(struct rcu_head *rhp)
    > >>>> +{
    > >>>> + struct _iosignalfd_item *item;
    > >>>> +
    > >>>> + item = container_of(rhp, struct _iosignalfd_item, rcu);
    > >>>> +
    > >>>> + iosignalfd_item_free(item);
    > >>>> +}
    > >>>> +
    > >>>> +static void
    > >>>> +iosignalfd_group_deferred_free(struct rcu_head *rhp)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *group;
    > >>>> +
    > >>>> + group = container_of(rhp, struct _iosignalfd_group, rcu);
    > >>>> +
    > >>>> + kfree(group);
    > >>>> +}
    > >>>> +
    > >>>> +static int
    > >>>> +iosignalfd_group_in_range(struct kvm_io_device *this, gpa_t addr, int len,
    > >>>> + int is_write)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *p = to_group(this);
    > >>>> +
    > >>>> + return ((addr >= p->addr && (addr < p->addr + p->length)));
    > >>>> +}
    > >>>>
    > >>>>
    > >>> What does this test? len is ignored ...
    > >>>
    > >>>
    > >>>
    > >> Yeah, I was following precedent with other IO devices. However, this
    > >> *is* sloppy, I agree. Will fix.
    > >>
    > >>
    > >>>> +
    > >>>> +static int
    > >>>>
    > >>>>
    > >>> This seems to be returning bool ...
    > >>>
    > >>>
    > >> Ack
    > >>
    > >>>
    > >>>
    > >>>> +iosignalfd_is_match(struct _iosignalfd_group *group,
    > >>>> + struct _iosignalfd_item *item,
    > >>>> + const void *val,
    > >>>> + int len)
    > >>>> +{
    > >>>> + u64 _val;
    > >>>> +
    > >>>> + if (len != group->length)
    > >>>> + /* mis-matched length is always a miss */
    > >>>> + return false;
    > >>>>
    > >>>>
    > >>> Why is that? what if there's 8 byte write which covers
    > >>> a 4 byte group?
    > >>>
    > >>>
    > >> v7 and earlier used to allow that for wildcards, actually. It of
    > >> course would never make sense to allow mis-matched writes for
    > >> non-wildcards, since the idea is to match the value exactly. However,
    > >> the feedback I got from Avi was that we should make the wildcard vs
    > >> non-wildcard access symmetrical and ensure they both conform to the size.
    > >>
    > >>>
    > >>>
    > >>>> +
    > >>>> + if (item->wildcard)
    > >>>> + /* wildcard is always a hit */
    > >>>> + return true;
    > >>>> +
    > >>>> + /* otherwise, we have to actually compare the data */
    > >>>> +
    > >>>> + if (!IS_ALIGNED((unsigned long)val, len))
    > >>>> + /* protect against this request causing a SIGBUS */
    > >>>> + return false;
    > >>>>
    > >>>>
    > >>> Could you explain what this does please?
    > >>>
    > >>>
    > >> Sure: item->match is a fixed u64 to represent all group->length
    > >> values. So it might have a 1, 2, 4, or 8 byte value in it. When I
    > >> write arrives, we need to cast the data-register (in this case
    > >> represented by (void*)val) into a u64 so the equality check (see [A],
    > >> below) can be done. However, you can't cast an unaligned pointer, or it
    > >> will SIGBUS on many (most?) architectures.
    > >>
    > >
    > > I mean guest access. Does it have to be aligned?
    > > You could memcpy the value...
    > >
    > >
    > >>> I thought misaligned accesses are allowed.
    > >>>
    > >>>
    > >> If thats true, we are in trouble ;)
    > >>
    > >
    > > I think it works at least on x86:
    > > http://en.wikipedia.org/wiki/Packed#x86_and_x86-64
    > >
    > >
    > >>>
    > >>>
    > >>>> +
    > >>>> + switch (len) {
    > >>>> + case 1:
    > >>>> + _val = *(u8 *)val;
    > >>>> + break;
    > >>>> + case 2:
    > >>>> + _val = *(u16 *)val;
    > >>>> + break;
    > >>>> + case 4:
    > >>>> + _val = *(u32 *)val;
    > >>>> + break;
    > >>>> + case 8:
    > >>>> + _val = *(u64 *)val;
    > >>>> + break;
    > >>>> + default:
    > >>>> + return false;
    > >>>> + }
    > >>>>
    > >>>>
    > >>> So legal values for len are 1,2,4 and 8?
    > >>> Might be a good idea to document this.
    > >>>
    > >>>
    > >>>
    > >> Ack
    > >>
    > >>
    > >>>> +
    > >>>> + return _val == item->match;
    > >>>>
    > >>>>
    > >> [A]
    > >>
    > >>
    > >>>> +}
    > >>>> +
    > >>>> +/*
    > >>>> + * MMIO/PIO writes trigger an event (if the data matches).
    > >>>> + *
    > >>>> + * This is invoked by the io_bus subsystem in response to an address match
    > >>>> + * against the group. We must then walk the list of individual items to check
    > >>>> + * for a match and, if applicable, to send the appropriate signal. If the item
    > >>>> + * in question does not have a "match" pointer, it is considered a wildcard
    > >>>> + * and will always generate a signal. There can be an arbitrary number
    > >>>> + * of distinct matches or wildcards per group.
    > >>>> + */
    > >>>> +static void
    > >>>> +iosignalfd_group_write(struct kvm_io_device *this, gpa_t addr, int len,
    > >>>> + const void *val)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *group = to_group(this);
    > >>>> + struct _iosignalfd_item *item;
    > >>>> +
    > >>>> + rcu_read_lock();
    > >>>> +
    > >>>> + list_for_each_entry_rcu(item, &group->items, list) {
    > >>>> + if (iosignalfd_is_match(group, item, val, len))
    > >>>> + eventfd_signal(item->file, 1);
    > >>>> + }
    > >>>> +
    > >>>> + rcu_read_unlock();
    > >>>> +}
    > >>>> +
    > >>>> +/*
    > >>>> + * MMIO/PIO reads against the group indiscriminately return all zeros
    > >>>> + */
    > >>>>
    > >>>>
    > >>> Does it have to be so? It would be better to bounce reads to
    > >>> userspace...
    > >>>
    > >>>
    > >>>
    > >> Good idea. I can set is_write = false and I should never get this
    > >> function called.
    > >>
    > >>
    > >>>> +static void
    > >>>> +iosignalfd_group_read(struct kvm_io_device *this, gpa_t addr, int len,
    > >>>> + void *val)
    > >>>> +{
    > >>>> + memset(val, 0, len);
    > >>>> +}
    > >>>> +
    > >>>> +/*
    > >>>> + * This function is called as KVM is completely shutting down. We do not
    > >>>> + * need to worry about locking or careful RCU dancing...just nuke anything
    > >>>> + * we have as quickly as possible
    > >>>> + */
    > >>>> +static void
    > >>>> +iosignalfd_group_destructor(struct kvm_io_device *this)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *group = to_group(this);
    > >>>> + struct _iosignalfd_item *item, *tmp;
    > >>>> +
    > >>>> + list_for_each_entry_safe(item, tmp, &group->items, list) {
    > >>>> + list_del(&item->list);
    > >>>> + iosignalfd_item_free(item);
    > >>>> + }
    > >>>> +
    > >>>> + list_del(&group->list);
    > >>>> + kfree(group);
    > >>>> +}
    > >>>> +
    > >>>> +static const struct kvm_io_device_ops iosignalfd_ops = {
    > >>>> + .read = iosignalfd_group_read,
    > >>>> + .write = iosignalfd_group_write,
    > >>>> + .in_range = iosignalfd_group_in_range,
    > >>>> + .destructor = iosignalfd_group_destructor,
    > >>>> +};
    > >>>> +
    > >>>> +/* assumes kvm->lock held */
    > >>>> +static struct _iosignalfd_group *
    > >>>> +iosignalfd_group_find(struct kvm *kvm, u64 addr)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *group;
    > >>>> +
    > >>>> + list_for_each_entry(group, &kvm->iosignalfds, list) {
    > >>>>
    > >>>>
    > >>> {} not needed here
    > >>>
    > >>>
    > >> Ack
    > >>
    > >>>
    > >>>
    > >>>> + if (group->addr == addr)
    > >>>> + return group;
    > >>>> + }
    > >>>> +
    > >>>> + return NULL;
    > >>>> +}
    > >>>> +
    > >>>> +/* assumes kvm->lock is held */
    > >>>> +static struct _iosignalfd_group *
    > >>>> +iosignalfd_group_create(struct kvm *kvm, struct kvm_io_bus *bus,
    > >>>> + u64 addr, size_t len)
    > >>>> +{
    > >>>> + struct _iosignalfd_group *group;
    > >>>> + int ret;
    > >>>> +
    > >>>> + group = kzalloc(sizeof(*group), GFP_KERNEL);
    > >>>> + if (!group)
    > >>>> + return ERR_PTR(-ENOMEM);
    > >>>> +
    > >>>> + INIT_LIST_HEAD(&group->list);
    > >>>> + INIT_LIST_HEAD(&group->items);
    > >>>> + group->addr = addr;
    > >>>> + group->length = len;
    > >>>> + kvm_iodevice_init(&group->dev, &iosignalfd_ops);
    > >>>> +
    > >>>> + ret = kvm_io_bus_register_dev(kvm, bus, &group->dev);
    > >>>> + if (ret < 0) {
    > >>>> + kfree(group);
    > >>>> + return ERR_PTR(ret);
    > >>>> + }
    > >>>> +
    > >>>> + list_add_tail(&group->list, &kvm->iosignalfds);
    > >>>> +
    > >>>> + return group;
    > >>>> +}
    > >>>> +
    > >>>> +static int
    > >>>> +kvm_assign_iosignalfd(struct kvm *kvm, struct kvm_iosignalfd *args)
    > >>>> +{
    > >>>> + int pio = args->flags & KVM_IOSIGNALFD_FLAG_PIO;
    > >>>> + struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
    > >>>> + struct _iosignalfd_group *group = NULL;
    > >>>>
    > >>>>
    > >>> why does group need to be initialized?
    > >>>
    > >>>
    > >>>
    > >>>> + struct _iosignalfd_item *item = NULL;
    > >>>>
    > >>>>
    > >>> Why does item need to be initialized?
    > >>>
    > >>>
    > >>>
    > >> Probably leftover from versions prior to v8. Will fix.
    > >>
    > >>
    > >>>> + struct file *file;
    > >>>> + int ret;
    > >>>> +
    > >>>> + if (args->len > sizeof(u64))
    > >>>>
    > >>>>
    > >>> Is e.g. value 3 legal?
    > >>>
    > >>>
    > >> Ack. Will check against legal values.
    > >>
    > >>
    > >>>
    > >>>
    > >>>> + return -EINVAL;
    > >>>>
    > >>>>
    > >>>
    > >>>
    > >>>> +
    > >>>> + file = eventfd_fget(args->fd);
    > >>>> + if (IS_ERR(file))
    > >>>> + return PTR_ERR(file);
    > >>>> +
    > >>>> + item = kzalloc(sizeof(*item), GFP_KERNEL);
    > >>>> + if (!item) {
    > >>>> + ret = -ENOMEM;
    > >>>> + goto fail;
    > >>>> + }
    > >>>> +
    > >>>> + INIT_LIST_HEAD(&item->list);
    > >>>> + item->file = file;
    > >>>> +
    > >>>> + /*
    > >>>> + * A trigger address is optional, otherwise this is a wildcard
    > >>>> + */
    > >>>> + if (args->flags & KVM_IOSIGNALFD_FLAG_TRIGGER)
    > >>>> + item->match = args->trigger;
    > >>>> + else
    > >>>> + item->wildcard = true;
    > >>>> +
    > >>>> + mutex_lock(&kvm->lock);
    > >>>> +
    > >>>> + /*
    > >>>> + * Put an upper limit on the number of items we support
    > >>>> + */
    > >>>>
    > >>>>
    > >>> Groups and items, actually, right?
    > >>>
    > >>>
    > >>>
    > >> Yeah, though technically that is implicit when you say "items", since
    > >> each group always has at least one item. I will try to make this
    > >> clearer, though.
    > >>
    > >>
    > >>>> + if (kvm->io_device_count >= CONFIG_KVM_MAX_IO_DEVICES) {
    > >>>> + ret = -ENOSPC;
    > >>>> + goto unlock_fail;
    > >>>> + }
    > >>>> +
    > >>>> + group = iosignalfd_group_find(kvm, args->addr);
    > >>>> + if (!group) {
    > >>>> +
    > >>>> + group = iosignalfd_group_create(kvm, bus,
    > >>>> + args->addr, args->len);
    > >>>> + if (IS_ERR(group)) {
    > >>>> + ret = PTR_ERR(group);
    > >>>> + goto unlock_fail;
    > >>>> + }
    > >>>> +
    > >>>> + /*
    > >>>> + * Note: We do not increment io_device_count for the first item,
    > >>>> + * as this is represented by the group device that we just
    > >>>> + * registered. Make sure we handle this properly when we
    > >>>> + * deassign the last item
    > >>>> + */
    > >>>> + } else {
    > >>>> +
    > >>>> + if (group->length != args->len) {
    > >>>> + /*
    > >>>> + * Existing groups must have the same addr/len tuple
    > >>>> + * or we reject the request
    > >>>> + */
    > >>>> + ret = -EINVAL;
    > >>>> + goto unlock_fail;
    > >>>>
    > >>>>
    > >>> Most errors seem to trigger EINVAL. Applications will be
    > >>> easier to debug if different errors are returned on
    > >>> different mistakes.
    > >>>
    > >> Yeah, agreed. Will try to differentiate some errors here.
    > >>
    > >>
    > >>> E.g. here EBUSY might be good. And same
    > >>> in other places.
    > >>>
    > >>>
    > >>>
    > >> Actually, I think EBUSY is supposed to be a transitory error, and would
    > >> not be appropriate to use here. That said, your point is taken: Find
    > >> more appropriate and descriptive errors.
    > >>
    > >>
    > >>>> + }
    > >>>> +
    > >>>> + kvm->io_device_count++;
    > >>>> + }
    > >>>> +
    > >>>> + /*
    > >>>> + * Note: We are committed to succeed at this point since we have
    > >>>> + * (potentially) published a new group-device. Any failure handling
    > >>>> + * added in the future after this point will need to be carefully
    > >>>> + * considered.
    > >>>> + */
    > >>>> +
    > >>>> + list_add_tail_rcu(&item->list, &group->items);
    > >>>> + group->count++;
    > >>>> +
    > >>>> + mutex_unlock(&kvm->lock);
    > >>>> +
    > >>>> + return 0;
    > >>>> +
    > >>>> +unlock_fail:
    > >>>> + mutex_unlock(&kvm->lock);
    > >>>> +fail:
    > >>>> + if (item)
    > >>>> + /*
    > >>>> + * it would have never made it to the group->items list
    > >>>> + * in the failure path, so we dont need to worry about removing
    > >>>> + * it
    > >>>> + */
    > >>>> + kfree(item);
    > >>>> +
    > >>>> + fput(file);
    > >>>> +
    > >>>> + return ret;
    > >>>> +}
    > >>>> +
    > >>>> +
    > >>>> +static int
    > >>>> +kvm_deassign_iosignalfd(struct kvm *kvm, struct kvm_iosignalfd *args)
    > >>>> +{
    > >>>> + int pio = args->flags & KVM_IOSIGNALFD_FLAG_PIO;
    > >>>> + struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
    > >>>> + struct _iosignalfd_group *group;
    > >>>> + struct _iosignalfd_item *item, *tmp;
    > >>>> + struct file *file;
    > >>>> + int ret = 0;
    > >>>> +
    > >>>> + file = eventfd_fget(args->fd);
    > >>>> + if (IS_ERR(file))
    > >>>> + return PTR_ERR(file);
    > >>>> +
    > >>>> + mutex_lock(&kvm->lock);
    > >>>> +
    > >>>> + group = iosignalfd_group_find(kvm, args->addr);
    > >>>> + if (!group) {
    > >>>> + ret = -EINVAL;
    > >>>> + goto out;
    > >>>> + }
    > >>>> +
    > >>>> + /*
    > >>>> + * Exhaustively search our group->items list for any items that might
    > >>>> + * match the specified fd, and (carefully) remove each one found.
    > >>>> + */
    > >>>> + list_for_each_entry_safe(item, tmp, &group->items, list) {
    > >>>> +
    > >>>> + if (item->file != file)
    > >>>> + continue;
    > >>>> +
    > >>>> + list_del_rcu(&item->list);
    > >>>> + group->count--;
    > >>>> + if (group->count)
    > >>>> + /*
    > >>>> + * We only decrement the global count if this is *not*
    > >>>> + * the last item. The last item will be accounted for
    > >>>> + * by the io_bus_unregister
    > >>>> + */
    > >>>> + kvm->io_device_count--;
    > >>>> +
    > >>>> + /*
    > >>>> + * The item may be still referenced inside our group->write()
    > >>>> + * path's RCU read-side CS, so defer the actual free to the
    > >>>> + * next grace
    > >>>> + */
    > >>>> + call_rcu(&item->rcu, iosignalfd_item_deferred_free);
    > >>>> + }
    > >>>> +
    > >>>> + /*
    > >>>> + * Check if the group is now completely vacated as a result of
    > >>>> + * removing the items. If so, unregister/delete it
    > >>>> + */
    > >>>> + if (!group->count) {
    > >>>> +
    > >>>> + kvm_io_bus_unregister_dev(kvm, bus, &group->dev);
    > >>>> +
    > >>>> + /*
    > >>>> + * Like the item, the group may also still be referenced as
    > >>>> + * per above. However, the kvm->iosignalfds list is not
    > >>>> + * RCU protected (its protected by kvm->lock instead) so
    > >>>> + * we can just plain-vanilla remove it. What needs to be
    > >>>> + * done carefully is the actual freeing of the group pointer
    > >>>> + * since we walk the group->items list within the RCU CS.
    > >>>> + */
    > >>>> + list_del(&group->list);
    > >>>> + call_rcu(&group->rcu, iosignalfd_group_deferred_free);
    > >>>>
    > >>>>
    > >>> This is a deferred call, is it not, with no guarantee on when it will
    > >>> run? If correct I think synchronize_rcu might be better here:
    > >>> - can the module go away while iosignalfd_group_deferred_free is
    > >>> running?
    > >>>
    > >>>
    > >> Good catch. Once I go this route it will be easy to use SRCU instead of
    > >> RCU, too. So I will fix this up.
    > >>
    > >>
    > >>
    > >>> - can eventfd be signalled *after* ioctl exits? If yes
    > >>> this might confuse applications if they use the eventfd
    > >>> for something else.
    > >>>
    > >>>
    > >> Not by iosignalfd. Once this function completes, we synchronously
    > >> guarantee that no more IO activity will generate an event on the
    > >> affected eventfds. Of course, this has no bearing on whether some other
    > >> producer wont signal, but that is beyond the scope of iosignalfd.
    > >>
    > >>>
    > >>>
    > >>>> + }
    > >>>> +
    > >>>> +out:
    > >>>> + mutex_unlock(&kvm->lock);
    > >>>> +
    > >>>> + fput(file);
    > >>>> +
    > >>>> + return ret;
    > >>>> +}
    > >>>> +
    > >>>> +int
    > >>>> +kvm_iosignalfd(struct kvm *kvm, struct kvm_iosignalfd *args)
    > >>>> +{
    > >>>> + if (args->flags & KVM_IOSIGNALFD_FLAG_DEASSIGN)
    > >>>> + return kvm_deassign_iosignalfd(kvm, args);
    > >>>> +
    > >>>> + return kvm_assign_iosignalfd(kvm, args);
    > >>>> +}
    > >>>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
    > >>>> index 42cbea7..e6495d4 100644
    > >>>> --- a/virt/kvm/kvm_main.c
    > >>>> +++ b/virt/kvm/kvm_main.c
    > >>>> @@ -971,7 +971,7 @@ static struct kvm *kvm_create_vm(void)
    > >>>> atomic_inc(&kvm->mm->mm_count);
    > >>>> spin_lock_init(&kvm->mmu_lock);
    > >>>> kvm_io_bus_init(&kvm->pio_bus);
    > >>>> - kvm_irqfd_init(kvm);
    > >>>> + kvm_eventfd_init(kvm);
    > >>>> mutex_init(&kvm->lock);
    > >>>> mutex_init(&kvm->irq_lock);
    > >>>> kvm_io_bus_init(&kvm->mmio_bus);
    > >>>> @@ -2227,6 +2227,15 @@ static long kvm_vm_ioctl(struct file *filp,
    > >>>> r = kvm_irqfd(kvm, data.fd, data.gsi, data.flags);
    > >>>> break;
    > >>>> }
    > >>>> + case KVM_IOSIGNALFD: {
    > >>>> + struct kvm_iosignalfd data;
    > >>>> +
    > >>>> + r = -EFAULT;
    > >>>> + if (copy_from_user(&data, argp, sizeof data))
    > >>>> + goto out;
    > >>>> + r = kvm_iosignalfd(kvm, &data);
    > >>>> + break;
    > >>>> + }
    > >>>> #ifdef CONFIG_KVM_APIC_ARCHITECTURE
    > >>>> case KVM_SET_BOOT_CPU_ID:
    > >>>> r = 0;
    > >>>>
    > >>>> --
    > >>>> To unsubscribe from this list: send the line "unsubscribe kvm" in
    > >>>> the body of a message to majordomo@vger.kernel.org
    > >>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
    > >>>>
    > >>>>
    > >> Thanks Michael,
    > >> -Greg
    > >>
    > >>
    > >>
    > >
    > >
    > > --
    > > To unsubscribe from this list: send the line "unsubscribe kvm" in
    > > the body of a message to majordomo@vger.kernel.org
    > > More majordomo info at http://vger.kernel.org/majordomo-info.html
    > >
    >
    >




    \
     
     \ /
      Last update: 2009-06-22 15:11    [W:0.100 / U:1.696 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site