[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |