Skip to content

Commit

Permalink
KVM: arm/arm64: vgic-its: New helper functions to free the caches
Browse files Browse the repository at this point in the history
We create two new functions that free the device and
collection lists. They are currently called by vgic_its_destroy()
and other callers will be added in subsequent patches.

We also remove the check on its->device_list.next.
Lists are initialized in vgic_create_its() and the device
is added to the device list only if this latter succeeds.

vgic_its_destroy is the device destroy ops. This latter is called
by kvm_destroy_devices() which loops on all created devices. So
at this point the list is initialized.

Acked-by: Marc Zyngier <[email protected]>
Signed-off-by: wanghaibin <[email protected]>
Signed-off-by: Eric Auger <[email protected]>
Signed-off-by: Christoffer Dall <[email protected]>
  • Loading branch information
wanghaibin-mouse authored and chazy committed Nov 6, 2017
1 parent 0a0d389 commit 2f609a0
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions virt/kvm/arm/vgic/vgic-its.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,24 @@ static void vgic_its_free_device(struct kvm *kvm, struct its_device *device)
kfree(device);
}

/* its lock must be held */
static void vgic_its_free_device_list(struct kvm *kvm, struct vgic_its *its)
{
struct its_device *cur, *temp;

list_for_each_entry_safe(cur, temp, &its->device_list, dev_list)
vgic_its_free_device(kvm, cur);
}

/* its lock must be held */
static void vgic_its_free_collection_list(struct kvm *kvm, struct vgic_its *its)
{
struct its_collection *cur, *temp;

list_for_each_entry_safe(cur, temp, &its->collection_list, coll_list)
vgic_its_free_collection(its, cur->collection_id);
}

/* Must be called with its_lock mutex held */
static struct its_device *vgic_its_alloc_device(struct vgic_its *its,
u32 device_id, gpa_t itt_addr,
Expand Down Expand Up @@ -1619,32 +1637,13 @@ static void vgic_its_destroy(struct kvm_device *kvm_dev)
{
struct kvm *kvm = kvm_dev->kvm;
struct vgic_its *its = kvm_dev->private;
struct list_head *cur, *temp;

/*
* We may end up here without the lists ever having been initialized.
* Check this and bail out early to avoid dereferencing a NULL pointer.
*/
if (!its->device_list.next)
return;

mutex_lock(&its->its_lock);
list_for_each_safe(cur, temp, &its->device_list) {
struct its_device *dev;

dev = list_entry(cur, struct its_device, dev_list);
vgic_its_free_device(kvm, dev);
}

list_for_each_safe(cur, temp, &its->collection_list) {
struct its_collection *coll;
vgic_its_free_device_list(kvm, its);
vgic_its_free_collection_list(kvm, its);

coll = list_entry(cur, struct its_collection, coll_list);
list_del(cur);
kfree(coll);
}
mutex_unlock(&its->its_lock);

kfree(its);
}

Expand Down

0 comments on commit 2f609a0

Please sign in to comment.