ChangeSet 1.1159.270.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
11:04:11 -05:00
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h 2005-03-21
11:04:11 -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
|