#10532 closed defect (fixed)
Incorrect order of task switching
回報者: | Yury Popov | 負責人: | |
---|---|---|---|
元件: | other | 版本: | VirtualBox 4.1.14 |
關鍵字: | 副本: | ||
Guest type: | other | Host type: | other |
描述
In Intel specifications (7.3), we can see:
- Saves the state of the current (old) task in the current task’s TSS.
…
- Loads the task register with the segment selector and descriptor for the new
task's TSS.
But, in VirtualBox code, the order is reversed: TSS registers & segments loads BEFORE save old task state.
更動歷史 (18)
跟進: 7 comment:2 13 年 前 由 編輯
I see no instance where state from the new TSS is loaded into actual registers before those same registers are saved into the old TSS. If you do, please point out the exact source lines and variable names. Even better, provide a testcase showing how the behavior differs from a real CPU.
You may be confused by the fact that the new TSS is loaded from memory (but not into the CPU) before saving he current state. That is done to avoid a situation where the old state is saved but new state can't actually be loaded.
comment:4 13 年 前 由 編輯
狀態: | closed → reopened |
---|---|
處理結果: | invalid |
Specifications of intel processors is declared save before load. Switch to same TSS is really easy way to initialize multitasking, and every systems that I tested (Celeron D, Pentium M, Atom, Core i5, and vmWare) saves current task state first.
comment:5 13 年 前 由 編輯
OK... please provide a testcase, or even better, point to some commercial operating system which uses this technique.
And out of curiosity, where does the Intel specification define the behavior when switching to the same TSS?
comment:6 13 年 前 由 編輯
The testcase is very simple:
xor eax, eax mov ax, [main_TSS_d] ; Main TSS descriptor ID in GDT. TSS is now empty (zero-filled) but CR3 shl eax, 3 ltr ax ; Loading current task ID mov [_tssd], ax ; Replacing segment in "far jmp" add eax, [gdt] and byte [eax+5], 11111101b ; Clearing 'busy' flag db 0xEA ; Equals to JMP far 0x0000:0x00000000 (task segment replaced before) dd 0 _tssd: dw 0 ; Segment ID _mtstart: or byte [eax+5], 10b ; Setting 'busy' flag, now we are in multitask mode
This code I got from this manual (Russian, with some fixes). This is work perfectly at any real x86 processor.
There are full code of my OS (with pre-built kernel can be loaded from GRUB, build script for Windows and commented fix for VBox).
Switching to same TSS is not defined, but in specification (chapter 7.3: Task Switching) exists this fragment:
- Saves the state of the current (old) task in the current task’s TSS. The processor finds the base address of the current TSS in the task register and then copies the states of the following registers into the current TSS: all the general-purpose registers, segment selectors from the segment registers, the temporarily saved image of the EFLAGS register, and the instruction pointer register (EIP).
...
- The TSS state is loaded into the processor. This includes the LDTR register, the PDBR (control register CR3), the EFLAGS register, the EIP register, the generalpurpose registers, and the segment selectors. A fault during the load of this state may corrupt architectural state.
So, same bug was found in QEMU code.
comment:7 13 年 前 由 編輯
Replying to michaln:
That is done to avoid a situation where the old state is saved but new state can't actually be loaded.
AMD specifications (12.3.2)
The current-task state is saved in the TSS. This includes the next-instruction pointer (EIP), EFLAGS, the general-purpose registers, and the segment-selector registers.
Up to this point, any exception that occurs aborts the task switch without changing the processor state. From this point forward, any exception that occurs does so in the context of the new task. If an exception occurs in the context of the new task during a task switch, the processor finishes loading the new-task state without performing additional checks. The processor transfers control to the #TS handler after this state is loaded, but before the first instruction is executed in the new task. When a #TS occurs, it is possible that some of the state loaded by the processor did not participate in segment access checks. The #TS handler must verify that all segments are accessible before returning to the interrupted task.
跟進: 10 comment:8 13 年 前 由 編輯
Could you please provide a bootable ISO image or perhaps a floppy image of your OS (without the workaround)?
comment:9 13 年 前 由 編輯
Oh, and FYI... no modern operating system that we know of uses TSS task switching. Operating systems initialize a TSS, but never switch. In 64-bit mode, TSS task switching isn't allowed at all.
For that reason, Intel does not support task switching with VT-x, which means that in a virtualized OS, task switching using TSSs will be very significantly slower than other methods.
comment:10 13 年 前 由 編輯
Replying to michaln:
Could you please provide a bootable ISO image or perhaps a floppy image of your OS (without the workaround)?
Yes. Here is iso image with menu - fixed kernel or kernel without fix. At real PCs both works identically.
跟進: 12 comment:11 13 年 前 由 編輯
I removed the last comment because it contained an inappropriate language.
comment:12 13 年 前 由 編輯
Replying to frank:
I removed the last comment because it contained an inappropriate language.
OK, sry about it... but...
Guys, what are you creating? Virtual Machine with full x86 emulation? Or VM for "commercial OSes" (MS Win)? If second, just rename your project and its description - and I will have no questions to you. But, if VirtualBox is full x86 emulator - do it as specifications define.
comment:13 13 年 前 由 編輯
I would say that VirtualBox is closer to the second than the first. We aim at making specific usage cases, mainly those of our customers, work, rather than trying to perfectly emulate an x86-based PC system. I'm not quite sure why the name and description of our project suggests to you that we are trying to achieve perfect emulation. If it is the term "full virtualiser" (not emulator!) this is simply intended to mean that we run unmodified PC operating systems rather than paravirtualised ones.
comment:14 13 年 前 由 編輯
Wikipedia's description means what VBox is
an x86 virtualization software package
comment:15 13 年 前 由 編輯
Wikipedia does not define what VirtualBox is or isn't. Wikipedia merely offers more or less inaccurate approximations.
comment:16 13 年 前 由 編輯
OK, then, please visit main page of your official site.
VirtualBox is a powerful x86 and AMD64/Intel64 virtualization product
What about it?
comment:17 13 年 前 由 編輯
I don't see any inaccuracy there. We do not claim to do perfectly accurate emulation, just that we support "a large number of guest operating systems including but not limited to Windows (NT 4.0, 2000, XP, Server 2003, Vista, Windows 7), DOS/Windows 3.x, Linux (2.4 and 2.6), Solaris and OpenSolaris, OS/2, and OpenBSD". However, I would rather not spend any longer discussing whether our home page is slightly unclear. If you would really like to discuss that you could always open a topic on the user forums to see what other people think, but given the low number of complaints we have had so far I don't think we are likely to change it.
Perhaps it would be more productive to return to the actual problem you were experiencing if Michal thinks that it is something he has time to look at. I'm afraid though that this sort of off-topic argument about what VirtualBox is or isn't may not encourage people to help you.
comment:18 11 年 前 由 編輯
priority: | major → minor |
---|---|
狀態: | reopened → closed |
處理結果: | → fixed |
This should be fixed in VirtualBox 4.3. It definitely fixes problems with Turbo Debugger 286 which uses an Eclipse/Ergo DOS extender that relies on the task switch implementation (loads a TSS from current state).
Wrong line from specifications is provided. Right is: