aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Jin <joe.jin@oracle.com>2011-01-07 05:20:54 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-01-10 10:46:31 -0500
commitfc550e95921e109f3778a6b2dc560d63388810ab (patch)
tree432771bf1dc084b52aa22412b49d766bd1671edc
parent731f3ab66a23dab28a359e87364f53d221b3d366 (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>
-rw-r--r--drivers/video/xen-fbfront.c17
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,
562static int xenfb_connect_backend(struct xenbus_device *dev, 562static 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