Skip to content

Commit 1a47908

Browse files
committed
Merge branch 'topic/ppc-kvm' into next
Merge our ppc-kvm topic branch. This contains several fixes for the XIVE interrupt controller that we are sharing with the KVM tree.
2 parents 4215fa2 + da15c03 commit 1a47908

File tree

6 files changed

+163
-50
lines changed

6 files changed

+163
-50
lines changed

arch/powerpc/include/asm/xive.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ struct xive_irq_data {
4646

4747
/* Setup/used by frontend */
4848
int target;
49+
/*
50+
* saved_p means that there is a queue entry for this interrupt
51+
* in some CPU's queue (not including guest vcpu queues), even
52+
* if P is not set in the source ESB.
53+
* stale_p means that there is no queue entry for this interrupt
54+
* in some CPU's queue, even if P is set in the source ESB.
55+
*/
4956
bool saved_p;
57+
bool stale_p;
5058
};
5159
#define XIVE_IRQ_FLAG_STORE_EOI 0x01
5260
#define XIVE_IRQ_FLAG_LSI 0x02

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
942942
ld r11, VCPU_XIVE_SAVED_STATE(r4)
943943
li r9, TM_QW1_OS
944944
lwz r8, VCPU_XIVE_CAM_WORD(r4)
945+
cmpwi r8, 0
946+
beq no_xive
945947
li r7, TM_QW1_OS + TM_WORD2
946948
mfmsr r0
947949
andi. r0, r0, MSR_DR /* in real mode? */
@@ -2831,29 +2833,39 @@ kvm_cede_prodded:
28312833
kvm_cede_exit:
28322834
ld r9, HSTATE_KVM_VCPU(r13)
28332835
#ifdef CONFIG_KVM_XICS
2834-
/* Abort if we still have a pending escalation */
2836+
/* are we using XIVE with single escalation? */
2837+
ld r10, VCPU_XIVE_ESC_VADDR(r9)
2838+
cmpdi r10, 0
2839+
beq 3f
2840+
li r6, XIVE_ESB_SET_PQ_00
2841+
/*
2842+
* If we still have a pending escalation, abort the cede,
2843+
* and we must set PQ to 10 rather than 00 so that we don't
2844+
* potentially end up with two entries for the escalation
2845+
* interrupt in the XIVE interrupt queue. In that case
2846+
* we also don't want to set xive_esc_on to 1 here in
2847+
* case we race with xive_esc_irq().
2848+
*/
28352849
lbz r5, VCPU_XIVE_ESC_ON(r9)
28362850
cmpwi r5, 0
2837-
beq 1f
2851+
beq 4f
28382852
li r0, 0
28392853
stb r0, VCPU_CEDED(r9)
2840-
1: /* Enable XIVE escalation */
2841-
li r5, XIVE_ESB_SET_PQ_00
2854+
li r6, XIVE_ESB_SET_PQ_10
2855+
b 5f
2856+
4: li r0, 1
2857+
stb r0, VCPU_XIVE_ESC_ON(r9)
2858+
/* make sure store to xive_esc_on is seen before xive_esc_irq runs */
2859+
sync
2860+
5: /* Enable XIVE escalation */
28422861
mfmsr r0
28432862
andi. r0, r0, MSR_DR /* in real mode? */
28442863
beq 1f
2845-
ld r10, VCPU_XIVE_ESC_VADDR(r9)
2846-
cmpdi r10, 0
2847-
beq 3f
2848-
ldx r0, r10, r5
2864+
ldx r0, r10, r6
28492865
b 2f
28502866
1: ld r10, VCPU_XIVE_ESC_RADDR(r9)
2851-
cmpdi r10, 0
2852-
beq 3f
2853-
ldcix r0, r10, r5
2867+
ldcix r0, r10, r6
28542868
2: sync
2855-
li r0, 1
2856-
stb r0, VCPU_XIVE_ESC_ON(r9)
28572869
#endif /* CONFIG_KVM_XICS */
28582870
3: b guest_exit_cont
28592871

arch/powerpc/kvm/book3s_xive.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,14 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu)
6767
void __iomem *tima = local_paca->kvm_hstate.xive_tima_virt;
6868
u64 pq;
6969

70-
if (!tima)
70+
/*
71+
* Nothing to do if the platform doesn't have a XIVE
72+
* or this vCPU doesn't have its own XIVE context
73+
* (e.g. because it's not using an in-kernel interrupt controller).
74+
*/
75+
if (!tima || !vcpu->arch.xive_cam_word)
7176
return;
77+
7278
eieio();
7379
__raw_writeq(vcpu->arch.xive_saved_state.w01, tima + TM_QW1_OS);
7480
__raw_writel(vcpu->arch.xive_cam_word, tima + TM_QW1_OS + TM_WORD2);
@@ -160,6 +166,9 @@ static irqreturn_t xive_esc_irq(int irq, void *data)
160166
*/
161167
vcpu->arch.xive_esc_on = false;
162168

