diff options
author | Joe Jin <joe.jin@oracle.com> | 2011-01-07 05:20:54 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-01-10 10:46:31 -0500 |
commit | fc550e95921e109f3778a6b2dc560d63388810ab (patch) | |
tree | 432771bf1dc084b52aa22412b49d766bd1671edc /drivers | |
parent | 731f3ab66a23dab28a359e87364f53d221b3d366 (diff) |
xen/fb: fix potential memory leak
This patch fixes a potential memory leak when xenfb connect to
the backend fails.
Thanks for Ian's review and comments.
[v2: reworded the commit message a bit]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
Tested-by: Gurudas Pai <gurudas.pai@oracle.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/xen-fbfront.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index f92313d33e27..95bbd0a1e5da 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
@@ -562,26 +562,24 @@ static void xenfb_init_shared_page(struct xenfb_info *info, | |||
562 | static int xenfb_connect_backend(struct xenbus_device *dev, | 562 | static int xenfb_connect_backend(struct xenbus_device *dev, |
563 | struct xenfb_info *info) | 563 | struct xenfb_info *info) |
564 | { | 564 | { |
565 | int ret, evtchn; | 565 | int ret, evtchn, irq; |
566 | struct xenbus_transaction xbt; | 566 | struct xenbus_transaction xbt; |
567 | 567 | ||
568 | ret = xenbus_alloc_evtchn(dev, &evtchn); | 568 | ret = xenbus_alloc_evtchn(dev, &evtchn); |
569 | if (ret) | 569 | if (ret) |
570 | return ret; | 570 | return ret; |
571 | ret = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, | 571 | irq = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, |
572 | 0, dev->devicetype, info); | 572 | 0, dev->devicetype, info); |
573 | if (ret < 0) { | 573 | if (irq < 0) { |
574 | xenbus_free_evtchn(dev, evtchn); | 574 | xenbus_free_evtchn(dev, evtchn); |
575 | xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); | 575 | xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); |
576 | return ret; | 576 | return irq; |
577 | } | 577 | } |
578 | info->irq = ret; | ||
579 | |||
580 | again: | 578 | again: |
581 | ret = xenbus_transaction_start(&xbt); | 579 | ret = xenbus_transaction_start(&xbt); |
582 | if (ret) { | 580 | if (ret) { |
583 | xenbus_dev_fatal(dev, ret, "starting transaction"); | 581 | xenbus_dev_fatal(dev, ret, "starting transaction"); |
584 | return ret; | 582 | goto unbind_irq; |
585 | } | 583 | } |
586 | ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", | 584 | ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", |
587 | virt_to_mfn(info->page)); | 585 | virt_to_mfn(info->page)); |
@@ -603,15 +601,18 @@ static int xenfb_connect_backend(struct xenbus_device *dev, | |||
603 | if (ret == -EAGAIN) | 601 | if (ret == -EAGAIN) |
604 | goto again; | 602 | goto again; |
605 | xenbus_dev_fatal(dev, ret, "completing transaction"); | 603 | xenbus_dev_fatal(dev, ret, "completing transaction"); |
606 | return ret; | 604 | goto unbind_irq; |
607 | } | 605 | } |
608 | 606 | ||
609 | xenbus_switch_state(dev, XenbusStateInitialised); | 607 | xenbus_switch_state(dev, XenbusStateInitialised); |
608 | info->irq = irq; | ||
610 | return 0; | 609 | return 0; |
611 | 610 | ||
612 | error_xenbus: | 611 | error_xenbus: |
613 | xenbus_transaction_end(xbt, 1); | 612 | xenbus_transaction_end(xbt, 1); |
614 | xenbus_dev_fatal(dev, ret, "writing xenstore"); | 613 | xenbus_dev_fatal(dev, ret, "writing xenstore"); |
614 | unbind_irq: | ||
615 | unbind_from_irqhandler(irq, info); | ||
615 | return ret; | 616 | return ret; |
616 | } | 617 | } |
617 | 618 | ||