Autor Thema: Schnellste Möglichkeit des Syscalls  (Gelesen 9762 mal)

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« am: 11. July 2011, 19:21 »
Im Wiki werden Syscalls zumeist mithilfe eines Interrupt implementiert, seltener auch mit der sysenter/sysextit-Instruktion. Beide Methoden halte ich nicht für das wahre. Interrupts prüfen zu viel Unfug vor der Ausführung. Die sysenter/sysextit-Instruktion hingegen ist auf Intel Plattformen beschränkt und stellt zudem einige Ansprüche. Im Englische Wiki wurden noch die Möglichkeit über die Invalid Opcode Fault und über far Jump aufgeführt. Diese beiden Möglickeiten erscheinen mir schon interessanter.

Darum frage ich mal: Welche Vorteile bieten die beiden Varianten und wie lässt sich die far Jump Version einsetzten? Kennt jemand noch andere Syscall Methoden?
« Letzte Änderung: 11. July 2011, 19:31 von Sannaj »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 11. July 2011, 19:37 »
Hallo,

Interrupts sind wirklich nicht die schnellste Variante, dafür aber auf jedem Prozessor einsetzbar. SYSENTER/SYSEXIT sind eine wesentlich schnellere Intel-spezifische Möglichkeit; auf AMD-Prozessoren gibt es die gleichwertige Variante SYSCALL/SYSRET.

Sowohl Windows als auch Linux reservieren eine Page im Speicher, die den CPU-spezifischen Code für einen Syscall enthält; dieser Code wird dann (als far jmp) einfach angesprungen und erledigt den Moduswechsel auf dem jeweils schnellsten Weg. Ein einfacher far jmp ist kein Syscall, da nicht in den Ring 0 gewechselt wird.

Traps (Exceptions) sind Interrupts, die von der CPU ausgelöst werden. Ich behaupte mal, dass die genauso langsam sind wie normale Interrupts. Mit der Variante hat MacOS in der Übergangszeit von m68k auf PPC gearbeitet, indem bei einer Invalid Opcode Exception der m68k-Emulator für den entsprechenden Codeabschnitt angeworfen wurde. Ansonsten funktioniert das wie ein Interrupt, dessen Nummer bekannt ist.

Gruß,
Svenska

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 11. July 2011, 19:54 »
Das blöde ist halt, das sysenter/syscall nicht das selbe ist, oder lässt sich da irgend eine Uniformierung einbauen.

Das mit der Invalid Opcode Exeption hab ich mir auch gedacht, bloß komisch, das manche Systeme wie L4 das einsetzten, wenn das keine Vorteile bietet.

Aber nochmal zu der Möglichkeit mit dem far call (jmp ist ja nur in eine Richtung, hab ich vorhin nicht bedacht), die erscheint mir irgentwie Interessant. Gibt's da nicht ne Möglichkeit far call zu nutzen?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 11. July 2011, 20:14 »
Hallo,

Auch ein far call ändert den Modus nicht. ;-)

Windows und Linux reservieren eine Page im Adressraum jedes Prozesses, wo der prozessorspezifische Code drin ist. Bei der Initialisierung des Kernels wird diese Page dann - je nach Prozessor - mit entsprechendem Code (sysenter, syscall oder interrupt) befüllt. Das geschieht also zur Laufzeit.

Call Gates sind eine Möglichkeit, wenn du stark auf Segmentierung setzt. Wenn du ein Flat-Memory-OS schreibst, wo du keine Segmente hast, ist das aber wieder mit Overhead verbunden, bringt also nichts.

Gruß,
Svenska

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 11. July 2011, 20:18 »
Ah danke jetzt kapier ich das. Was mich verwirrt ist, das man in Linux Assemblerprogrammen Syscalls über Interrupts handelt. Besitzt das System dann zwei Syscallmethoden?

Gruß Sannaj

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 11. July 2011, 20:31 »
Das blöde ist halt, das sysenter/syscall nicht das selbe ist, oder lässt sich da irgend eine Uniformierung einbauen.
Für ein Protected-Mode-OS nimmst du einfach immer sysenter und für ein Long-Mode-OS immer syscall.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 11. July 2011, 20:32 »
und das klappt? ich dachte immer da muss man zwischen intel und amd unterscheiden.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 11. July 2011, 20:42 »
Intel kann sysenter in beiden Modi und syscall nur im LM, AMD kann syscall in beiden Modi und sysenter nur im PM. Es gibt also in jedem Modus einen Befehl, der auf beiden läuft.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 11. July 2011, 20:45 »
Hallo,


