SMP : IDT et GDT – Linux

Petite mise à jour de l’article SMP : IDT et GDT – Linux. Cette version modifiée du code fonctionne également sur x86_64 :

#define _GNU_SOURCE
#define __USE_GNU
#include <stdio.h>
#include <sched.h>
#include <errno.h>
#include <unistd.h>
 
struct dt_struct {
  unsigned short limit;
  unsigned long base;
} __attribute__((packed));
 
void *get_sidt (void) {
  struct dt_struct idt;
  asm volatile ("sidt %0\t\n" : "=m"(idt));
  return (void *)idt.base;
}
 
void *get_sgdt (void) {
  struct dt_struct gdt;
  asm volatile ("sgdt %0\t\n" : "=m"(gdt));
  return (void *)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 : %p\nGDT : %p\n\n", cpu, get_sidt(), get_sgdt());
      CPU_CLR (cpu, &cs);
    }
    ++cpu;
  }
  return 0;
}
# gcc -Wall -o idt_gtd idt_gtd.c
# ./idt_gtd
CPU 0
IDT : 0xffffffff814dc000
GDT : 0xffff880001013000
 
CPU 1
IDT : 0xffffffff814dc000
GDT : 0xffff880001021000

2 Comments

Leave a Reply

XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">