Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/include/cpu.h	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -51,5 +51,5 @@
  */
 typedef struct cpu {
-	IRQ_SPINLOCK_DECLARE(lock);
+	IRQ_SPINLOCK_DECLARE(tlb_lock);
 
 	tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN];
@@ -97,4 +97,5 @@
 	cpu_arch_t arch;
 
+	IRQ_SPINLOCK_DECLARE(fpu_lock);
 	struct thread *fpu_owner;
 
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/cpu/cpu.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -84,5 +84,6 @@
 			cpus[i].id = i;
 
-			irq_spinlock_initialize(&cpus[i].lock, "cpus[].lock");
+			irq_spinlock_initialize(&cpus[i].fpu_lock, "cpus[].fpu_lock");
+			irq_spinlock_initialize(&cpus[i].tlb_lock, "cpus[].tlb_lock");
 
 			for (unsigned int j = 0; j < RQ_COUNT; j++) {
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/interrupt/interrupt.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -114,10 +114,8 @@
 	/* Account CPU usage if it woke up from sleep */
 	if (CPU && CPU->idle) {
-		irq_spinlock_lock(&CPU->lock, false);
 		uint64_t now = get_cycle();
 		atomic_time_increment(&CPU->idle_cycles, now - CPU->last_cycle);
 		CPU->last_cycle = now;
 		CPU->idle = false;
-		irq_spinlock_unlock(&CPU->lock, false);
 	}
 
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/mm/tlb.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -95,5 +95,5 @@
 		cpu_t *cpu = &cpus[i];
 
-		irq_spinlock_lock(&cpu->lock, false);
+		irq_spinlock_lock(&cpu->tlb_lock, false);
 		if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) {
 			/*
@@ -116,5 +116,5 @@
 			cpu->tlb_messages[idx].count = count;
 		}
-		irq_spinlock_unlock(&cpu->lock, false);
+		irq_spinlock_unlock(&cpu->tlb_lock, false);
 	}
 
@@ -158,5 +158,5 @@
 	irq_spinlock_unlock(&tlblock, false);
 
-	irq_spinlock_lock(&CPU->lock, false);
+	irq_spinlock_lock(&CPU->tlb_lock, false);
 	assert(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
 
@@ -189,5 +189,5 @@
 
 	CPU->tlb_messages_count = 0;
-	irq_spinlock_unlock(&CPU->lock, false);
+	irq_spinlock_unlock(&CPU->tlb_lock, false);
 	CPU->tlb_active = true;
 }
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/proc/scheduler.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -129,5 +129,5 @@
 {
 	fpu_enable();
-	irq_spinlock_lock(&CPU->lock, false);
+	irq_spinlock_lock(&CPU->fpu_lock, false);
 
 	/* Save old context */
@@ -154,5 +154,5 @@
 	irq_spinlock_unlock(&THREAD->lock, false);
 
-	irq_spinlock_unlock(&CPU->lock, false);
+	irq_spinlock_unlock(&CPU->fpu_lock, false);
 }
 #endif /* CONFIG_FPU_LAZY */
@@ -187,7 +187,5 @@
 		 * This improves energy saving and hyperthreading.
 		 */
-		irq_spinlock_lock(&CPU->lock, false);
 		CPU->idle = true;
-		irq_spinlock_unlock(&CPU->lock, false);
 
 		/*
@@ -298,6 +296,4 @@
 	size_t n = 0;
 
-	irq_spinlock_lock(&CPU->lock, false);
-
 	/* Move every list (except the one with highest priority) one level up. */
 	for (int i = RQ_COUNT - 1; i > start; i--) {
@@ -322,6 +318,4 @@
 		irq_spinlock_unlock(&CPU->rq[start].lock, false);
 	}
-
-	irq_spinlock_unlock(&CPU->lock, false);
 }
 
@@ -684,6 +678,4 @@
 			continue;
 
-		irq_spinlock_lock(&cpus[cpu].lock, true);
-
 		/* Technically a data race, but we don't really care in this case. */
 		int needs_relink = cpus[cpu].relink_deadline - cpus[cpu].current_clock_tick;
@@ -711,6 +703,4 @@
 			irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
 		}
-
-		irq_spinlock_unlock(&cpus[cpu].lock, true);
 	}
 }
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/proc/thread.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -425,11 +425,14 @@
 
 	assert((thread->state == Exiting) || (thread->state == Lingering));
-	assert(thread->cpu);
 
 	/* Clear cpu->fpu_owner if set to this thread. */
-	irq_spinlock_lock(&thread->cpu->lock, false);
-	if (thread->cpu->fpu_owner == thread)
-		thread->cpu->fpu_owner = NULL;
-	irq_spinlock_unlock(&thread->cpu->lock, false);
+#ifdef CONFIG_FPU_LAZY
+	if (thread->cpu) {
+		irq_spinlock_lock(&thread->cpu->fpu_lock, false);
+		if (thread->cpu->fpu_owner == thread)
+			thread->cpu->fpu_owner = NULL;
+		irq_spinlock_unlock(&thread->cpu->fpu_lock, false);
+	}
+#endif
 
 	interrupts_restore(ipl);
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/sysinfo/stats.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -119,6 +119,4 @@
 	size_t i;
 	for (i = 0; i < config.cpu_count; i++) {
-		irq_spinlock_lock(&cpus[i].lock, true);
-
 		stats_cpus[i].id = cpus[i].id;
 		stats_cpus[i].active = cpus[i].active;
@@ -127,6 +125,4 @@
 		stats_cpus[i].busy_cycles = atomic_time_read(&cpus[i].busy_cycles);
 		stats_cpus[i].idle_cycles = atomic_time_read(&cpus[i].idle_cycles);
-
-		irq_spinlock_unlock(&cpus[i].lock, true);
 	}
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision b2ec5cfd5e00eac7963f5a84fb71f002ad79f1f0)
+++ kernel/generic/src/time/clock.c	(revision 169815e2ba9d5c7d3100ba8cb47424144c4ceb3b)
@@ -123,9 +123,7 @@
 static void cpu_update_accounting(void)
 {
-	irq_spinlock_lock(&CPU->lock, false);
 	uint64_t now = get_cycle();
 	atomic_time_increment(&CPU->busy_cycles, now - CPU->last_cycle);
 	CPU->last_cycle = now;
-	irq_spinlock_unlock(&CPU->lock, false);
 }
 