ich bin mir nicht ganz sicher aber ich denke das an die Performance von sysenter/syscall ein Call-Gate (für das man dann einen FAR CALL benötigt) nicht ran kommt, erst recht nicht in einem Flat-Memory-OS. Wer wirklich die schnellste Methode will ist auf x86 mit sysenter/syscall IMO auf jeden Fall am besten beraten. Wer maximale Kompatibilität benötigt nutzt dann eben die Methode mit der einen Page in welche der Befehl reingemappt wird der auf der gegebenen CPU am besten funktioniert.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 11. July 2011, 20:56 »
Wenn dafür dann eine Page ausgelagert werden muss, auf die der Syscall zugreift, ist es die langsamste Methode. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 11. July 2011, 21:12 »
Wenn dafür dann eine Page ausgelagert werden muss, auf die der Syscall zugreift, ist es die langsamste Methode. ;)
Ich weiß zwar nicht welche Page Du meinst aber die Spezial-Page mit dem sysenter/syscall gibt es physisch nur ein einziges mal und wird in alle Prozesse identisch eingeblendet so das es sehr unklug wäre gerade diese auszulagern. ;)
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 11. July 2011, 21:23 »
Ja, das wollte ich erst schreiben, bin dann aber zum selben Schluss gekommen. Deswegen habe ich eine andere Page genommen, die ausgelagert werden muss, weil die Syscallpage drinbleibt. Nicht, dass es viel wahrscheinlicher wäre, aber zum Haarespalten gut genug. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 11. July 2011, 21:44 »
aber zum Haarespalten gut genug. ;)
Guter Versuch, aber diesmal nicht. Diesmal bleibe ich standhaft! :evil:
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 11. July 2011, 21:53 »
Nochmal zurück zum far call. Wenn ich in der GDT das Ring 3 Segment über das Ring 0 Segment lege, kann ich doch mit einem far call auf das Ring 0 Segment wechseln und mit far ret wieder zurückkehren.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 11. July 2011, 22:01 »
Hallo,


@Sannaj:
Nein, für einen richtigen x86-PM-Ringwechsel benötigt man schon etwas mehr, entweder ein Call-Gate oder einen Interrupt/Trap.
Um eine andere Berechtigung zu bekommen muss sich auch die CPL ändern und das geht nicht so ohne weiteres sonst wäre es ja eine Sicherheitslücke.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 11. July 2011, 22:07 »
Nein, ein "normaler" Far Call geht nur innerhalb einer Privilegstufe, sonst bekommst du einen GPF. Die Ausnahmen sind Sprünge zu Call Gates und Task Gates oder direkt zu einem TSS. (Weiß grad zufällig jemand, was der Unterschied ist zwischen Task Gate und TSS? Auf den ersten Blick hab ich das im Manual nicht gefunden.)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 11. July 2011, 22:08 »
Und ist das mit der Call Gate schneller als sysenter?

PS: Das mit dem far call ist logisch, sonst könnt man ja den Code als Inhalt der R3-segments laden und dann mit einem far call als r0 code anspringen.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 11. July 2011, 22:11 »
Würde mir sehr wundern, wenn Call Gates schneller wären als sysenter.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 11. July 2011, 22:20 »
Hallo,

Und ist das mit der Call Gate schneller als sysenter?
Nein, ganz sicher nicht.


@taljeth:
Ich rate mal das man ein Task-Gate auch in eine beliebige LDT packen kann und ein TSS immer in der GDT sein muss außerdem kann man einem Gate eine niedrigere Priorität (höheren Ring) geben damit das Gate auch aus weniger privilegierten Ringen benutzt werden kann.


Grüße
Erik


Und danke taljeth das Du das mit dem Haarespalten heute nicht mehr weiter verfolgst. Meine Goldwaage ist derzeit leider, äh, indisponiert. Die turnusmäßige Prüfzertifizierung muss gerade beim TÜV-Kalibrierdienst erneuert werden. Du weißt schon wegen ISO 9001 und so. Nächste Woche oder später mach ich aber gerne wieder mal bei einer richtig zünftigen Haarspalterei mit, versprochen.
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 11. July 2011, 22:25 »
Naja, ein Task Gate verweist ja immer auf ein TSS, insofern hat man sich den GDT-Eintrag damit auch nicht gespart. Dass es was damit zu tun hat, höherprivilegierte Tasks aufzurufen, könnte aber sein.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen