problem with v86 mode and INT n instruction

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
aladdin

problem with v86 mode and INT n instruction

Post by aladdin »

I want to add vm86 support for my OS.
I have a simple but working multitasking implementation and can tun tasks with
pl3.
here is the code I'm using to run a 16bits program in vm86, this program is
loaded at linear address 0x90000.

my context initialisation code for the vm86 task is :

Code: Select all

v86t._ldtss=0;
v86t._t=0;
v86t._iomapaddr=sizeof(struct _tss);
v86t._cr3 = (u32)_PD_ADDR_;
v86t._fs = xtss[i]._gs = 0;
v86t._ds = 0x0;
xtss[i]._es = 0;
v86t._ss =0x9000;
v86t._cs=0x9000;
v86t._esp=(u32)&task_stack[3];
v86t._ss0=0x10;
v86t._esp0=(u32)&pl0_stack[3];
v86t._eflags=0x23202;
v86t._eip=0;
v86t._iomapaddr point to a bitmap table with 8132 bytes containing zeroes
except the last byte which contain 0xFF.



so... when I load and run this 16bits code

Code: Select all

[BITS 16]
[section .text]
mov ax, 0xDEAD
mov bx, 0xDEAD
mov cx, 0xDEAD
mov dx, 0xDEAD
jmp $
averything works well, and bochs report that i'm running in v8086 mode and ax,
bx, cx, dx regesters contains 0xDEAD


but when I try the same code with a call to an int n instruction :

Code: Select all

 [BITS 16]
 [section .text]
 mov ax, 0xDEAD
 mov bx, 0xDEAD
 mov cx, 0xDEAD
 mov dx, 0xDEAD
 int 3
 jmp $
 
I get a page fault with paging enabled and if i disable paging bochs hangs
with a lot of "write beyond limit" messages.


I tried the same code with IOPL=0 and get the same error.

I folowwed everythink in intel manual except what they called "Software
interrupt redirection bit map"... do you think this is the source of my
problem ?
and how can I fix it ?
Dreamsmith

Re:problem with v86 mode int INT n instruction

Post by Dreamsmith »

From the IA-32 Intel Architecture Software Developer's Manual, Volume 3: System Programming Guide
When the processor receives a software interrupt (an interrupt generated with the INT n instruction) while in virtual-8086 mode, it can use any of six different methods to handle the interrupt.
Which method are you attempting to use? I would recommend Method 2 as the easiest one to setup, and it's also backwards compatible all the way to the original 386. I see that you're setting the IOPL to 3, so you must be trying method 1, 4, or 5, in which case it's either calling the protected mode interrupt handler in question (rather than the GPF handler), or the 8086 mode one if you've set the software interrupt bitmap appropriately. You can try that if you want, but it's a lot trickier to setup correctly -- I'd get your monitor working using method 2 first, then try one of the more complicated methods. To use method 2, set your IOPL to 0, then make sure your GPF handler knows how to properly interpret the INT instruction when it's called/switched to.

What are you doing when you receive the GPF?
aladdin

Re:problem with v86 mode int INT n instruction

Post by aladdin »

the problem is that I get a page fault instead of GPF, whant I use IOPL to 0 or 3.
and the error code returned from page fault handler is 2, whitch mean that some code with pl0 is attempting to write to somewhere in memory, and this occure when i attemp to do an INT n instruction.
but the code works correctly when there is no INT n instruction (and no other unhandled instruction of corse).

so can you tell me what can cause the #PF while calling an interrupt under v8086 mode ?
Dreamsmith

Re:problem with v86 mode int INT n instruction

Post by Dreamsmith »

If you're using QEMU, you'll get a page fault instead of a GPF due to a bug in QEMU. You can avoid it (while exposing your OS to serious security flaws) by setting the USER bit on the page table entries that cover your V86 task's TSS. If you're getting this under Bochs or on real hardware, make sure you've mapped the appropriate pages correctly in the v86 task's page table. And your normal TSS too, of course.
aladdin

Re:problem with v86 mode int INT n instruction

Post by aladdin »

the problem occure under bochs and on real pc
and my v86 task is running in the first MB of memory, which is direct mapped to the first MB of physical memory, is this correct ? or i must do something else ?
Dreamsmith

Re:problem with v86 mode int INT n instruction

Post by Dreamsmith »

aladdin wrote: the problem occure under bochs and on real pc
and my v86 task is running in the first MB of memory, which is direct mapped to the first MB of physical memory, is this correct ? or i must do something else ?
Is your task's TSS also mapped into the first MB of memory? If not, did you also map pages that contain its TSS into its page tables? And the pages that contain your kernel's TSS? It needs access to these in order to accomplish a task switch at GPF time -- if they aren't available, you're going to cause a page fault in the process of trying to process the GPF...
aladdin

