diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/arm/vgic/vgic-its.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index ec7e07bc2559..07411cf967b9 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c | |||
@@ -697,36 +697,34 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, | |||
697 | struct its_device *device; | 697 | struct its_device *device; |
698 | struct its_collection *collection, *new_coll = NULL; | 698 | struct its_collection *collection, *new_coll = NULL; |
699 | int lpi_nr; | 699 | int lpi_nr; |
700 | int ret; | ||
701 | 700 | ||
702 | device = find_its_device(its, device_id); | 701 | device = find_its_device(its, device_id); |
703 | if (!device) | 702 | if (!device) |
704 | return E_ITS_MAPTI_UNMAPPED_DEVICE; | 703 | return E_ITS_MAPTI_UNMAPPED_DEVICE; |
705 | 704 | ||
706 | collection = find_collection(its, coll_id); | ||
707 | if (!collection) { | ||
708 | ret = vgic_its_alloc_collection(its, &collection, coll_id); | ||
709 | if (ret) | ||
710 | return ret; | ||
711 | new_coll = collection; | ||
712 | } | ||
713 | |||
714 | if (its_cmd_get_command(its_cmd) == GITS_CMD_MAPTI) | 705 | if (its_cmd_get_command(its_cmd) == GITS_CMD_MAPTI) |
715 | lpi_nr = its_cmd_get_physical_id(its_cmd); | 706 | lpi_nr = its_cmd_get_physical_id(its_cmd); |
716 | else | 707 | else |
717 | lpi_nr = event_id; | 708 | lpi_nr = event_id; |
718 | if (lpi_nr < GIC_LPI_OFFSET || | 709 | if (lpi_nr < GIC_LPI_OFFSET || |
719 | lpi_nr >= max_lpis_propbaser(kvm->arch.vgic.propbaser)) { | 710 | lpi_nr >= max_lpis_propbaser(kvm->arch.vgic.propbaser)) |
720 | ret = E_ITS_MAPTI_PHYSICALID_OOR; | 711 | return E_ITS_MAPTI_PHYSICALID_OOR; |
721 | goto err; | 712 | |
713 | collection = find_collection(its, coll_id); | ||
714 | if (!collection) { | ||
715 | int ret = vgic_its_alloc_collection(its, &collection, coll_id); | ||
716 | if (ret) | ||
717 | return ret; | ||
718 | new_coll = collection; | ||
722 | } | 719 | } |
723 | 720 | ||
724 | itte = find_itte(its, device_id, event_id); | 721 | itte = find_itte(its, device_id, event_id); |
725 | if (!itte) { | 722 | if (!itte) { |
726 | itte = kzalloc(sizeof(struct its_itte), GFP_KERNEL); | 723 | itte = kzalloc(sizeof(struct its_itte), GFP_KERNEL); |
727 | if (!itte) { | 724 | if (!itte) { |
728 | ret = -ENOMEM; | 725 | if (new_coll) |
729 | goto err; | 726 | vgic_its_free_collection(its, coll_id); |
727 | return -ENOMEM; | ||
730 | } | 728 | } |
731 | 729 | ||
732 | itte->event_id = event_id; | 730 | itte->event_id = event_id; |
@@ -746,10 +744,6 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, | |||
746 | update_lpi_config(kvm, itte->irq, NULL); | 744 | update_lpi_config(kvm, itte->irq, NULL); |
747 | 745 | ||
748 | return 0; | 746 | return 0; |
749 | err: | ||
750 | if (new_coll) | ||
751 | vgic_its_free_collection(its, coll_id); | ||
752 | return ret; | ||
753 | } | 747 | } |
754 | 748 | ||
755 | /* Requires the its_lock to be held. */ | 749 | /* Requires the its_lock to be held. */ |