math_state_restore and kernel_fpu_end disable interrupts?

From: Nate Eldredge
Date: Sat Jan 18 2014 - 01:21:18 EST


In trying to track down a bug (see below), I noticed that math_state_restore() in arch/x86/kernel/traps.c appears to unconditionally disable interrupts when called. Is this intended behavior or a bug?

The bug in question is triggered by dumping core on an ecryptfs file system when aesni-intel is loaded. (See https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1265841 for the original report.) The symptom is that __find_get_block() gets called with interrupts disabled, causing a BUG(). I tried to find where interrupts were getting disabled and wound up in aes_set_key_common() in arch/x86/crypto/aesni-intel_glue.c. It calls aesni_set_key(), and since that uses the FPU, it wraps it in kernel_fpu_begin()/kernel_fpu_end(). But kernel_fpu_end() calls math_state_restore() which disables interrupts. I've verified that interrupts are still enabled just before the call to kernel_fpu_end().

math_state_restore() does:

local_irq_enable();
init_fpu(tsk);
local_irq_disable();

with the result that interrupts are disabled when it finishes, even if they were enabled to begin with. That looks strange to me; are we sure it shouldn't just save and restore the interrupt flag? Or are we not supposed to call it with interrupts enabled?

Given the intimidating comment preceding math_state_restore() ("Don't touch unless you *really* know how it works"), it's entirely possible I am missing something...

Any suggestions appreciated. Thanks!

--
Nate Eldredge
nate@xxxxxxxxxxxxxxxxxxxx

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/