X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fmath-emu%2Ffpu_entry.c;h=a0f1cab20cecd82af9243ec0e33b5f7d27add1fb;hb=refs%2Fheads%2Fvserver;hp=baebe5c08da7522cac347f28cfc1d0c0d7fc35cd;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c index baebe5c08..a0f1cab20 100644 --- a/arch/i386/math-emu/fpu_entry.c +++ b/arch/i386/math-emu/fpu_entry.c @@ -25,7 +25,6 @@ +---------------------------------------------------------------------------*/ #include -#include #include #include @@ -128,7 +127,7 @@ static u_char const type_table[64] = { u_char emulating=0; #endif /* RE_ENTRANT_CHECKING */ -static int valid_prefix(u_char *Byte, u_char **fpu_eip, +static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, overrides *override); asmlinkage void math_emulate(long arg) @@ -140,7 +139,7 @@ asmlinkage void math_emulate(long arg) FPU_REG loaded_data; FPU_REG *st0_ptr; u_char loaded_tag, st0_tag; - void *data_address; + void __user *data_address; struct address data_sel_off; struct address entry_sel_off; unsigned long code_base = 0; @@ -155,10 +154,10 @@ asmlinkage void math_emulate(long arg) RE_ENTRANT_CHECK_ON; #endif /* RE_ENTRANT_CHECKING */ - if (!current->used_math) + if (!used_math()) { finit(); - current->used_math = 1; + set_used_math(); } SETUP_DATA_AREA(arg); @@ -192,7 +191,8 @@ asmlinkage void math_emulate(long arg) math_abort(FPU_info, SIGILL); } - if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) ) + code_descriptor = LDT_DESCRIPTOR(FPU_CS); + if ( SEG_D_SIZE(code_descriptor) ) { /* The above test may be wrong, the book is not clear */ /* Segmented 32 bit protected mode */ @@ -210,11 +210,10 @@ asmlinkage void math_emulate(long arg) if ( code_limit < code_base ) code_limit = 0xffffffff; } - FPU_lookahead = 1; - if (current->ptrace & PT_PTRACED) - FPU_lookahead = 0; + /* Don't run ahead if single-stepping. */ + FPU_lookahead = (FPU_EFLAGS & X86_EFLAGS_TF) == 0; - if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP, + if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP, &addr_modes.override) ) { RE_ENTRANT_CHECK_OFF; @@ -256,8 +255,8 @@ do_another_FPU_instruction: } RE_ENTRANT_CHECK_OFF; - FPU_code_verify_area(1); - FPU_get_user(FPU_modrm, (u_char *) FPU_EIP); + FPU_code_access_ok(1); + FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP); RE_ENTRANT_CHECK_ON; FPU_EIP++; @@ -336,23 +335,23 @@ do_another_FPU_instruction: switch ( (byte1 >> 1) & 3 ) { case 0: - unmasked = FPU_load_single((float *)data_address, + unmasked = FPU_load_single((float __user *)data_address, &loaded_data); loaded_tag = unmasked & 0xff; unmasked &= ~0xff; break; case 1: - loaded_tag = FPU_load_int32((long *)data_address, &loaded_data); + loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data); break; case 2: - unmasked = FPU_load_double((double *)data_address, + unmasked = FPU_load_double((double __user *)data_address, &loaded_data); loaded_tag = unmasked & 0xff; unmasked &= ~0xff; break; case 3: default: /* Used here to suppress gcc warnings. */ - loaded_tag = FPU_load_int16((short *)data_address, &loaded_data); + loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data); break; } @@ -563,7 +562,7 @@ FPU_fwait_done: if (FPU_lookahead && !need_resched()) { FPU_ORIG_EIP = FPU_EIP - code_base; - if ( valid_prefix(&byte1, (u_char **)&FPU_EIP, + if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP, &addr_modes.override) ) goto do_another_FPU_instruction; } @@ -579,16 +578,16 @@ FPU_fwait_done: all prefix bytes, further changes are needed in the emulator code which accesses user address space. Access to separate segments is important for msdos emulation. */ -static int valid_prefix(u_char *Byte, u_char **fpu_eip, +static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, overrides *override) { u_char byte; - u_char *ip = *fpu_eip; + u_char __user *ip = *fpu_eip; *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */ RE_ENTRANT_CHECK_OFF; - FPU_code_verify_area(1); + FPU_code_access_ok(1); FPU_get_user(byte, ip); RE_ENTRANT_CHECK_ON; @@ -634,7 +633,7 @@ static int valid_prefix(u_char *Byte, u_char **fpu_eip, do_next_byte: ip++; RE_ENTRANT_CHECK_OFF; - FPU_code_verify_area(1); + FPU_code_access_ok(1); FPU_get_user(byte, ip); RE_ENTRANT_CHECK_ON; break; @@ -679,13 +678,13 @@ void math_abort(struct info * info, unsigned int signal) #define sstatus_word() \ ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top)) -int restore_i387_soft(void *s387, struct _fpstate *buf) +int restore_i387_soft(void *s387, struct _fpstate __user *buf) { - u_char *d = (u_char *)buf; + u_char __user *d = (u_char __user *)buf; int offset, other, i, tags, regnr, tag, newtop; RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_READ, d, 7*4 + 8*10); + FPU_access_ok(VERIFY_READ, d, 7*4 + 8*10); if (__copy_from_user(&S387->cwd, d, 7*4)) return -1; RE_ENTRANT_CHECK_ON; @@ -725,13 +724,13 @@ int restore_i387_soft(void *s387, struct _fpstate *buf) } -int save_i387_soft(void *s387, struct _fpstate * buf) +int save_i387_soft(void *s387, struct _fpstate __user * buf) { - u_char *d = (u_char *)buf; + u_char __user *d = (u_char __user *)buf; int offset = (S387->ftop & 7) * 10, other = 80 - offset; RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE, d, 7*4 + 8*10); + FPU_access_ok(VERIFY_WRITE, d, 7*4 + 8*10); #ifdef PECULIAR_486 S387->cwd &= ~0xe080; /* An 80486 sets nearly all of the reserved bits to 1. */ @@ -741,7 +740,8 @@ int save_i387_soft(void *s387, struct _fpstate * buf) S387->fcs &= ~0xf8000000; S387->fos |= 0xffff0000; #endif /* PECULIAR_486 */ - __copy_to_user(d, &S387->cwd, 7*4); + if (__copy_to_user(d, &S387->cwd, 7*4)) + return -1; RE_ENTRANT_CHECK_ON; d += 7*4;