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

[Xen-changelog] Fix floppy driver on Xen -- vmalloc/vfree are unsafe because of the



ChangeSet 1.1794.1.4, 2005/03/21 09:51:50+00:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix floppy driver on Xen -- vmalloc/vfree are unsafe because of the
        context that the fd_dma functions may get called from.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 floppy.h |  119 +++++++++++----------------------------------------------------
 1 files changed, 22 insertions(+), 97 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h 
b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h 2005-03-21 
05:03:42 -05:00
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h 2005-03-21 
05:03:42 -05:00
@@ -28,10 +28,14 @@
 #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
 #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
 #define fd_free_irq()          free_irq(FLOPPY_IRQ, NULL)
-#define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
-#define fd_dma_mem_alloc(size) vdma_mem_alloc(size)
-#define fd_dma_mem_free(addr, size) vdma_mem_free(addr, size) 
+#define fd_get_dma_residue()    (virtual_dma_count + virtual_dma_residue)
 #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
+/*
+ * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from
+ * softirq context via motor_off_callback. A generic bug we happen to trigger.
+ */
+#define fd_dma_mem_alloc(size) __get_free_pages(GFP_KERNEL, get_order(size))
+#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
 
 static int virtual_dma_count;
 static int virtual_dma_residue;
@@ -42,99 +46,36 @@
 static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
 {
        register unsigned char st;
+       register int lcount;
+       register char *lptr;
 
-#undef TRACE_FLPY_INT
-#define NO_FLOPPY_ASSEMBLER
-
-#ifdef TRACE_FLPY_INT
-       static int calls=0;
-       static int bytes=0;
-       static int dma_wait=0;
-#endif
        if (!doing_pdma)
                return floppy_interrupt(irq, dev_id, regs);
 
-#ifdef TRACE_FLPY_INT
-       if(!calls)
-               bytes = virtual_dma_count;
-#endif
-
-#ifndef NO_FLOPPY_ASSEMBLER
-       __asm__ (
-       "testl %1,%1"
-       "je 3f"
-"1:    inb %w4,%b0"
-       "andb $160,%b0"
-       "cmpb $160,%b0"
-       "jne 2f"
-       "incw %w4"
-       "testl %3,%3"
-       "jne 4f"
-       "inb %w4,%b0"
-       "movb %0,(%2)"
-       "jmp 5f"
-"4:            movb (%2),%0"
-       "outb %b0,%w4"
-"5:    decw %w4"
-       "outb %0,$0x80"
-       "decl %1"
-       "incl %2"
-       "testl %1,%1"
-       "jne 1b"
-"3:    inb %w4,%b0"
-"2:    "
-       : "=a" ((char) st), 
-       "=c" ((long) virtual_dma_count), 
-       "=S" ((long) virtual_dma_addr)
-       : "b" ((long) virtual_dma_mode),
-       "d" ((short) virtual_dma_port+4), 
-       "1" ((long) virtual_dma_count),
-       "2" ((long) virtual_dma_addr));
-#else  
-       {
-               register int lcount;
-               register char *lptr;
-
-               st = 1;
-               for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
-                   lcount; lcount--, lptr++) {
-                       st=inb(virtual_dma_port+4) & 0xa0 ;
-                       if(st != 0xa0) 
-                               break;
-                       if(virtual_dma_mode)
-                               outb_p(*lptr, virtual_dma_port+5);
-                       else
-                               *lptr = inb_p(virtual_dma_port+5);
-               }
-               virtual_dma_count = lcount;
-               virtual_dma_addr = lptr;
-               st = inb(virtual_dma_port+4);
+       st = 1;
+       for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
+           lcount; lcount--, lptr++) {
+               st=inb(virtual_dma_port+4) & 0xa0 ;
+               if(st != 0xa0) 
+                       break;
+               if(virtual_dma_mode)
+                       outb_p(*lptr, virtual_dma_port+5);
+               else
+                       *lptr = inb_p(virtual_dma_port+5);
        }
-#endif
+       virtual_dma_count = lcount;
+       virtual_dma_addr = lptr;
+       st = inb(virtual_dma_port+4);
 
-#ifdef TRACE_FLPY_INT
-       calls++;
-#endif
        if(st == 0x20)
                return IRQ_HANDLED;
        if(!(st & 0x20)) {
                virtual_dma_residue += virtual_dma_count;
                virtual_dma_count=0;
-#ifdef TRACE_FLPY_INT
-               printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
-                      virtual_dma_count, virtual_dma_residue, calls, bytes,
-                      dma_wait);
-               calls = 0;
-               dma_wait=0;
-#endif
                doing_pdma = 0;
                floppy_interrupt(irq, dev_id, regs);
                return IRQ_HANDLED;
        }
-#ifdef TRACE_FLPY_INT
-       if(!virtual_dma_count)
-               dma_wait++;
-#endif
        return IRQ_HANDLED;
 }
 
@@ -145,26 +86,10 @@
        virtual_dma_count=0;
 }
 
-static int vdma_get_dma_residue(unsigned int dummy)
-{
-       return virtual_dma_count + virtual_dma_residue;
-}
-
 static int fd_request_irq(void)
 {
        return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
                                           "floppy", NULL);
-}
-
-static unsigned long vdma_mem_alloc(unsigned long size)
-{
-       return (unsigned long) vmalloc(size);
-
-}
-
-static void vdma_mem_free(unsigned long addr, unsigned long size)
-{
-       vfree((void *)addr);
 }
 
 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)


-------------------------------------------------------
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®.