Skip to content

Commit 3f57d4b

Browse files
legoatergregkh
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Free escalation interrupts before disabling the VP
[ Upstream commit 237aed4 ] When a vCPU is brought done, the XIVE VP (Virtual Processor) is first disabled and then the event notification queues are freed. When freeing the queues, we check for possible escalation interrupts and free them also. But when a XIVE VP is disabled, the underlying XIVE ENDs also are disabled in OPAL. When an END (Event Notification Descriptor) is disabled, its ESB pages (ESn and ESe) are disabled and loads return all 1s. Which means that any access on the ESB page of the escalation interrupt will return invalid values. When an interrupt is freed, the shutdown handler computes a 'saved_p' field from the value returned by a load in xive_do_source_set_mask(). This value is incorrect for escalation interrupts for the reason described above. This has no impact on Linux/KVM today because we don't make use of it but we will introduce in future changes a xive_get_irqchip_state() handler. This handler will use the 'saved_p' field to return the state of an interrupt and 'saved_p' being incorrect, softlockup will occur. Fix the vCPU cleanup sequence by first freeing the escalation interrupts if any, then disable the XIVE VP and last free the queues. Fixes: 90c7379 ("KVM: PPC: Book3S HV: Add a new KVM device for the XIVE native exploitation mode") Fixes: 5af5099 ("KVM: PPC: Book3S HV: Native usage of the XIVE interrupt controller") Cc: [email protected] # v4.12+ Signed-off-by: Cédric Le Goater <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
1 parent 2046bee commit 3f57d4b

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

arch/powerpc/kvm/book3s_xive.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,20 +1001,22 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
10011001
/* Mask the VP IPI */
10021002
xive_vm_esb_load(&xc->vp_ipi_data, XIVE_ESB_SET_PQ_01);
10031003

1004-
/* Disable the VP */
1005-
xive_native_disable_vp(xc->vp_id);
1006-
1007-
/* Free the queues & associated interrupts */
1004+
/* Free escalations */
10081005
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1009-
struct xive_q *q = &xc->queues[i];
1010-
1011-
/* Free the escalation irq */
10121006
if (xc->esc_virq[i]) {
10131007
free_irq(xc->esc_virq[i], vcpu);
10141008
irq_dispose_mapping(xc->esc_virq[i]);
10151009
kfree(xc->esc_virq_names[i]);
10161010
}
1017-
/* Free the queue */
1011+
}
1012+
1013+
/* Disable the VP */
1014+
xive_native_disable_vp(xc->vp_id);
1015+
1016+
/* Free the queues */
1017+
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1018+
struct xive_q *q = &xc->queues[i];
1019+
10181020
xive_native_disable_queue(xc->vp_id, q, i);
10191021
if (q->qpage) {
10201022
free_pages((unsigned long)q->qpage,

0 commit comments

Comments
 (0)