Skip to content

Commit cae2059

Browse files
committed
hv: Add a rendezvous timeout and panic on failure
Prints the CPUs that failed rendezvous, which should help debug what caused them to go away. Signed-off-by: Hector Martin <[email protected]>
1 parent 587da64 commit cae2059

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

src/hv.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int hv_want_cpu;
3131
static bool hv_has_ecv;
3232
static bool hv_should_exit;
3333
bool hv_started_cpus[MAX_CPUS];
34-
u32 hv_cpus_in_guest;
34+
u64 hv_cpus_in_guest;
3535
u64 hv_saved_sp[MAX_CPUS];
3636

3737
struct hv_secondary_info_t {
@@ -139,11 +139,11 @@ void hv_start(void *entry, u64 regs[4])
139139
hv_arm_tick(false);
140140
hv_pinned_cpu = -1;
141141
hv_want_cpu = -1;
142-
hv_cpus_in_guest = 1;
142+
hv_cpus_in_guest = BIT(smp_id());
143143

144144
hv_enter_guest(regs[0], regs[1], regs[2], regs[3], entry);
145145

146-
__atomic_sub_fetch(&hv_cpus_in_guest, 1, __ATOMIC_ACQUIRE);
146+
__atomic_and_fetch(&hv_cpus_in_guest, ~BIT(smp_id()), __ATOMIC_ACQUIRE);
147147
spin_lock(&bhl);
148148

149149
hv_wdt_stop();
@@ -204,7 +204,7 @@ static void hv_enter_secondary(void *entry, u64 regs[4])
204204
hv_should_exit = true;
205205
printf("HV: Exiting from CPU %d\n", smp_id());
206206

207-
__atomic_sub_fetch(&hv_cpus_in_guest, 1, __ATOMIC_ACQUIRE);
207+
__atomic_and_fetch(&hv_cpus_in_guest, ~BIT(smp_id()), __ATOMIC_ACQUIRE);
208208

209209
spin_unlock(&bhl);
210210
}
@@ -222,14 +222,16 @@ void hv_start_secondary(int cpu, void *entry, u64 regs[4])
222222

223223
printf("HV: Entering guest secondary %d at %p\n", cpu, entry);
224224
hv_started_cpus[cpu] = true;
225-
__atomic_add_fetch(&hv_cpus_in_guest, 1, __ATOMIC_ACQUIRE);
225+
__atomic_or_fetch(&hv_cpus_in_guest, BIT(smp_id()), __ATOMIC_ACQUIRE);
226226

227227
iodev_console_flush();
228228
smp_call4(cpu, hv_enter_secondary, (u64)entry, (u64)regs, 0, 0);
229229
}
230230

231231
void hv_rendezvous(void)
232232
{
233+
int timeout = 1000000;
234+
233235
if (!__atomic_load_n(&hv_cpus_in_guest, __ATOMIC_ACQUIRE))
234236
return;
235237

@@ -239,8 +241,14 @@ void hv_rendezvous(void)
239241
smp_send_ipi(i);
240242
}
241243
}
242-
while (__atomic_load_n(&hv_cpus_in_guest, __ATOMIC_ACQUIRE))
243-
;
244+
245+
while (timeout--) {
246+
if (!__atomic_load_n(&hv_cpus_in_guest, __ATOMIC_ACQUIRE))
247+
return;
248+
}
249+
250+
panic("HV: Failed to rendezvous, missing CPUs: 0x%lx\n",
251+
__atomic_load_n(&hv_cpus_in_guest, __ATOMIC_ACQUIRE));
244252
}
245253

246254
bool hv_switch_cpu(int cpu)

src/hv_exc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void hv_exit_guest(void) __attribute__((noreturn));
3636
static u64 stolen_time = 0;
3737
static u64 exc_entry_time;
3838

39-
extern u32 hv_cpus_in_guest;
39+
extern u64 hv_cpus_in_guest;
4040
extern int hv_pinned_cpu;
4141
extern int hv_want_cpu;
4242

@@ -367,7 +367,7 @@ static void hv_exc_entry(struct exc_info *ctx)
367367
if (!(mrs(ISR_EL1) & 0x100))
368368
sysop("msr daifclr, 4");
369369

370-
__atomic_sub_fetch(&hv_cpus_in_guest, 1, __ATOMIC_ACQUIRE);
370+
__atomic_and_fetch(&hv_cpus_in_guest, ~BIT(smp_id()), __ATOMIC_ACQUIRE);
371371
spin_lock(&bhl);
372372
hv_wdt_breadcrumb('X');
373373
exc_entry_time = mrs(CNTPCT_EL0);
@@ -385,7 +385,7 @@ static void hv_exc_exit(struct exc_info *ctx)
385385
reg_set(SYS_IMP_APL_PMCR0, PERCPU(exc_entry_pmcr0_cnt));
386386
msr(CNTVOFF_EL2, stolen_time);
387387
spin_unlock(&bhl);
388-
__atomic_add_fetch(&hv_cpus_in_guest, 1, __ATOMIC_ACQUIRE);
388+
__atomic_or_fetch(&hv_cpus_in_guest, BIT(smp_id()), __ATOMIC_ACQUIRE);
389389

390390
hv_set_spsr(ctx->spsr);
391391
hv_set_elr(ctx->elr);

0 commit comments

Comments
 (0)