[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Fix malloc / ring full checking (thanks to Harry Butterworth for spotting these).



ChangeSet 1.1307.2.1, 2005/03/10 16:17:58+00:00, mwilli2@xxxxxxxxxxxxxxxxxxxx

        Fix malloc / ring full checking (thanks to Harry Butterworth for 
spotting these).
        Add more locking (fixes a potential race on 2.4, also needed for safety 
now we
        can do SMP).
        
        Signed-off-by: <mark.williamson@xxxxxxxxxxxx>



 usbfront.c |   38 ++++++++++++++++++++++++++++++++++++--
 xhci.h     |    1 +
 2 files changed, 37 insertions(+), 2 deletions(-)


diff -Nru a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c 
b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c
--- a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c   2005-03-18 
05:03:42 -05:00
+++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c   2005-03-18 
05:03:42 -05:00
@@ -203,6 +203,7 @@
  */
 static int xhci_queue_req(struct urb *urb)
 {
+        unsigned long flags;
         usbif_request_t *req;
         usbif_front_ring_t *usb_ring = &xhci->usb_ring;
 
@@ -213,11 +214,13 @@
                usbif->resp_prod, xhci->usb_resp_cons);
 #endif
         
+        spin_lock_irqsave(&xhci->ring_lock, flags);
 
         if ( RING_FULL(usb_ring) )
         {
                 printk(KERN_WARNING
                        "xhci_queue_req(): USB ring full, not queuing 
request\n");
+                spin_unlock_irqrestore(&xhci->ring_lock, flags);
                 return -ENOBUFS;
         }
 
@@ -253,6 +256,8 @@
         usb_ring->req_prod_pvt++;
         RING_PUSH_REQUESTS(usb_ring);
 
+        spin_unlock_irqrestore(&xhci->ring_lock, flags);
+
        notify_via_evtchn(xhci->evtchn);
 
         DPRINTK("Queued request for an URB.\n");
@@ -276,11 +281,15 @@
                virt_to_machine(&usbif->req_prod),
               usbif->resp_prod, xhci->usb_resp_cons);
 #endif
-        
+ 
+        /* This is always called from the timer interrupt. */
+        spin_lock(&xhci->ring_lock);
+       
         if ( RING_FULL(usb_ring) )
         {
                 printk(KERN_WARNING
                        "xhci_queue_probe(): ring full, not queuing request\n");
+                spin_unlock(&xhci->ring_lock);
                 return NULL;
         }
 
@@ -295,6 +304,8 @@
         usb_ring->req_prod_pvt++;
         RING_PUSH_REQUESTS(usb_ring);
 
+        spin_unlock(&xhci->ring_lock);
+
        notify_via_evtchn(xhci->evtchn);
 
         return req;
@@ -308,6 +319,17 @@
         usbif_request_t *req;
         usbif_front_ring_t *usb_ring = &xhci->usb_ring;
 
+        /* Only ever happens from process context (hub thread). */
+        spin_lock_irq(&xhci->ring_lock);
+
+        if ( RING_FULL(usb_ring) )
+        {
+                printk(KERN_WARNING
+                       "xhci_port_reset(): ring full, not queuing request\n");
+                spin_unlock_irq(&xhci->ring_lock);
+                return -ENOBUFS;
+        }
+
         /* We only reset one port at a time, so we only need one variable per
          * hub. */
         xhci->awaiting_reset = 1;
@@ -323,6 +345,8 @@
         usb_ring->req_prod_pvt++;
        RING_PUSH_REQUESTS(usb_ring);
 
+        spin_unlock_irq(&xhci->ring_lock);
+
        notify_via_evtchn(xhci->evtchn);
 
         while ( xhci->awaiting_reset > 0 )
@@ -1529,6 +1553,10 @@
        xhci->rh.numports = status->num_ports;
 
         xhci->rh.ports = kmalloc (sizeof(xhci_port_t) * xhci->rh.numports, 
GFP_KERNEL);
+       
+       if ( xhci->rh.ports == NULL )
+            goto alloc_ports_nomem;
+       
         memset(xhci->rh.ports, 0, sizeof(xhci_port_t) * xhci->rh.numports);
 
        usb_connect(xhci->rh.dev);
@@ -1553,7 +1581,7 @@
                 xhci->evtchn, xhci->irq);
 
         xhci->state = USBIF_STATE_CONNECTED;
-        
+
         break;
 
     default:
@@ -1561,6 +1589,12 @@
                status->status);
         break;
     }
+
+    return;
+
+ alloc_ports_nomem:
+    printk(KERN_WARNING "Failed to allocate port memory, XHCI failed to 
connect.\n");
+    return;
 }
 
 /**
diff -Nru a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h 
b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h
--- a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h       2005-03-18 
05:03:42 -05:00
+++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h       2005-03-18 
05:03:42 -05:00
@@ -74,6 +74,7 @@
 
        struct virt_root_hub rh;        /* private data of the virtual root hub 
*/
 
+        spinlock_t ring_lock;
         usbif_front_ring_t usb_ring;
 
         int awaiting_reset;


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.