SMP : IDT et GDT – Linux
Un petit post rapide qui fait suite (ou non) à d’autres billets qu’on peut trouver sur ce même blog, juste un bout de code permettant de récupérer l’IDT et la GDT sur chaque processeur (si tant est qu’il y en ait plusieurs évidement), mais sous Linux.
#define _GNU_SOURCE #define __USE_GNU #include <errno.h> #include <stdio.h> #include <sched.h> struct dt_struct { unsigned short limit; unsigned long base; } __attribute__((packed)); unsigned int get_sidt (void) { struct dt_struct idt; asm volatile ("sidt %0\t\n" : "=m"(idt)); return idt.base; } unsigned int get_sgdt (void) { struct dt_struct gdt; asm volatile ("sgdt %0\t\n" : "=m"(gdt)); return gdt.base; } int main (void) { int result = 0, cpu = 0, cpu2; cpu_set_t cs, cs2; if (sched_getaffinity (getpid (), sizeof (cs), &cs) != 0) { printf ("sched_getaffinity() failed : %m\n"); return -1; } while (CPU_COUNT (&cs) != 0) { if (CPU_ISSET (cpu, &cs)) { CPU_ZERO (&cs2); CPU_SET (cpu, &cs2); if (sched_setaffinity (getpid (), sizeof (cs2), &cs2) != 0) { printf ("setaffinity(%d) failed: %m\n", cpu); result = 1; } else { cpu2 = sched_getcpu (); if (cpu2 == -1 && errno == ENOSYS) { puts ("getcpu syscall not implemented"); return -1; } if (cpu2 != cpu) { printf ("getcpu results %d not possible\n", cpu2); result = 1; } } printf ("CPU %d\nIDT : 0x%08x\nGDT : 0x%08x\n\n", cpu, get_sidt(), get_sgdt()); CPU_CLR (cpu, &cs); } ++cpu; } return 0; }
Réfs:
http://linux.die.net/man/2/sched_getaffinity
http://www.linux.com/learn/docs/man/2479-cpucount3
https://www.codeblog.org/viewsrc/glibc-2.6.1/sysdeps/unix/sysv/linux/tst-getcpu.c
http://lkml.org/lkml/2007/5/10/578
etc.
























[...] l’instruction SIDT sur ce cœur. Cette instruction est accessible en ring 3 ; voici un code qui l’illustre. Cependant, si vous utilisez Linux dans une machine virtuelle telle que [...]
[...] update of the SMP : IDT et GDT – Linux. This modified version of the code also works on [...]