Skip to content

Commit 44e7cab

Browse files
committed
enable the virtual timer interrupt on application processors
The switch from the physical timer (CNTP_*) to the virtual timer (CNTV_*) updated the FDT parsing in init(), which now selects the third interrupt triplet of the "arm,armv8-timer" node (Virtual, PPI 11 / INTID 27). init_cpu() still selected the second triplet (Non-secure Phys, PPI 14 / INTID 30), so every application processor enabled the physical timer PPI in its redistributor while set_oneshot_timer programs the virtual timer. Timer PPIs are per-core: sleeping tasks on the secondary cores were never woken up again. This is why thread_test with --smp 4 timed out: of eight threads only the two scheduled on the boot core finished; the six on the secondary cores slept forever. Skip the same two triplets in init_cpu() so all cores enable the virtual timer interrupt.
1 parent 2575d7e commit 44e7cab

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

src/arch/aarch64/kernel/interrupts.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,15 @@ pub fn init_cpu() {
627627

628628
if let Some(timer_node) = fdt.find_compatible(&["arm,armv8-timer", "arm,armv7-timer"]) {
629629
let irq_slice = timer_node.property("interrupts").unwrap().value;
630-
/* Secure Phys IRQ */
630+
// Select the Virtual Timer triplet, matching `init()`: the kernel
631+
// programs the virtual timer (CNTV_*), and timer PPIs are per-core,
632+
// so every application processor has to enable the *same* interrupt
633+
// in its redistributor that the boot core selected.
634+
/* Secure Phys IRQ — skip */
635+
let (_irqtype, irq_slice) = irq_slice.split_at(size_of::<u32>());
636+
let (_irq, irq_slice) = irq_slice.split_at(size_of::<u32>());
637+
let (_irqflags, irq_slice) = irq_slice.split_at(size_of::<u32>());
638+
/* Non-secure Phys IRQ — skip */
631639
let (_irqtype, irq_slice) = irq_slice.split_at(size_of::<u32>());
632640
let (_irq, irq_slice) = irq_slice.split_at(size_of::<u32>());
633641
let (_irqflags, irq_slice) = irq_slice.split_at(size_of::<u32>());

0 commit comments

Comments
 (0)