unsigned short ip, sp; 
unsigned short ip, sp, orig_flags; 
void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code){	unsigned char opcode;	unsigned char __user *csp;	unsigned char __user *ssp;	unsigned short ip, sp;	int data32, pref_done;#define CHECK_IF_IN_TRAP \	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \		newflags |= TF_MASK#define VM86_FAULT_RETURN do { \	if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \		return_to_32bit(regs, VM86_PICRETURN); \	return; } while (0)	csp = (unsigned char __user *) (regs->cs << 4);	ssp = (unsigned char __user *) (regs->ss << 4);	sp = SP(regs);	ip = IP(regs);	data32 = 0;	pref_done = 0;	do {		switch (opcode = popb(csp, ip, simulate_sigsegv)) {			case 0x66:      /* 32-bit data */     data32=1; break;			case 0x67:      /* 32-bit address */  break;			case 0x2e:      /* CS */              break;			case 0x3e:      /* DS */              break;			case 0x26:      /* ES */              break;			case 0x36:      /* SS */              break;			case 0x65:      /* GS */              break;			case 0x64:      /* FS */              break;			case 0xf2:      /* repnz */       break;			case 0xf3:      /* rep */             break;			default: pref_done = 1;		}	} while (!pref_done);	switch (opcode) {	/* pushf */	case 0x9c:		if (data32) {			pushl(ssp, sp, get_vflags(regs), simulate_sigsegv);			SP(regs) -= 4;		} else {			pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);			SP(regs) -= 2;		}		IP(regs) = ip;		VM86_FAULT_RETURN;	/* popf */	case 0x9d:		{		unsigned long newflags;		if (data32) {			newflags=popl(ssp, sp, simulate_sigsegv);			SP(regs) += 4;		} else {			newflags = popw(ssp, sp, simulate_sigsegv);			SP(regs) += 2;		}		IP(regs) = ip;		CHECK_IF_IN_TRAP;		if (data32) {			set_vflags_long(newflags, regs);		} else {			set_vflags_short(newflags, regs);		}		VM86_FAULT_RETURN;		}	/* int xx */	case 0xcd: {		int intno=popb(csp, ip, simulate_sigsegv);		IP(regs) = ip;		if (VMPI.vm86dbg_active) {			if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] )				return_to_32bit(regs, VM86_INTx + (intno << 8));		}		do_int(regs, intno, ssp, sp);		return;	}	/* iret */	case 0xcf:		{		unsigned long newip;		unsigned long newcs;		unsigned long newflags;		if (data32) {			newip=popl(ssp, sp, simulate_sigsegv);			newcs=popl(ssp, sp, simulate_sigsegv);			newflags=popl(ssp, sp, simulate_sigsegv);			SP(regs) += 12;		} else {			newip = popw(ssp, sp, simulate_sigsegv);			newcs = popw(ssp, sp, simulate_sigsegv);			newflags = popw(ssp, sp, simulate_sigsegv);			SP(regs) += 6;		}		IP(regs) = newip;		regs->cs = newcs;		CHECK_IF_IN_TRAP;		if (data32) {			set_vflags_long(newflags, regs);		} else {			set_vflags_short(newflags, regs);		}		VM86_FAULT_RETURN;		}	/* cli */	case 0xfa:		IP(regs) = ip;		clear_IF(regs);		VM86_FAULT_RETURN;	/* sti */	/*	 * Damn. This is incorrect: the 'sti' instruction should actually	 * enable interrupts after the /next/ instruction. Not good.	 *	 * Probably needs some horsing around with the TF flag. Aiee..	 */	case 0xfb:		IP(regs) = ip;		set_IF(regs);		VM86_FAULT_RETURN;	default:		return_to_32bit(regs, VM86_UNKNOWN);	}	return;simulate_sigsegv:	/* FIXME: After a long discussion with Stas we finally	 *        agreed, that this is wrong. Here we should	 *        really send a SIGSEGV to the user program.	 *        But how do we create the correct context? We	 *        are inside a general protection fault handler	 *        and has just returned from a page fault handler.	 *        The correct context for the signal handler	 *        should be a mixture of the two, but how do we	 *        get the information? [KD]	 */	return_to_32bit(regs, VM86_UNKNOWN);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/5fd75ebb1a58c1a3c9e3d9fdf75ce7286b79bb74/vm86.c/buggy/arch/i386/kernel/vm86.c