[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] kernel2: erkennung von vm86 tasks im exception handler



So, nachdem ich mir gestern den ganzen vm86-Code mal wieder erarbeitet habe, glaube ich
jetzt zu verstehen, was da geschieht...

Der einzige Interrupt, der für vm86-Tasks erlaubt ist, ist der GPF. Alle anderen
Interrupts lösen einen GPF aus, anhand des Fehlercodes kann dann erkannt werden, dass
es ursprünglich ein anderer Interrupt war. Irgendwie muss dann dieser andere Interrupt
aber dem normalen im_handler gemeldet werden. Dafür wird im GPF-Handler für vm86-Tasks
(vm86_gpf_entry) ein Stackframe erstellt, der so aussieht, als wäre der andere
Interrupt ausgelöst worden. Damit man dann im Exceptionhandler (handle_exception)
erkennen kann, dass es sich um einen vm86-Task handelte, wird das reservierte Bit 1
im EFLAGS-Feld auf 0 gesetzt (was bei normalen Tasks natürlich nie der Fall ist).

Das VM-Flag kann hierfür nicht verwendet werden. Um in den vm86-Task zurückzukehren,
ist ein Sprung ins vm86-TSS notwendig. Dies geht nur, indem vorher in speziellen Code
(vm86_task_entry) gesprungen wird, der das Backlinkfeld des normalen TSS auf das
vm86-TSS umbiegt und das NT-Flag im EFLAGS-Register setzt, sodass beim iret in das
vm86-TSS gesprungen wird. Daher kann das VM-Flag nicht gesetzt sein, sonst würde
dieser Code ja im vm86-Modus ausgeführt, was nicht so toll wäre.

Das Problem, was sich jetzt tatsächlich auftut, ist, dass der erstellte Stackframe
bei einem Taskwechsel wegen des Interrupts als tatsächlicher Stackframe das
vm86-Threads verwendet wird. Dadurch wird bei einem Wiederaufrufen des Threads zwar
wunderschön in die erwähnte vm86_task_entry-Funktion gesprungen, welche das TSS und
damit den alten Prozessorzustand wiederherstellt, aber gleichzeitig leider auch das
Bit 1 in EFLAGS gelöscht, was eher doof ist. Da müsste ich also nochmal einen
kleinen Fix senden.

Diesen kleinen Fix könnte ich mir aber gleich sparen, weil es natürlich schon ein
bisschen gemogelt ist, dieses Bit zu benutzen, was später jederzeit eine Bedeutung
gewinnen könnte. Deshalb müsste man vm86-Threads sowieso besser irgendwie anders
identifizieren. Da müsste ich mir aber noch irgendwas überlegen... Eine Möglichkeit
wäre vielleicht ein Flag in vm86.c, dass am Ende von vm86_gpf_entry gesetzt wird,
vor dem im_handler-Aufruf, und dann vor dem load_isf_and_return-Aufruf wieder
gelöscht wird. Aber das müsste ich mir auch erstmal genauer ansehen, nicht, dass
im_handler irgendwo so schlau ist und einfach so einen Stackframe lädt...


Max