Skip to content

Commit aef92d8

Browse files
vivierdgibson
authored andcommitted
pseries: fix kvmppc_set_fwnmi()
QEMU issues the ioctl(KVM_CAP_PPC_FWNMI) on the first vCPU. If the first vCPU is currently running, the vCPU mutex is held and the ioctl() cannot be done and waits until the mutex is released. This never happens and the VM is stuck. To avoid this deadlock, issue the ioctl on the same vCPU doing the RTAS call. The problem can be reproduced by booting a guest with several vCPUs (the probability to have the problem is (n - 1) / n, n = # of CPUs), and then by triggering a kernel crash with "echo c >/proc/sysrq-trigger". On the reboot, the kernel hangs after: ... [ 0.000000] ----------------------------------------------------- [ 0.000000] ppc64_pft_size = 0x0 [ 0.000000] phys_mem_size = 0x48000000 [ 0.000000] dcache_bsize = 0x80 [ 0.000000] icache_bsize = 0x80 [ 0.000000] cpu_features = 0x0001c06f8f4f91a7 [ 0.000000] possible = 0x0003fbffcf5fb1a7 [ 0.000000] always = 0x00000003800081a1 [ 0.000000] cpu_user_features = 0xdc0065c2 0xaee00000 [ 0.000000] mmu_features = 0x3c006041 [ 0.000000] firmware_features = 0x00000085455a445f [ 0.000000] physical_start = 0x8000000 [ 0.000000] ----------------------------------------------------- [ 0.000000] numa: NODE_DATA [mem 0x47f33c80-0x47f3ffff] Fixes: ec010c0 ("ppc/spapr: KVM FWNMI should not be enabled until guest requests it") Cc: [email protected] Signed-off-by: Laurent Vivier <[email protected]> Message-Id: <[email protected]> Signed-off-by: David Gibson <[email protected]>
1 parent 194f8ca commit aef92d8

File tree

3 files changed

+4
-5
lines changed

3 files changed

+4
-5
lines changed

hw/ppc/spapr_rtas.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
438438
}
439439

440440
if (kvm_enabled()) {
441-
if (kvmppc_set_fwnmi() < 0) {
441+
if (kvmppc_set_fwnmi(cpu) < 0) {
442442
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
443443
return;
444444
}

target/ppc/kvm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,9 +2071,8 @@ bool kvmppc_get_fwnmi(void)
20712071
return cap_fwnmi;
20722072
}
20732073

2074-
int kvmppc_set_fwnmi(void)
2074+
int kvmppc_set_fwnmi(PowerPCCPU *cpu)
20752075
{
2076-
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
20772076
CPUState *cs = CPU(cpu);
20782077

20792078
return kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_FWNMI, 0);

target/ppc/kvm_ppc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void kvmppc_set_papr(PowerPCCPU *cpu);
2828
int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
2929
void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
3030
bool kvmppc_get_fwnmi(void);
31-
int kvmppc_set_fwnmi(void);
31+
int kvmppc_set_fwnmi(PowerPCCPU *cpu);
3232
int kvmppc_smt_threads(void);
3333
void kvmppc_error_append_smt_possible_hint(Error *const *errp);
3434
int kvmppc_set_smt_threads(int smt);
@@ -169,7 +169,7 @@ static inline bool kvmppc_get_fwnmi(void)
169169
return false;
170170
}
171171

172-
static inline int kvmppc_set_fwnmi(void)
172+
static inline int kvmppc_set_fwnmi(PowerPCCPU *cpu)
173173
{
174174
return -1;
175175
}

0 commit comments

Comments
 (0)