public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Stas Sergeev <stssppnn@yahoo.com>
To: linux-kernel@vger.kernel.org
Subject: [patch] vm86: Handle multiply prefixes
Date: Sun, 28 Jul 2002 20:13:38 +0400	[thread overview]
Message-ID: <3D441832.10506@yahoo.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 399 bytes --]

Hello.

Problem:
Currently v86 monitor doesn't
handle multiply prefixes.
For example, pushfd can be coded
as 66 9c which is handled correctly,
but also as 67 66 9c
(winnt.exe does this) which is not
handled.

The attached patch is intended to
fix the problem. With it applied,
dosemu can run winnt.exe (Windows NT
Setup), otherwise it crashes.
The patch is against the latest
2.4.19-pre-ac kernels.

[-- Attachment #2: vm86_pref.diff --]
[-- Type: text/plain, Size: 4410 bytes --]

--- linux/arch/i386/kernel/vm86.c	Sat Jun 15 19:46:46 2002
+++ linux/arch/i386/kernel/vm86.c	Fri Jul 26 14:25:35 2002
@@ -502,8 +508,9 @@
 
 void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
 {
-	unsigned char *csp, *ssp;
+	unsigned char *csp, *ssp, opcode;
 	unsigned short ip, sp;
+	int data32, pref_done;
 
 #define CHECK_IF_IN_TRAP \
 	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
@@ -518,70 +525,63 @@
 	sp = SP(regs);
 	ip = IP(regs);
 
-	switch (popb(csp, ip, simulate_sigsegv)) {
+	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);
 
-	/* operand size override */
-	case 0x66:
-		switch (popb(csp, ip, simulate_sigsegv)) {
+	switch (opcode) {
 
-		/* pushfd */
-		case 0x9c:
+	/* pushf */
+	case 0x9c:
+		if (data32) {
 			pushl(ssp, sp, get_vflags(regs), simulate_sigsegv);
 			SP(regs) -= 4;
-			IP(regs) += 2;
-			VM86_FAULT_RETURN;
-
-		/* popfd */
-		case 0x9d:
-			{
-			unsigned long newflags=popl(ssp, sp, simulate_sigsegv);
-			SP(regs) += 4;
-			IP(regs) += 2;
-			CHECK_IF_IN_TRAP;
-			set_vflags_long(newflags, regs);
-			VM86_FAULT_RETURN;
-			}
-
-		/* iretd */
-		case 0xcf:
-			{
-			unsigned long newip=popl(ssp, sp, simulate_sigsegv);
-			unsigned long newcs=popl(ssp, sp, simulate_sigsegv);
-			unsigned long newflags=popl(ssp, sp, simulate_sigsegv);
-			SP(regs) += 12;
-			IP(regs) = (unsigned short)newip;
-			regs->cs = (unsigned short)newcs;
-			CHECK_IF_IN_TRAP;
-			set_vflags_long(newflags, regs);
-			VM86_FAULT_RETURN;
-			}
-		/* need this to avoid a fallthrough */
-		default:
-			return_to_32bit(regs, VM86_UNKNOWN);
+		} else {
+			pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);
+			SP(regs) -= 2;
 		}
-
-	/* pushf */
-	case 0x9c:
-		pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);
-		SP(regs) -= 2;
-		IP(regs)++;
+		IP(regs) = ip;
 		VM86_FAULT_RETURN;
 
 	/* popf */
 	case 0x9d:
 		{
-		unsigned short newflags=popw(ssp, sp, simulate_sigsegv);
-		SP(regs) += 2;
-		IP(regs)++;
+		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;
-		set_vflags_short(newflags, regs);
+		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) += 2;
+		IP(regs) = ip;
 		if (VMPI.vm86dbg_active) {
 			if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] )
 				return_to_32bit(regs, VM86_INTx + (intno << 8));
@@ -593,20 +593,34 @@
 	/* iret */
 	case 0xcf:
 		{
-		unsigned short newip=popw(ssp, sp, simulate_sigsegv);
-		unsigned short newcs=popw(ssp, sp, simulate_sigsegv);
-		unsigned short newflags=popw(ssp, sp, simulate_sigsegv);
-		SP(regs) += 6;
+		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;
-		set_vflags_short(newflags, regs);
+		if (data32) {
+			set_vflags_long(newflags, regs);
+		} else {
+			set_vflags_short(newflags, regs);
+		}
 		VM86_FAULT_RETURN;
 		}
 
 	/* cli */
 	case 0xfa:
-		IP(regs)++;
+		IP(regs) = ip;
 		clear_IF(regs);
 		VM86_FAULT_RETURN;
 
@@ -618,7 +632,7 @@
 	 * Probably needs some horsing around with the TF flag. Aiee..
 	 */
 	case 0xfb:
-		IP(regs)++;
+		IP(regs) = ip;
 		set_IF(regs);
 		VM86_FAULT_RETURN;
 

                 reply	other threads:[~2002-07-28 16:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3D441832.10506@yahoo.com \
    --to=stssppnn@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stas.orel@mailcity.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox