[Kos-dev] double fault fonctionnel !

Christophe Avoinne (Club-Internet) kos-dev@enix.org
Sun, 1 Apr 2001 22:05:44 +0200


----- Original Message -----
From: "Thomas Petazzoni" <thomas.petazzoni@ifrance.com>
To: <kos-dev@enix.org>
Sent: Sunday, April 01, 2001 7:43 AM
Subject: Re: [Kos-dev] double fault fonctionnel !


> > Ah je me disais quand même ! :))))))))))
>
> bin voui... hey quand meme on est pas des blaireaux !
>
> > Bon c'est une bonne chose de validée. Reste qu'il y a un cas à tester
avant
> > de se lancer dans les piles dynamiques et autre : que se passe-t-il si
c'est
> > un IRQ qui provoque le #DF ? là il s'agit d'une interruption externe,
> > autrement dit, ce n'est pas le code interrompu qui est fautif du #DF. Or
> > l'EIP dans le TSS system doivent être celui du code interrompu et non
celui
> > du handler. Je présens que cet IRQ va être perdu et jamais exécuté, ce
qui
> > est un gros problème à mon avis si on ne peut pas le détecter.
>
> ouais oula c'est complique tout ca.... tres complique.
>
> > 0: mov    $DEADBEEF,%esp // attention boucle infini, il ne faut pas que
le
> > handler #DF alloue dynamiquement la pile !!!
> >     hlt
> >     jmp 0b
>
>
> d'accord je vois.
>
> > le timer 0 devrait afficher une autre barre tournante d'une autre
couleur à
> > chacune de ses exécutions.
> > Comme vous pouvez noter, on crée intentionnellement une pile invalide
avec
> > la signature 0xDEADBEEF juste avant l'exécution de l'instruction "hlt"
qui
> > devrait attendre jusqu'à ce qu'un signal d'interruption ait lieu (en
> > particulier celui du timer 0). Un #DF apparaîtra forcément qui donnera
> > provisoirement sa pile pour laisser continuer l'exécution.
>
> ton test est tellement complique qu'on risque avant de se retrouver avec
> la vraie reponse de 50000 bugs... c'est grave chiant.
> le hic c'est qu'on a pas trop le choix en fait. c un peu emmerdant
> grave. enfin bon je vais essayer, voir ce que ca donne.
>

Mon test consiste à visualiser une barre tournante indiquant ou non si le
handler du timer 0 s'exécute après la réparation de la pile système via un
#DF.

Ce qui se passe :
1) la pile est invalidée avec la signature 0xDEADBEEF.
2) on tombe sur "hlt", le CPU est en pause.
3) un signal IRQ #0 intervient.
4) le CPU se réveille et tente d'exécuter l'int 32.
5) la pile étant invalide, un #DF s'exécute et place une pile valide
6) on reprend le point 1)

On est dans une boucle infini, où l'IRQ se trouvera toujours avec une pile
système invalide.

Dans le cas du #PF qui donne lieu au #DF, on s'apperçoit que le #PF est
irrémédiablement perdu puisque du #DF on revient directement à l'instruction
fautive, et qu'il n'y a pas tentative de la part du CPU de lancer un #PF
juste après le #DF. En fait il y a eu une transition directe du #PF en #DF.
D'ailleurs, quand on est dans le #DF, on ne sait pas quelle est l'exception
à l'origine de son appel. On ne le sait que parce que on suppose qu'il y a
que le #PF qui le provoque et en consultant la validité de l'ESP, mais pas
de code erreur donné par le CPU (toujours 0).

> > Pour être honnête, je crois que le 2°) est le plus probable.
>
> attends tu vas me faire coder un truc qui a de fortes chances de ne pas
> marcher... hum hum... douteux comme machin. le pb c'est qu'on ne sait
> pas ce qu'on doit obtenir : avec le double fault, on voulait que ca
> revienne dans le thread, mais la on sait pas si on a pas la barre
> tournante si c vraiment a cause du DF ou si c'est pour une autre
> raison...

Si on remplace le #PF par un IRQ (qui va forcément entraîner un #PF puis un
#DF), il n'est donc possible non plus a priori de retourner à l'exécution du
IRQ au même titre que pour le handler #PF. C'est pourquoi je crois que le
IRQ sera perdu.

>
> > Si on veut vraiment pouvoir exécuter l'IRQ, il faut arriver à déterminer
> > quel IRQ a eu lieu. Pour cela il nous faudrait consulter le masque des
IRQ
> > en état d'attente (pending IRQ) et repérer l'IRQ dans le bitmap obtenu.
On
> > simule alors un appel d'interruption à cet IRQ depuis le #DF.
>
> c'est a dire, pourrais-tu etre plus explicite ?
>

Bien tu as des registres de ports (0x20/0x21) qui permettent de configurer
le PIC.

Ces registres permettent également de consulter lors d'un appel IRQ quel est
le numéro d'IRQ en cours de traitement. Consulte la documentation et tu
verras que tu peux connaître le masque des IRQ dont les signaux ont été
activés. On peut se servir de ça dans le handler #DF pour déterminer si un
IRQ en est responsable. Dis comme ça, ça a l'air facile, mais c'est plus
compliqué en fait à déterminer si oui on non l'IRQ est responsable du #DF. A
mon avis, il faudrait que je creuse plus en profondeur la question avant de
continuer.

Christophe.