Disabling all interrupts to protect CPU register state on multi processor systems

8.3k views Asked by At

I need to ensure in a code portion (in kernel mode) that no one else can modify/check the CR0 register. On a one-processor system I think disabling interrupts is the best. But on multi-processor systems :

  • Is there a way to disable ALL interrupts from ALL processors during a code section (with the spinlock mechanism for example)?

  • Is this necessary? When modifying the cr0 register on a multi-processor system, I guess the register is only modified for the current CPU? --> so disabling interrupts only for the current CPU would be sufficient? --> is there a way to check/modify from other CPUs (on a same system) the register from another CPU?

Many thanks in forward for your answers (and sorry for my approximative English)

Jérôme.

2

There are 2 answers

1
Will Tate On

Jérôme,

Have you looked into using spin_lock_irqsave() and spin_unlock_irqrestore()? This disables local interrupts.

I believe a more all-encompassing version is spin_lock_irq() and spin_unlock_irq() which stops all interrupts unconditionally (like cli()/sti()).

There are many conditions to take into account when using these locking mechanisms. One of the primary examples is losing the ability to call kernel functions that may sleep while inside your spin_lock. You may need to do a bit of research before you can determine which is best in your particular case. But from the brief explanation you provided it seems one of the two schemes above should work for you.

Good luck!

0
mpe On

You asked a lot of questions in there, I'll try to answer them in order:

No there is not generally a simple way to disable all interrupts on all processors around a section of code. But you would rarely need to do that. In most cases all you need is to prevent the code from executing on another CPU, and also prevent interrupts on the current cpu. That can be achieved with spin_lock_irqsave().

To modify a register you generally don't need to do any locking, you can modify a register atomically. If you want to modify a register, do something, and then change the register back, then you might need to disable interrupts around that sequence.

In general there is no way to see the registers of another CPU in the system. The way the kernel does that is to ask the other CPU to store its registers into memory.

One thing to be wary of is that on modern CPUs some registers might be per core, ie. shared between multiple threads on a core.

Finally I assume you're talking about CR0 on x86. That is not like modifying any old register, you need to really know what you're doing :-)