ia64/xen-unstable

changeset 3917:86b610094dd0

bitkeeper revision 1.1236.1.16 (421db67dL0mXatHebAtt9KpMqkCIBQ)

More FPU fixes. Extend taskswitch hypercall to allow TS bit to be
cleared as well as set.
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 24 11:11:57 2005 +0000 (2005-02-24)
parents ade108bf0e19
children 926914d421dc f7c31440d003
files extras/mini-os/h/hypervisor.h linux-2.4.29-xen-sparse/arch/xen/kernel/process.c linux-2.4.29-xen-sparse/include/asm-xen/system.h linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h xen/arch/x86/traps.c
line diff
     1.1 --- a/extras/mini-os/h/hypervisor.h	Thu Feb 24 11:10:19 2005 +0000
     1.2 +++ b/extras/mini-os/h/hypervisor.h	Thu Feb 24 11:11:57 2005 +0000
     1.3 @@ -126,12 +126,18 @@ static __inline__ int HYPERVISOR_set_cal
     1.4  }
     1.5  #endif
     1.6  
     1.7 -static __inline__ int HYPERVISOR_fpu_taskswitch(void)
     1.8 +static __inline__ int
     1.9 +HYPERVISOR_fpu_taskswitch(
    1.10 +    int set)
    1.11  {
    1.12      int ret;
    1.13 +    unsigned long ign;
    1.14 +
    1.15      __asm__ __volatile__ (
    1.16          TRAP_INSTR
    1.17 -        : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
    1.18 +        : "=a" (ret), "=b" (ign)
    1.19 +        : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set)
    1.20 +        : "memory" );
    1.21  
    1.22      return ret;
    1.23  }
     2.1 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/process.c	Thu Feb 24 11:10:19 2005 +0000
     2.2 +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/process.c	Thu Feb 24 11:11:57 2005 +0000
     2.3 @@ -334,7 +334,7 @@ void fastcall __switch_to(struct task_st
     2.4              asm volatile( "fnsave %0 ; fwait"
     2.5                            : "=m" (prev_p->thread.i387.fsave) );
     2.6  	prev_p->flags &= ~PF_USEDFPU;
     2.7 -        queue_multicall0(__HYPERVISOR_fpu_taskswitch);
     2.8 +        queue_multicall1(__HYPERVISOR_fpu_taskswitch, 1);
     2.9      }
    2.10  
    2.11      queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
     3.1 --- a/linux-2.4.29-xen-sparse/include/asm-xen/system.h	Thu Feb 24 11:10:19 2005 +0000
     3.2 +++ b/linux-2.4.29-xen-sparse/include/asm-xen/system.h	Thu Feb 24 11:11:57 2005 +0000
     3.3 @@ -109,7 +109,7 @@ static inline unsigned long _get_base(ch
     3.4  
     3.5  /* NB. 'clts' is done for us by Xen during virtual trap. */
     3.6  #define clts() ((void)0)
     3.7 -#define stts() (HYPERVISOR_fpu_taskswitch())
     3.8 +#define stts() (HYPERVISOR_fpu_taskswitch(1))
     3.9  
    3.10  #endif	/* __KERNEL__ */
    3.11  
     4.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Thu Feb 24 11:10:19 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Thu Feb 24 11:11:57 2005 +0000
     4.3 @@ -500,7 +500,7 @@ struct task_struct fastcall * __switch_t
     4.4  	 */
     4.5  	if (prev_p->thread_info->status & TS_USEDFPU) {
     4.6  		__save_init_fpu(prev_p); /* _not_ save_init_fpu() */
     4.7 -		queue_multicall0(__HYPERVISOR_fpu_taskswitch);
     4.8 +		queue_multicall1(__HYPERVISOR_fpu_taskswitch, 1);
     4.9  	}
    4.10  
    4.11  	/*
     5.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Feb 24 11:10:19 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Feb 24 11:11:57 2005 +0000
     5.3 @@ -902,14 +902,6 @@ asmlinkage void math_state_restore(struc
     5.4  	struct thread_info *thread = current_thread_info();
     5.5  	struct task_struct *tsk = thread->task;
     5.6  
     5.7 -	/*
     5.8 -	 * A trap in kernel mode can be ignored. It'll be the fast XOR or
     5.9 -	 * copying libraries, which will correctly save/restore state and
    5.10 -	 * reset the TS bit in CR0.
    5.11 -	 */
    5.12 -	if ((regs.xcs & 2) == 0)
    5.13 -		return;
    5.14 -
    5.15  	/* NB. 'clts' is done for us by Xen during virtual trap. */
    5.16  	if (!tsk->used_math)
    5.17  		init_fpu(tsk);
     6.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Feb 24 11:10:19 2005 +0000
     6.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Feb 24 11:11:57 2005 +0000
     6.3 @@ -106,17 +106,16 @@ static inline unsigned long _get_base(ch
     6.4  /*
     6.5   * Clear and set 'TS' bit respectively
     6.6   */
     6.7 -#define clts() __asm__ __volatile__ ("clts")
     6.8 +#define clts() (HYPERVISOR_fpu_taskswitch(0))
     6.9  #define read_cr0() \
    6.10  	BUG();
    6.11  #define write_cr0(x) \
    6.12  	BUG();
    6.13 -
    6.14  #define read_cr4() \
    6.15  	BUG();
    6.16  #define write_cr4(x) \
    6.17  	BUG();
    6.18 -#define stts() (HYPERVISOR_fpu_taskswitch())
    6.19 +#define stts() (HYPERVISOR_fpu_taskswitch(1))
    6.20  
    6.21  #endif	/* __KERNEL__ */
    6.22  
     7.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h	Thu Feb 24 11:10:19 2005 +0000
     7.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h	Thu Feb 24 11:11:57 2005 +0000
     7.3 @@ -212,12 +212,16 @@ HYPERVISOR_set_callbacks(
     7.4  
     7.5  static inline int
     7.6  HYPERVISOR_fpu_taskswitch(
     7.7 -    void)
     7.8 +    int set)
     7.9  {
    7.10      int ret;
    7.11 +    unsigned long ign;
    7.12 +
    7.13      __asm__ __volatile__ (
    7.14          TRAP_INSTR
    7.15 -        : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
    7.16 +        : "=a" (ret), "=b" (ign)
    7.17 +        : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set)
    7.18 +        : "memory" );
    7.19  
    7.20      return ret;
    7.21  }
     8.1 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c	Thu Feb 24 11:10:19 2005 +0000
     8.2 +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c	Thu Feb 24 11:11:57 2005 +0000
     8.3 @@ -412,7 +412,7 @@ i386_proc0_tss_ldt_init()
     8.4  	ltr(lwp0.l_md.md_tss_sel);
     8.5  	lldt(pcb->pcb_ldt_sel);
     8.6  #else
     8.7 -	HYPERVISOR_fpu_taskswitch();
     8.8 +	HYPERVISOR_fpu_taskswitch(1);
     8.9  	XENPRINTF(("lwp tss sp %p ss %04x/%04x\n",
    8.10  		      (void *)pcb->pcb_tss.tss_esp0,
    8.11  		      pcb->pcb_tss.tss_ss0, IDXSEL(pcb->pcb_tss.tss_ss0)));
    8.12 @@ -455,7 +455,7 @@ i386_switch_context(struct pcb *new)
    8.13  
    8.14  	ci = curcpu();
    8.15  	if (ci->ci_fpused) {
    8.16 -		HYPERVISOR_fpu_taskswitch();
    8.17 +		HYPERVISOR_fpu_taskswitch(1);
    8.18  		ci->ci_fpused = 0;
    8.19  	}
    8.20  
     9.1 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h	Thu Feb 24 11:10:19 2005 +0000
     9.2 +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h	Thu Feb 24 11:11:57 2005 +0000
     9.3 @@ -180,12 +180,16 @@ HYPERVISOR_set_callbacks(
     9.4  }
     9.5  
     9.6  static inline int
     9.7 -HYPERVISOR_fpu_taskswitch(void)
     9.8 +HYPERVISOR_fpu_taskswitch(int set)
     9.9  {
    9.10      int ret;
    9.11 +    unsigned long ign;
    9.12 +
    9.13      __asm__ __volatile__ (
    9.14          TRAP_INSTR
    9.15 -        : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
    9.16 +        : "=a" (ret), "=b" (ign)
    9.17 +        : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set)
    9.18 +        : "memory" );
    9.19  
    9.20      return ret;
    9.21  }
    10.1 --- a/xen/arch/x86/traps.c	Thu Feb 24 11:10:19 2005 +0000
    10.2 +++ b/xen/arch/x86/traps.c	Thu Feb 24 11:11:57 2005 +0000
    10.3 @@ -348,6 +348,25 @@ asmlinkage int do_page_fault(struct xen_
    10.4      return 0;
    10.5  }
    10.6  
    10.7 +long do_fpu_taskswitch(int set)
    10.8 +{
    10.9 +    struct exec_domain *ed = current;
   10.10 +
   10.11 +    if ( set )
   10.12 +    {
   10.13 +        set_bit(EDF_GUEST_STTS, &ed->ed_flags);
   10.14 +        stts();
   10.15 +    }
   10.16 +    else
   10.17 +    {
   10.18 +        clear_bit(EDF_GUEST_STTS, &ed->ed_flags);
   10.19 +        if ( test_bit(EDF_USEDFPU, &ed->ed_flags) )
   10.20 +            clts();
   10.21 +    }
   10.22 +
   10.23 +    return 0;
   10.24 +}
   10.25 +
   10.26  static int emulate_privileged_op(struct xen_regs *regs)
   10.27  {
   10.28      extern void *decode_reg(struct xen_regs *regs, u8 b);
   10.29 @@ -369,9 +388,7 @@ static int emulate_privileged_op(struct 
   10.30      switch ( opcode )
   10.31      {
   10.32      case 0x06: /* CLTS */
   10.33 -        clear_bit(EDF_GUEST_STTS, &ed->ed_flags);
   10.34 -        if ( test_bit(EDF_USEDFPU, &ed->ed_flags) )
   10.35 -            clts();
   10.36 +        (void)do_fpu_taskswitch(0);
   10.37          break;
   10.38  
   10.39      case 0x09: /* WBINVD */
   10.40 @@ -420,17 +437,7 @@ static int emulate_privileged_op(struct 
   10.41          switch ( (opcode >> 3) & 7 )
   10.42          {
   10.43          case 0: /* Write CR0 */
   10.44 -            if ( *reg & X86_CR0_TS )
   10.45 -            {
   10.46 -                set_bit(EDF_GUEST_STTS, &ed->ed_flags);
   10.47 -                stts();
   10.48 -            }
   10.49 -            else
   10.50 -            {
   10.51 -                clear_bit(EDF_GUEST_STTS, &ed->ed_flags);
   10.52 -                if ( test_bit(EDF_USEDFPU, &ed->ed_flags) )
   10.53 -                    clts();
   10.54 -            }
   10.55 +            (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS));
   10.56              break;
   10.57  
   10.58          case 2: /* Write CR2 */
   10.59 @@ -827,14 +834,6 @@ long do_set_trap_table(trap_info_t *trap
   10.60  }
   10.61  
   10.62  
   10.63 -long do_fpu_taskswitch(void)
   10.64 -{
   10.65 -    set_bit(EDF_GUEST_STTS, &current->ed_flags);
   10.66 -    stts();
   10.67 -    return 0;
   10.68 -}
   10.69 -
   10.70 -
   10.71  #if defined(__i386__)
   10.72  #define DB_VALID_ADDR(_a) \
   10.73      ((_a) <= (PAGE_OFFSET - 4))