[Kos-dev] Double fault avec bit NT a 1

Christophe Avoinne (Club-Internet) kos-dev@enix.org
Sat, 24 Mar 2001 16:16:22 +0100


Salut !!! une bonne nouvelle je pense pour aujourd'hui ! :)

----- Original Message -----
From: "Thomas Petazzoni" <thomas.petazzoni@ifrance.com>
To: <kos-dev@enix.org>
Sent: Friday, March 23, 2001 8:08 PM
Subject: [Kos-dev] Double fault avec bit NT a 1


> back link for current TSS is 0x28, stack addr 0x5c9fff, eflags 0x4202
> Double fault handler is going to return with new stack addr 0x5b8fff and
> with eip 0x5d8448
>

J'ai beaucoup de soucis...

1) tes pointeurs de pile ont des valeurs très louches. Ils devraient être
alignés sur des mots 32-bit au minimum. Ils devraient donc être
respectivement 0x5C9FFC et 0x5B9000. Je ne te dis pas pour les caches du CPU
à cause de ce mauvais alignement dans la pile...

=> bug mineur qui n'empêche pas de tourner le CPU, dont je suspecte
d'utiliser le même procédé de création de la pile système qu'en 2).

2) j'ai regardé ta routine doublefault_handler, et j'ai trouvé ceci :

  new_stack_addr = get_physical_page();
  new_stack_addr += PAGE_SIZE-1;

Ca me gène énormement, car j'aurais plutôt envie de lire "... += PAGE_SIZE;
". En effet, quand tu fais "push %0", le CPU fait : " sub $4,%%esp; mov
%0,(%%esp) ". Et puis ce n'est pas -1 mais au moins -4 pour être multiple
sur des mots 32-bit.

=> bug mineur qui n'empêche de tourner le CPU, que je suspecte .

3) quand tu crées des threads, tu dois avoir empiler certaines valeurs
spéciaux, ne serait ce que pour assurer correctement la terminaison de ce
thread, par exemple. En effet, j'ai vu qu'il suffisait de faire une simple
routine et de l'exécuter en créant un thread. Donc à la terminaison de cette
routine, on doit logiquement aller sur une routine spéciale qui tue le
thread correctement. Or ce doublefault n'empile rien de ces valeurs... donc
je n'ose pas imaginer comment va terminer ce thread après le fatidique
"retn" qui ne trouvera pas son adresse de retour sur la nouvelle pile.

=> bug majeur qui empêchera la terminaison des threads après un #DF.

Donc sois vigilant !

> cette valeur de eflags semble tout a fait correcte, mais ca ne
> fonctionne toujours pas, il genere encore des double fault a l'infini,
> avec un nouveau eflags :
>
> back link for current TSS is 0x28, stack addr 0x5c9fff, eflags 0x206
> Double fault handler is going to return with new stack addr 0x5b7fff and
> with eip 0x5d8448
>

Et enfin, le truc qui évidemment nous conduit aux doublefaults en chaîne :

  system_tss = get_system_tss();
  system_tss->esp0 = new_stack_addr;
  cpu_context->eip = system_tss->eip;

Il y a un oubli très très très important...

Fallait mettre :
  system_tss->esp   =
  system_tss->esp0 = new_stack_addr;

Parce que là tu repartais du #DF sans changer l'esp dans le TSS system, d'où
ton "stack addr 0x5c9fff" invariant et bien sûr des #DF à n'en plus finir !

Allez, un soucis de moins de ce côté là ;)

Hlide