X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-ia64%2Fsystem.h;h=83b2c1bc0ffe6f1b4be0d89c246783d4e3dc8c2c;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=d6a5d7eb44f4c8defda62029e2e5e17b5673103b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index d6a5d7eb4..83b2c1bc0 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -114,10 +114,16 @@ extern struct ia64_boot_param { */ /* For spinlocks etc */ -/* clearing psr.i is implicitly serialized (visible by next insn) */ -/* setting psr.i requires data serialization */ +/* + * - clearing psr.i is implicitly serialized (visible by next insn) + * - setting psr.i requires data serialization + * - we need a stop-bit before reading PSR because we sometimes + * write a floating-point register right before reading the PSR + * and that writes to PSR.mfl + */ #define __local_irq_save(x) \ do { \ + ia64_stop(); \ (x) = ia64_getreg(_IA64_REG_PSR); \ ia64_stop(); \ ia64_rsm(IA64_PSR_I); \ @@ -165,8 +171,8 @@ do { \ # define local_irq_restore(x) __local_irq_restore(x) #endif /* !CONFIG_IA64_DEBUG_IRQ */ -#define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) -#define local_save_flags(flags) ((flags) = ia64_getreg(_IA64_REG_PSR)) +#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) +#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) #define irqs_disabled() \ ({ \ @@ -233,7 +239,7 @@ extern void ia64_load_extra (struct task_struct *task); * the latest fph state from another CPU. In other words: eager save, lazy restore. */ # define switch_to(prev,next,last) do { \ - if (ia64_psr(ia64_task_regs(prev))->mfh) { \ + if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \ ia64_psr(ia64_task_regs(prev))->mfh = 0; \ (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ __ia64_save_fpu((prev)->thread.fph); \