On Thursday 08 January 2009 00:18:39 Marcelo Tosatti wrote:
> Hi Sheng,
>
Thanks for the careful review! :)
> On Wed, Jan 07, 2009 at 06:42:37PM +0800, Sheng Yang wrote:
> > diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
> > index 5162a41..7460e7f 100644
> > --- a/virt/kvm/irq_comm.c
> > +++ b/virt/kvm/irq_comm.c
> > @@ -123,3 +123,73 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, int
> > irq, bool mask) kimn->func(kimn, mask);
> > }
> >
> > +int kvm_update_gsi_route(struct kvm *kvm, struct kvm_gsi_route_entry
> > *entry) +{
> > + struct kvm_gsi_route_entry *found_entry, *new_entry;
> > + int r, gsi;
> > +
> > + mutex_lock(&kvm->lock);
> > + /* Find whether we need a update or a new entry */
> > + found_entry = kvm_find_gsi_route_entry(kvm, entry->gsi);
> > + if (found_entry)
> > + *found_entry = *entry;
> > + else {
>
> Having a kvm_find_alloc_gsi_route_entry which either returns a present
> entry if found or returns a newly allocated one makes the code easier to
> read for me. Then just
>
> entry = kvm_find_alloc_gsi_route_entry
> *entry = *new_entry;
>
> Just style, feel free to ignore the comment.
A little different, for we have to use kvm_find_alloc_gsi_route_entry() to
find correlated gsi for injecting interrupt, so allocate a new one is not that
proper here.
>
> > + gsi = find_first_zero_bit(kvm->gsi_route_bitmap,
> > + KVM_NR_GSI_ROUTE_ENTRIES);
> > + if (gsi >= KVM_NR_GSI_ROUTE_ENTRIES) {
> > + r = -ENOSPC;
> > + goto out;
> > + }
> > + __set_bit(gsi, kvm->gsi_route_bitmap);
> > + entry->gsi = gsi | KVM_GSI_ROUTE_MASK;
> > + new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
>
> Allocate first, then set the bit in the bitmap?
>
> > + if (!new_entry) {
> > + r = -ENOMEM;
> > + goto out;
>
> Because here you don't clear the state on failure.
>
> </NITPICK MODE>
Oh, you are right.:)
>
> > + }
> > + *new_entry = *entry;
> > + hlist_add_head(&new_entry->link, &kvm->gsi_route_list);
> > + }
> > + r = 0;
> > +out:
> > + mutex_unlock(&kvm->lock);
> > + return r;
> > +}
> > +
> >
> > +static int kvm_vm_ioctl_request_gsi_route(struct kvm *kvm,
> > + struct kvm_gsi_route_guest *gsi_route,
> > + struct kvm_gsi_route_entry_guest *guest_entries)
> > +{
> > + struct kvm_gsi_route_entry entry;
> > + int r, i;
> > +
> > + for (i = 0; i < gsi_route->entries_nr; i++) {
> > + memcpy(&entry, &guest_entries[i], sizeof(entry));
> > + r = kvm_update_gsi_route(kvm, &entry);
> > + if (r == 0)
> > + guest_entries[i].gsi = entry.gsi;
> > + else
> > + break;
> > + }
> > + return r;
> > +}
> > +
> > +static int kvm_vm_ioctl_free_gsi_route(struct kvm *kvm,
> > + struct kvm_gsi_route_guest *gsi_route,
> > + struct kvm_gsi_route_entry_guest *guest_entries)
> > +{
> > + struct kvm_gsi_route_entry *entry;
> > + int r, i;
> > +
> > + mutex_lock(&kvm->lock);
> > + for (i = 0; i < gsi_route->entries_nr; i++) {
> > + entry = kvm_find_gsi_route_entry(kvm, guest_entries[i].gsi);
> > + if (!entry ||
> > + memcmp(entry, &guest_entries[i], sizeof(*entry)) != 0) {
> > + printk(KERN_WARNING "kvm: illegal gsi mapping!");
>
> Don't think you need that printk?
After reconsidering, I am not sure if I should verify guest entry here, or
just leave a gsi number to kernel for freeing. I am a little prefer only gsi
here, for I think I can trust userspace to some degree... I would update the
patch.(in fact, I didn't use this ioctl in userspace for now...)
>
> > + r = -EINVAL;
> > + goto out;
> > + }
> > + kvm_free_gsi_route(kvm, entry);
> > + }
> > +out:
> > + mutex_unlock(&kvm->lock);
> > + return r;
> > +}
> > +
> > static long kvm_vcpu_ioctl(struct file *filp,
> > unsigned int ioctl, unsigned long arg)
> > {
> > @@ -1803,6 +1846,7 @@ static long kvm_vm_ioctl(struct file *filp,
> > {
> > struct kvm *kvm = filp->private_data;
> > void __user *argp = (void __user *)arg;
> > + struct kvm_gsi_route_entry_guest *gsi_entries = NULL;
> > int r;
> >
> > if (kvm->mm != current->mm)
> > @@ -1887,10 +1931,72 @@ static long kvm_vm_ioctl(struct file *filp,
> > break;
> > }
> > #endif
> > + case KVM_REQUEST_GSI_ROUTE: {
> > + struct kvm_gsi_route_guest gsi_route;
>
> r = -EFAULT;
> if (copy_from_user...)
> goto out;
>
> etc...
>
> To conform with the rest of the code in the function?
OK...
>
> > + r = copy_from_user(&gsi_route, argp, sizeof gsi_route);
> > + if (r)
> > + goto out;
> > + if (gsi_route.entries_nr == 0) {
> > + r = -EFAULT;
> > + goto out;
> > + }
>
> Should check for a max of KVM_NR_GSI_ROUTE_ENTRIES ?
Yeah.
>
> > + gsi_entries = kmalloc(gsi_route.entries_nr *
> > + sizeof(struct kvm_gsi_route_entry_guest),
> > + GFP_KERNEL);
>
> And use vmalloc/vfree instead.
Yeah... kmalloc is not necessary here...
>
> > + if (!gsi_entries) {
> > + r = -ENOMEM;
> > + goto out;
> > + }
> > + r = copy_from_user(gsi_entries,
> > + (void __user *)gsi_route.entries,
> > + gsi_route.entries_nr *
> > + sizeof(struct kvm_gsi_route_entry_guest));
> > + if (r)
> > + goto out;
> > + r = kvm_vm_ioctl_request_gsi_route(kvm, &gsi_route,
> > + gsi_entries);
> > + if (r)
> > + goto out;
> > + r = copy_to_user((void __user *)gsi_route.entries,
> > + gsi_entries,
> > + gsi_route.entries_nr *
> > + sizeof(struct kvm_gsi_route_entry_guest));
> > + if (r)
> > + goto out;
> > + break;
> > + }
> > + case KVM_FREE_GSI_ROUTE: {
> > + struct kvm_gsi_route_guest gsi_route;
> > + r = copy_from_user(&gsi_route, argp, sizeof gsi_route);
> > + if (r)
> > + goto out;
> > + if (gsi_route.entries_nr == 0) {
> > + r = -EFAULT;
> > + goto out;
> > + }
>
> Check KVM_NR_GSI_ROUTE_ENTRIES and vmalloc.
Sure.
--
regards
Yang, Sheng
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html