Skip to content

Commit 237aed4

Browse files
legoatermpe
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Free escalation interrupts before disabling the VP
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]
1 parent 609488b commit 237aed4

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

arch/powerpc/kvm/book3s_xive.c

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

1137-
/* Disable the VP */
1138-
xive_native_disable_vp(xc->vp_id);
1139-
1140-
/* Free the queues & associated interrupts */
1137+
/* Free escalations */
11411138
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1142-
struct xive_q *q = &xc->queues[i];
1143-
1144-
/* Free the escalation irq */
11451139
if (xc->esc_virq[i]) {
11461140
free_irq(xc->esc_virq[i], vcpu);
11471141
irq_dispose_mapping(xc->esc_virq[i]);
11481142
kfree(xc->esc_virq_names[i]);
11491143
}
1150-
/* Free the queue */
1144+
}
1145+
1146+
/* Disable the VP */
1147+
xive_native_disable_vp(xc->vp_id);
1148+
1149+
/* Free the queues */
1150+
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1151+
struct xive_q *q = &xc->queues[i];
1152+
11511153
xive_native_disable_queue(xc->vp_id, q, i);
11521154
if (q->qpage) {
11531155
free_pages((unsigned long)q->qpage,

arch/powerpc/kvm/book3s_xive_native.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
6767
xc->valid = false;
6868
kvmppc_xive_disable_vcpu_interrupts(vcpu);
6969

70-
/* Disable the VP */
71-
xive_native_disable_vp(xc->vp_id);
72-
73-
/* Free the queues & associated interrupts */
70+
/* Free escalations */
7471
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
7572
/* Free the escalation irq */
7673
if (xc->esc_virq[i]) {
@@ -79,8 +76,13 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
7976
kfree(xc->esc_virq_names[i]);
8077
xc->esc_virq[i] = 0;
8178
}
79+
}
8280

83-
/* Free the queue */
81+
/* Disable the VP */
82+
xive_native_disable_vp(xc->vp_id);
83+
84+
/* Free the queues */
85+
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
8486
kvmppc_xive_native_cleanup_queue(vcpu, i);
8587
}
8688

0 commit comments

Comments
 (0)