Skip to content

Commit 0d3c6b2

Browse files
Gautam Menghanimpe
authored andcommitted
KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
commit 6398326 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") introduced an optimization to use only vcpu->doorbell_request for SMT emulation for Power9 and above guests, but the code for nested guests still relies on the old way of handling doorbells, due to which an L2 guest (see [1]) cannot be booted with XICS with SMT>1. The command to repro this issue is: // To be run in L1 qemu-system-ppc64 \ -drive file=rhel.qcow2,format=qcow2 \ -m 20G \ -smp 8,cores=1,threads=8 \ -cpu host \ -nographic \ -machine pseries,ic-mode=xics -accel kvm Fix the plumbing to utilize vcpu->doorbell_request instead of vcore->dpdes for nested KVM guests on P9 and above. [1] Terminology 1. L0 : PowerNV linux running with HV privileges 2. L1 : Pseries KVM guest running on top of L0 2. L2 : Nested KVM guest running on top of L1 Fixes: 6398326 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") Signed-off-by: Gautam Menghani <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent ed351c5 commit 0d3c6b2

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

arch/powerpc/kvm/book3s_hv.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4285,6 +4285,15 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
42854285
}
42864286
hvregs.hdec_expiry = time_limit;
42874287

4288+
/*
4289+
* hvregs has the doorbell status, so zero it here which
4290+
* enables us to receive doorbells when H_ENTER_NESTED is
4291+
* in progress for this vCPU
4292+
*/
4293+
4294+
if (vcpu->arch.doorbell_request)
4295+
vcpu->arch.doorbell_request = 0;
4296+
42884297
/*
42894298
* When setting DEC, we must always deal with irq_work_raise
42904299
* via NMI vs setting DEC. The problem occurs right as we

arch/powerpc/kvm/book3s_hv_nested.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
3232
struct kvmppc_vcore *vc = vcpu->arch.vcore;
3333

3434
hr->pcr = vc->pcr | PCR_MASK;
35-
hr->dpdes = vc->dpdes;
35+
hr->dpdes = vcpu->arch.doorbell_request;
3636
hr->hfscr = vcpu->arch.hfscr;
3737
hr->tb_offset = vc->tb_offset;
3838
hr->dawr0 = vcpu->arch.dawr0;
@@ -105,7 +105,7 @@ static void save_hv_return_state(struct kvm_vcpu *vcpu,
105105
{
106106
struct kvmppc_vcore *vc = vcpu->arch.vcore;
107107

108-
hr->dpdes = vc->dpdes;
108+
hr->dpdes = vcpu->arch.doorbell_request;
109109
hr->purr = vcpu->arch.purr;
110110
hr->spurr = vcpu->arch.spurr;
111111
hr->ic = vcpu->arch.ic;
@@ -143,7 +143,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *
143143
struct kvmppc_vcore *vc = vcpu->arch.vcore;
144144

145145
vc->pcr = hr->pcr | PCR_MASK;
146-
vc->dpdes = hr->dpdes;
146+
vcpu->arch.doorbell_request = hr->dpdes;
147147
vcpu->arch.hfscr = hr->hfscr;
148148
vcpu->arch.dawr0 = hr->dawr0;
149149
vcpu->arch.dawrx0 = hr->dawrx0;
@@ -170,7 +170,13 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu,
170170
{
171171
struct kvmppc_vcore *vc = vcpu->arch.vcore;
172172

173-
vc->dpdes = hr->dpdes;
173+
/*
174+
* This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled.
175+
* Make sure we preserve the doorbell if it was either:
176+
* a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1)
177+
* b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1)
178+
*/
179+
vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes;
174180
vcpu->arch.hfscr = hr->hfscr;
175181
vcpu->arch.purr = hr->purr;
176182
vcpu->arch.spurr = hr->spurr;

0 commit comments

Comments
 (0)