Same IDTR value for each cpu

Viewed 52

I wrote a kernel module to print IDTR value to see if each CPU (hyper-threads) running on each core have their own separate IDT or share the same one for a particular Core. But, I am getting same base and limit value for IDTR on each CPU, which makes it seem like that there is a global IDT that is shared by all the CPUs.

To run on different CPUs, I wrote a script that inserts my module using a particular CPU using 'taskset'.

This is my module:

#include <linux/init.h>
#include <linux/module.h>

struct idt {
    u16 length;
        u64    base;
} __attribute__((packed)) idt;

void my_store_idt(struct idt *idt)
{
    asm volatile ("sidt %0" : "=m"(*idt));
}

static int __init mod_init(void) {
        my_store_idt(&idt);
        printk("cpu = %d, idtr.length = %u, idtr.base =  %llu\n"
                ,get_cpu(), idt.length, idt.base);

        return 0;
}

static void __exit mod_exit(void)
{

        printk("byeee\n");
}

module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");

And this is the output I get:

[Sep15 00:52] cpu = 0, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001625] byeee
[  +0.016648] cpu = 1, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001234] byeee
[  +0.012360] cpu = 2, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001140] byeee
[  +0.007094] cpu = 3, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001182] byeee
[  +0.010665] cpu = 4, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001136] byeee
[  +0.007931] cpu = 5, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001141] byeee
[  +0.012969] cpu = 6, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001189] byeee
[  +0.019079] cpu = 7, idtr.length = 4095, idtr.base =  18446741874686296064
[  +0.001226] byeee

This is the scrpt I used to run it on different CPUs:

 #!/bin/bash

 for i in {0..7} 
  do

      taskset -c $i insmod read_idtr.ko

      rmmod read_idtr 
  done

I have read that each processor has its own IDT. So, either it should show different IDTR value for each CPU or for atleast each Core. Why I am getting the same for each CPU?

1 Answers

I wrote a kernel module to print IDTR value to see if each CPU (hyper-threads) running on each core have their own separate IDT or share the same one for a particular Core. But, I am getting same base and limit value for IDTR on each CPU, which makes it seem like that there is a global IDT that is shared by all the CPUs.

And? That seems like a valid and eminently reasonable result to me. Why would you expect a multiprocessing OS kernel to establish different interrupt vectors for different cores? And if the cores are all to have the same interrupt vectors, then why give each one its own copy of the IDT? Better all around in that case for all execution units to share the same IDT.

In any case, as the basis for your experiment, you already hypothesized that different virtual CPUs associated with the same core might have the same IDT, so I don't see what the problem is. Of course, your experiment does not show whether the IDTRs are per-core or per-hyperthread, but its design cannot distinguish between those alternatives in the per-core case anyway, and it might not distinguish between them in the per-hyperthread case. That is, when you see different virtual CPUs having the same IDT, the expirement does not tell you whether that's because they are incapable of having different ones or because the system just set them up that way.

Am I doing something wrong?

If anything is wrong with your code then I don't see it, but I suspect that some of your assumptions are wrong. Also, reading specs would probably be a better approach to answering your question than is performing the experiment you have devised.

Related