169+
/* This orders xive_esc_on = false vs. subsequent stale_p = true */
170+
smp_wmb(); /* goes with smp_mb() in cleanup_single_escalation */
171+
163172
return IRQ_HANDLED;
164173
}
165174

@@ -1113,6 +1122,31 @@ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu)
11131122
vcpu->arch.xive_esc_raddr = 0;
11141123
}
11151124

1125+
/*
1126+
* In single escalation mode, the escalation interrupt is marked so
1127+
* that EOI doesn't re-enable it, but just sets the stale_p flag to
1128+
* indicate that the P bit has already been dealt with. However, the
1129+
* assembly code that enters the guest sets PQ to 00 without clearing
1130+
* stale_p (because it has no easy way to address it). Hence we have
1131+
* to adjust stale_p before shutting down the interrupt.
1132+
*/
1133+
void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu,
1134+
struct kvmppc_xive_vcpu *xc, int irq)
1135+
{
1136+
struct irq_data *d = irq_get_irq_data(irq);
1137+
struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
1138+
1139+
/*
1140+
* This slightly odd sequence gives the right result
1141+
* (i.e. stale_p set if xive_esc_on is false) even if
1142+
* we race with xive_esc_irq() and xive_irq_eoi().
1143+
*/
1144+
xd->stale_p = false;
1145+
smp_mb(); /* paired with smb_wmb in xive_esc_irq */
1146+
if (!vcpu->arch.xive_esc_on)
1147+
xd->stale_p = true;
1148+
}
1149+
11161150
void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
11171151
{
11181152
struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
@@ -1134,20 +1168,28 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
11341168
/* Mask the VP IPI */
11351169
xive_vm_esb_load(&xc->vp_ipi_data, XIVE_ESB_SET_PQ_01);
11361170

1137-
/* Disable the VP */
1138-
xive_native_disable_vp(xc->vp_id);
1139-
1140-
/* Free the queues & associated interrupts */
1171+
/* Free escalations */
11411172
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1142-
struct xive_q *q = &xc->queues[i];
1143-
1144-
/* Free the escalation irq */
11451173
if (xc->esc_virq[i]) {
1174+
if (xc->xive->single_escalation)
1175+
xive_cleanup_single_escalation(vcpu, xc,
1176+
xc->esc_virq[i]);
11461177
free_irq(xc->esc_virq[i], vcpu);
11471178
irq_dispose_mapping(xc->esc_virq[i]);
11481179
kfree(xc->esc_virq_names[i]);
11491180
}
1150-
/* Free the queue */
1181+
}
1182+
1183+
/* Disable the VP */
1184+
xive_native_disable_vp(xc->vp_id);
1185+
1186+
/* Clear the cam word so guest entry won't try to push context */
1187+
vcpu->arch.xive_cam_word = 0;
1188+
1189+
/* Free the queues */
1190+
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1191+
struct xive_q *q = &xc->queues[i];
1192+
11511193
xive_native_disable_queue(xc->vp_id, q, i);
11521194
if (q->qpage) {
11531195
free_pages((unsigned long)q->qpage,

arch/powerpc/kvm/book3s_xive.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio);
282282
int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio,
283283
bool single_escalation);
284284
struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type);
285+
void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu,
286+
struct kvmppc_xive_vcpu *xc, int irq);
285287

286288
#endif /* CONFIG_KVM_XICS */
287289
#endif /* _KVM_PPC_BOOK3S_XICS_H */

arch/powerpc/kvm/book3s_xive_native.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,28 @@ 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]) {
74+
if (xc->xive->single_escalation)
75+
xive_cleanup_single_escalation(vcpu, xc,
76+
xc->esc_virq[i]);
7777
free_irq(xc->esc_virq[i], vcpu);
7878
irq_dispose_mapping(xc->esc_virq[i]);
7979
kfree(xc->esc_virq_names[i]);
8080
xc->esc_virq[i] = 0;
8181
}
82+
}
8283

83-
/* Free the queue */
84+
/* Disable the VP */
85+
xive_native_disable_vp(xc->vp_id);
86+
87+
/* Clear the cam word so guest entry won't try to push context */
88+
vcpu->arch.xive_cam_word = 0;
89+
90+
/* Free the queues */
91+
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
8492
kvmppc_xive_native_cleanup_queue(vcpu, i);
8593
}
8694

0 commit comments

Comments
 (0)