diff --git a/src/hv_exc.c b/src/hv_exc.c index 3533802a..803f14f7 100644 --- a/src/hv_exc.c +++ b/src/hv_exc.c @@ -522,7 +522,7 @@ void hv_exc_fiq(struct exc_info *ctx) int interruptible_cpu = hv_pinned_cpu; if (interruptible_cpu == -1) - interruptible_cpu = 0; + interruptible_cpu = boot_cpu_idx; if (smp_id() != interruptible_cpu && !(mrs(ISR_EL1) & 0x40) && hv_want_cpu == -1) { // Non-interruptible CPU and it was just a timer tick (or spurious), so just update FIQs diff --git a/src/smp.c b/src/smp.c index 6e683b49..15ccc0e4 100644 --- a/src/smp.c +++ b/src/smp.c @@ -319,6 +319,10 @@ void smp_start_secondaries(void) if (strcmp(state, "running") == 0) { boot_cpu_idx = i; boot_cpu_mpidr = mrs(MPIDR_EL1); + if (in_el2()) + msr(TPIDR_EL2, boot_cpu_idx); + else + msr(TPIDR_EL1, boot_cpu_idx); break; } } @@ -330,6 +334,8 @@ void smp_start_secondaries(void) return; } + spin_table[boot_cpu_idx].mpidr = mrs(MPIDR_EL1) & 0xFFFFFF; + for (int i = 0; i < MAX_CPUS; i++) { int cpu_node = cpu_nodes[i]; @@ -369,8 +375,6 @@ void smp_start_secondaries(void) smp_start_cpu(i, die, cluster, core, cpu_impl_reg[0], pmgr_reg + cpu_start_off); } - - spin_table[boot_cpu_idx].mpidr = mrs(MPIDR_EL1) & 0xFFFFFF; } void smp_stop_secondaries(bool deep_sleep) @@ -432,7 +436,7 @@ void smp_call4(int cpu, void *func, u64 arg0, u64 arg1, u64 arg2, u64 arg3) struct spin_table *target = &spin_table[cpu]; - if (cpu == 0) + if (cpu == boot_cpu_idx) return; u64 flag = target->flag;