Re:problem with v86 mode int INT n instruction

Post by aladdin »

Is your task's TSS also mapped into the first MB of memory?
do you mean that also TSS structur must be in the first MB ? if this is the question... the answer is yes, all my system tables (GDT, IDT, TSS ...) are stored between 0x80000 and 0x90000 .

I'm using a very simple paging :
the same page table is used in both kernel and vm86 task
this page table maps the first 4MB to first physical 4MB (as direct mapped).

It needs access to these in order to accomplish a task switch at GPF time -- if they aren't available, you're going to cause a page fault in the process of trying to process the GPF...
the page fault occure at addresse 0x20001027, and all my TSSs are between 0x80000 and 0x90000, so I don't think this is the problem.

but there is something strange, I noticed that bochs gives a lot of "write beyond limit" messages before the page fault.
and there is more messages wen I give more stack to the task.
can stack have something to do with INT n instruction in virtual mode ???
Dreamsmith

Re:problem with v86 mode int INT n instruction

Post by Dreamsmith »

aladdin wrote:can stack have something to do with INT n instruction in virtual mode ???
Absolutely, in any mode. One of the first things that happens during the processing of any interrupt or exception is several writes to the stack.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:problem with v86 mode int INT n instruction

Post by Candy »

Dreamsmith wrote:
aladdin wrote:can stack have something to do with INT n instruction in virtual mode ???
Absolutely, in any mode. One of the first things that happens during the processing of any interrupt or exception is several writes to the stack.
For the record, switching to a different task (TSS / task gate) happens before these pushes.

You can figure out how to handle a stack exception right?


On AMD64's this step is replaced by switching to a different indicated stack. See also AMD64 docs for that.
aladdin

Re:problem with v86 mode int INT n instruction

Post by aladdin »

but the problem occure only with vm86 tasks when they use instructions like (int, iiret ...)
other tasks works well in pl 3.

I noticed another think,
when i add this line to my 8086 program I get the same error (Page fault)

Code: Select all

mov dx, [0xFFFF]
but the page fault don't occure when I use a value below 0xFFFF (0xFFFE works well). ???

I think the main relationship between int n and mov dx, [0xFFFF], is the attemp to read in memory above real-mode segment limit....
If this is true can someone explain me what Is supposed to happen in this case, and how to handle it (to avoid the page fault and get GPF instead)
Dreamsmith

Re:problem with v86 mode and INT n instruction

Post by Dreamsmith »

Well, a page fault can only occur if an error is detected during linear to physical address translation. The error code will tell you whether it was caused by a page not present or a protection violation, and the address that was the target of the operation. This is invariably true. If it says an attempt was made to write to a non-present page covering address 0x20001027, then that's what's happened -- the trick is figuring out what's attempting to write there and why.

During a task switch, the processor may access up to four segments, an error in any of which can cause a page fault. If the fault occurs when saving the state of the original task in the task's TSS, or when reading the GDT to locate the TSS descriptor of the new task, the exception will be generated in the context of the old task. If the fault occurs while reading the TSS or LDT of the new task, the exception is generated in the context of the new task. Where does your CS/EIP point to when the error occurs?
aladdin

Re:problem with v86 mode and INT n instruction

Post by aladdin »

I dumped memory where EIP point, and found that eip point to a data zone (EIP is pointing to a character in a string message in my kernel).
and it allways point there (+/- some character), when the fault occure.
I'll become crazy (?_O)!!
Dreamsmith

Re:problem with v86 mode and INT n instruction

Post by Dreamsmith »

aladdin wrote:I'll become crazy (?_O)!!
Heh, I know the feeling. I just love it when my code jumps into the middle of data, leaving no clue as to where it came from. Maybe the INTERCAL "COME FROM" statement isn't such a bad idea, at least then you always know how you got there. ;)

It is possible your V86 task is clobbering your ordinary task's TSS? If the GPF is performing a task switch back to your ordinary task, but the saved CS/EIP was corrupted, you could wind up anywhere...
aladdin

Re:problem with v86 mode and INT n instruction

Post by aladdin »

after reading some docs I think that the problem comes from, my esp0 and ss0 values, but I don't found any document or tutorial telling what i must put into these records (esp0, esp1, esp2 and esp), so can any one give me a link to a tutorial or document, or .... a simple working example that switch to vm86.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:problem with v86 mode and INT n instruction

Post by Pype.Clicker »

ss0:esp0 should point towards a memory region that you can use as stack when processing an exception/interrupt from user mode.
Post Reply