From 9bbafce2eec190ef7e44b0eb1095ba17ce6ad3af Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 26 Mar 2008 19:02:47 +0900 Subject: sh: Fix occasional FPU register corruption under preempt. Presently with preempt enabled there's the possibility to be preempted after the TIF_USEDFPU test and the register save, leading to bogus state post-__switch_to(). Use an explicit preempt_disable()/enable() pair around unlazy_fpu()/clear_fpu() to avoid this. Follows the x86 change. Reported-by: Takuo Koguchi Signed-off-by: Paul Mundt --- include/asm-sh/fpu.h | 32 ++++++++++++++++++-------------- include/asm-sh/processor.h | 1 - include/asm-sh/processor_32.h | 1 + include/asm-sh/processor_64.h | 1 + 4 files changed, 20 insertions(+), 15 deletions(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/fpu.h b/include/asm-sh/fpu.h index f8429880a27..f89abf5920d 100644 --- a/include/asm-sh/fpu.h +++ b/include/asm-sh/fpu.h @@ -1,9 +1,8 @@ #ifndef __ASM_SH_FPU_H #define __ASM_SH_FPU_H -#define SR_FD 0x00008000 - #ifndef __ASSEMBLY__ +#include #include #ifdef CONFIG_SH_FPU @@ -28,18 +27,23 @@ extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); extern int do_fpu_inst(unsigned short, struct pt_regs *); -#define unlazy_fpu(tsk, regs) do { \ - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ - save_fpu(tsk, regs); \ - } \ -} while (0) - -#define clear_fpu(tsk, regs) do { \ - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ - clear_tsk_thread_flag(tsk, TIF_USEDFPU); \ - release_fpu(regs); \ - } \ -} while (0) +static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) +{ + preempt_disable(); + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) + save_fpu(tsk, regs); + preempt_enable(); +} + +static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs) +{ + preempt_disable(); + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { + clear_tsk_thread_flag(tsk, TIF_USEDFPU); + release_fpu(regs); + } + preempt_enable(); +} #endif /* __ASSEMBLY__ */ diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 19fe47c1ca1..ec707b98e5b 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -2,7 +2,6 @@ #define __ASM_SH_PROCESSOR_H #include -#include #ifndef __ASSEMBLY__ /* diff --git a/include/asm-sh/processor_32.h b/include/asm-sh/processor_32.h index df2d5b039ef..c09305d6a9d 100644 --- a/include/asm-sh/processor_32.h +++ b/include/asm-sh/processor_32.h @@ -70,6 +70,7 @@ extern struct sh_cpuinfo cpu_data[]; */ #define SR_DSP 0x00001000 #define SR_IMASK 0x000000f0 +#define SR_FD 0x00008000 /* * FPU structure and data diff --git a/include/asm-sh/processor_64.h b/include/asm-sh/processor_64.h index eda4bef448e..88a2edf8fa5 100644 --- a/include/asm-sh/processor_64.h +++ b/include/asm-sh/processor_64.h @@ -112,6 +112,7 @@ extern struct sh_cpuinfo cpu_data[]; #endif #define SR_IMASK 0x000000f0 +#define SR_FD 0x00008000 #define SR_SSTEP 0x08000000 #ifndef __ASSEMBLY__ -- cgit v1.2.3 From 138bed154eab2205b4ef93f02f5feb1edf6d8552 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 26 Mar 2008 19:09:21 +0900 Subject: sh: Fix TIF_USEDFPU clearing under FPU emulation. The unlazy_fpu() path calls in to save_fpu() if the task has TIF_USEDFPU set. save_fpu() being the crap API that it is has the side effect of clearing the flag itself, which presently doesn't happen if we're using FPU emulation. Fix this up for now, pending an overhaul in 2.6.26. Signed-off-by: Paul Mundt --- include/asm-sh/fpu.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/fpu.h b/include/asm-sh/fpu.h index f89abf5920d..91462fea150 100644 --- a/include/asm-sh/fpu.h +++ b/include/asm-sh/fpu.h @@ -20,9 +20,14 @@ struct task_struct; extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); #else + #define release_fpu(regs) do { } while (0) #define grab_fpu(regs) do { } while (0) -#define save_fpu(tsk, regs) do { } while (0) + +static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs) +{ + clear_tsk_thread_flag(tsk, TIF_USEDFPU); +} #endif extern int do_fpu_inst(unsigned short, struct pt_regs *); -- cgit v1.2.3 From 7d7f7c3ed2c519a462a4ae989ad3d55cc7f7f6ec Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 31 Mar 2008 01:53:43 +0300 Subject: remove include/asm-sh/floppy.h This patch removes the unused include/asm-sh/floppy.h (ARCH_MAY_HAVE_PC_FDC was not enabled). Signed-off-by: Adrian Bunk Signed-off-by: Paul Mundt --- include/asm-sh/floppy.h | 268 ------------------------------------------------ 1 file changed, 268 deletions(-) delete mode 100644 include/asm-sh/floppy.h (limited to 'include/asm-sh') diff --git a/include/asm-sh/floppy.h b/include/asm-sh/floppy.h deleted file mode 100644 index 59fbfdc90df..00000000000 --- a/include/asm-sh/floppy.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Architecture specific parts of the Floppy driver - * include/asm-i386/floppy.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995 - */ -#ifndef __ASM_SH_FLOPPY_H -#define __ASM_SH_FLOPPY_H - -#include - - -/* - * The DMA channel used by the floppy controller cannot access data at - * addresses >= 16MB - * - * Went back to the 1MB limit, as some people had problems with the floppy - * driver otherwise. It doesn't matter much for performance anyway, as most - * floppy accesses go through the track buffer. - */ -#define _CROSS_64KB(a,s,vdma) \ -(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) - -#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1) - - -#define SW fd_routine[use_virtual_dma&1] -#define CSW fd_routine[can_use_virtual_dma & 1] - - -#define fd_inb(port) inb_p(port) -#define fd_outb(value,port) outb_p(value,port) - -#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy") -#define fd_free_dma() CSW._free_dma(FLOPPY_DMA) -#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() SW._get_dma_residue(FLOPPY_DMA) -#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size) -#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io) - -#define FLOPPY_CAN_FALLBACK_ON_NODMA - -static int virtual_dma_count; -static int virtual_dma_residue; -static char *virtual_dma_addr; -static int virtual_dma_mode; -static int doing_pdma; - -static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) -{ - register unsigned char st; - -#undef TRACE_FLPY_INT - -#ifdef TRACE_FLPY_INT - static int calls=0; - static int bytes=0; - static int dma_wait=0; -#endif - if(!doing_pdma) { - floppy_interrupt(irq, dev_id, regs); - return; - } - -#ifdef TRACE_FLPY_INT - if(!calls) - bytes = virtual_dma_count; -#endif - - { - 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); - } - -#ifdef TRACE_FLPY_INT - calls++; -#endif - if(st == 0x20) - return; - 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; - } -#ifdef TRACE_FLPY_INT - if(!virtual_dma_count) - dma_wait++; -#endif -} - -static void fd_disable_dma(void) -{ - if(! (can_use_virtual_dma & 1)) - disable_dma(FLOPPY_DMA); - doing_pdma = 0; - virtual_dma_residue += virtual_dma_count; - virtual_dma_count=0; -} - -static int vdma_request_dma(unsigned int dmanr, const char * device_id) -{ - return 0; -} - -static void vdma_nop(unsigned int dummy) -{ -} - - -static int vdma_get_dma_residue(unsigned int dummy) -{ - return virtual_dma_count + virtual_dma_residue; -} - - -static int fd_request_irq(void) -{ - if(can_use_virtual_dma) - return request_irq(FLOPPY_IRQ, floppy_hardint, - IRQF_DISABLED, "floppy", NULL); - else - return request_irq(FLOPPY_IRQ, floppy_interrupt, - IRQF_DISABLED, "floppy", NULL); -} - -static unsigned long dma_mem_alloc(unsigned long size) -{ - return __get_dma_pages(GFP_KERNEL,get_order(size)); -} - - -static unsigned long vdma_mem_alloc(unsigned long size) -{ - return (unsigned long) vmalloc(size); - -} - -#define nodma_mem_alloc(size) vdma_mem_alloc(size) - -static void _fd_dma_mem_free(unsigned long addr, unsigned long size) -{ - if((unsigned int) addr >= (unsigned int) high_memory) - return vfree((void *)addr); - else - free_pages(addr, get_order(size)); -} - -#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size) - -static void _fd_chose_dma_mode(char *addr, unsigned long size) -{ - if(can_use_virtual_dma == 2) { - if((unsigned int) addr >= (unsigned int) high_memory || - virt_to_phys(addr) >= 0x10000000) - use_virtual_dma = 1; - else - use_virtual_dma = 0; - } else { - use_virtual_dma = can_use_virtual_dma & 1; - } -} - -#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size) - - -static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) -{ - doing_pdma = 1; - virtual_dma_port = io; - virtual_dma_mode = (mode == DMA_MODE_WRITE); - virtual_dma_addr = addr; - virtual_dma_count = size; - virtual_dma_residue = 0; - return 0; -} - -static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) -{ -#ifdef FLOPPY_SANITY_CHECK - if (CROSS_64KB(addr, size)) { - printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size); - return -1; - } -#endif - - __flush_purge_region(addr, size); - - /* actual, physical DMA */ - doing_pdma = 0; - clear_dma_ff(FLOPPY_DMA); - set_dma_mode(FLOPPY_DMA,mode); - set_dma_addr(FLOPPY_DMA,virt_to_phys(addr)); - set_dma_count(FLOPPY_DMA,size); - enable_dma(FLOPPY_DMA); - return 0; -} - -static struct fd_routine_l { - int (*_request_dma)(unsigned int dmanr, const char * device_id); - void (*_free_dma)(unsigned int dmanr); - int (*_get_dma_residue)(unsigned int dummy); - unsigned long (*_dma_mem_alloc) (unsigned long size); - int (*_dma_setup)(char *addr, unsigned long size, int mode, int io); -} fd_routine[] = { - { - request_dma, - free_dma, - get_dma_residue, - dma_mem_alloc, - hard_dma_setup - }, - { - vdma_request_dma, - vdma_nop, - vdma_get_dma_residue, - vdma_mem_alloc, - vdma_dma_setup - } -}; - - -static int FDC1 = 0x3f0; -static int FDC2 = -1; - -/* - * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock - * is needed to prevent corrupted CMOS RAM in case "insmod floppy" - * coincides with another rtc CMOS user. Paul G. - */ -#define FLOPPY0_TYPE (4) -#define FLOPPY1_TYPE (0) - -#define N_FDC 2 -#define N_DRIVE 8 - -#define EXTRA_FLOPPY_PARAMS - -#endif /* __ASM_SH_FLOPPY_H */ -- cgit v1.2.3 From dd135ebbd2a6b5e07dadb66c4dd033bb69531051 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 2 Apr 2008 13:04:40 -0700 Subject: kvm: provide kvm.h for all architecture: fixes headers_install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently include/linux/kvm.h is not considered by make headers_install, because Kbuild cannot handle " unifdef-$(CONFIG_FOO) += foo.h. This problem was introduced by commit fb56dbb31c4738a3918db81fd24da732ce3b4ae6 Author: Avi Kivity Date: Sun Dec 2 10:50:06 2007 +0200 KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM Currently, make headers_check barfs due to , which includes, not existing. Rather than add a zillion s, export kvm. only if the arch actually supports it. Signed-off-by: Avi Kivity which makes this an 2.6.25 regression. One way of solving the issue is to enhance Kbuild, but Avi and David conviced me, that changing headers_install is not the way to go. This patch changes the definition for linux/kvm.h to unifdef-y. If  unifdef-y is used for linux/kvm.h "make headers_check" will fail on all architectures without asm/kvm.h. Therefore, this patch also provides asm/kvm.h on all architectures. Signed-off-by: Christian Borntraeger Acked-by: Avi Kivity Cc: Sam Ravnborg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-sh/kvm.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 include/asm-sh/kvm.h (limited to 'include/asm-sh') diff --git a/include/asm-sh/kvm.h b/include/asm-sh/kvm.h new file mode 100644 index 00000000000..6af51dbab2d --- /dev/null +++ b/include/asm-sh/kvm.h @@ -0,0 +1,6 @@ +#ifndef __LINUX_KVM_SH_H +#define __LINUX_KVM_SH_H + +/* sh does not support KVM */ + +#endif -- cgit v1.2.3