Message ID | 20210219063542.1425130-13-npiggin@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | KVM: PPC: Book3S: C-ify the P9 entry/exit code | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/merge (626a6c3d2e20da80aaa710104f34ea6037b28b33) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/next (6895c5ba7bdcc55eacad03cf309ab23be63b9cac) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch linus/master (92bf22614b21a2706f4993b278017e437f7785b3) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/fixes (24321ac668e452a4942598533d267805f291fdc9) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch linux-next (1e0d27fce010b0a4a9e595506b6ede75934c31be) |
snowpatch_ozlabs/apply_patch | fail | Failed to apply to any branch |
Nicholas Piggin <npiggin@gmail.com> writes: > Switching the MMU from radix<->radix mode is tricky particularly as the > MMU can remain enabled and requires a certain sequence of SPR updates. > Move these together into their own functions. > > This also includes the radix TLB check / flush because it's tied in to > MMU switching due to tlbiel getting LPID from LPIDR. > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- <snip> > @@ -4117,7 +4138,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, > { > struct kvm_run *run = vcpu->run; > int trap, r, pcpu; > - int srcu_idx, lpid; > + int srcu_idx; > struct kvmppc_vcore *vc; > struct kvm *kvm = vcpu->kvm; > struct kvm_nested_guest *nested = vcpu->arch.nested; > @@ -4191,13 +4212,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, > vc->vcore_state = VCORE_RUNNING; > trace_kvmppc_run_core(vc, 0); > > - if (cpu_has_feature(CPU_FTR_HVMODE)) { > - lpid = nested ? nested->shadow_lpid : kvm->arch.lpid; > - mtspr(SPRN_LPID, lpid); > - isync(); > - kvmppc_check_need_tlb_flush(kvm, pcpu, nested); > - } > - What about the counterpart to this^ down below? if (cpu_has_feature(CPU_FTR_HVMODE)) { mtspr(SPRN_LPID, kvm->arch.host_lpid); isync(); } > guest_enter_irqoff(); > > srcu_idx = srcu_read_lock(&kvm->srcu);
Excerpts from Fabiano Rosas's message of February 25, 2021 6:36 am: > Nicholas Piggin <npiggin@gmail.com> writes: > >> Switching the MMU from radix<->radix mode is tricky particularly as the >> MMU can remain enabled and requires a certain sequence of SPR updates. >> Move these together into their own functions. >> >> This also includes the radix TLB check / flush because it's tied in to >> MMU switching due to tlbiel getting LPID from LPIDR. >> >> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> >> --- > > <snip> > >> @@ -4117,7 +4138,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, >> { >> struct kvm_run *run = vcpu->run; >> int trap, r, pcpu; >> - int srcu_idx, lpid; >> + int srcu_idx; >> struct kvmppc_vcore *vc; >> struct kvm *kvm = vcpu->kvm; >> struct kvm_nested_guest *nested = vcpu->arch.nested; >> @@ -4191,13 +4212,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, >> vc->vcore_state = VCORE_RUNNING; >> trace_kvmppc_run_core(vc, 0); >> >> - if (cpu_has_feature(CPU_FTR_HVMODE)) { >> - lpid = nested ? nested->shadow_lpid : kvm->arch.lpid; >> - mtspr(SPRN_LPID, lpid); >> - isync(); >> - kvmppc_check_need_tlb_flush(kvm, pcpu, nested); >> - } >> - > > What about the counterpart to this^ down below? > > if (cpu_has_feature(CPU_FTR_HVMODE)) { > mtspr(SPRN_LPID, kvm->arch.host_lpid); > isync(); > } Good catch, you're right that can be removed too. Thanks, Nick
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 53d0cbfe5933..6bf7f5ce4865 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3446,12 +3446,38 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) trace_kvmppc_run_core(vc, 1); } +static void switch_mmu_to_guest_radix(struct kvm *kvm, struct kvm_vcpu *vcpu, u64 lpcr) +{ + struct kvmppc_vcore *vc = vcpu->arch.vcore; + struct kvm_nested_guest *nested = vcpu->arch.nested; + u32 lpid; + + lpid = nested ? nested->shadow_lpid : kvm->arch.lpid; + + mtspr(SPRN_LPID, lpid); + mtspr(SPRN_LPCR, lpcr); + mtspr(SPRN_PID, vcpu->arch.pid); + isync(); + + /* TLBIEL must have LPIDR set, so set guest LPID before flushing. */ + kvmppc_check_need_tlb_flush(kvm, vc->pcpu, nested); +} + +static void switch_mmu_to_host_radix(struct kvm *kvm, u32 pid) +{ + mtspr(SPRN_PID, pid); + mtspr(SPRN_LPID, kvm->arch.host_lpid); + mtspr(SPRN_LPCR, kvm->arch.host_lpcr); + isync(); +} + /* * Load up hypervisor-mode registers on P9. */ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpcr) { + struct kvm *kvm = vcpu->kvm; struct kvmppc_vcore *vc = vcpu->arch.vcore; s64 hdec; u64 tb, purr, spurr; @@ -3467,12 +3493,12 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, * P8 and P9 suppress the HDEC exception when LPCR[HDICE] = 0, * so set HDICE before writing HDEC. */ - mtspr(SPRN_LPCR, vcpu->kvm->arch.host_lpcr | LPCR_HDICE); + mtspr(SPRN_LPCR, kvm->arch.host_lpcr | LPCR_HDICE); isync(); hdec = time_limit - mftb(); if (hdec < 0) { - mtspr(SPRN_LPCR, vcpu->kvm->arch.host_lpcr); + mtspr(SPRN_LPCR, kvm->arch.host_lpcr); isync(); return BOOK3S_INTERRUPT_HV_DECREMENTER; } @@ -3503,7 +3529,6 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, } mtspr(SPRN_CIABR, vcpu->arch.ciabr); mtspr(SPRN_IC, vcpu->arch.ic); - mtspr(SPRN_PID, vcpu->arch.pid); mtspr(SPRN_PSSCR, vcpu->arch.psscr | PSSCR_EC | (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG)); @@ -3517,8 +3542,7 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, mtspr(SPRN_AMOR, ~0UL); - mtspr(SPRN_LPCR, lpcr); - isync(); + switch_mmu_to_guest_radix(kvm, vcpu, lpcr); kvmppc_xive_push_vcpu(vcpu); @@ -3553,7 +3577,6 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, mtspr(SPRN_CIABR, host_ciabr); mtspr(SPRN_DAWR0, host_dawr); mtspr(SPRN_DAWRX0, host_dawrx); - mtspr(SPRN_PID, host_pidr); /* * Since this is radix, do a eieio; tlbsync; ptesync sequence in @@ -3568,9 +3591,6 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, if (cpu_has_feature(CPU_FTR_ARCH_31)) asm volatile(PPC_CP_ABORT); - mtspr(SPRN_LPID, vcpu->kvm->arch.host_lpid); /* restore host LPID */ - isync(); - vc->dpdes = mfspr(SPRN_DPDES); vc->vtb = mfspr(SPRN_VTB); mtspr(SPRN_DPDES, 0); @@ -3587,7 +3607,8 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, } mtspr(SPRN_HDEC, 0x7fffffff); - mtspr(SPRN_LPCR, vcpu->kvm->arch.host_lpcr); + + switch_mmu_to_host_radix(kvm, host_pidr); return trap; } @@ -4117,7 +4138,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, { struct kvm_run *run = vcpu->run; int trap, r, pcpu; - int srcu_idx, lpid; + int srcu_idx; struct kvmppc_vcore *vc; struct kvm *kvm = vcpu->kvm; struct kvm_nested_guest *nested = vcpu->arch.nested; @@ -4191,13 +4212,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, vc->vcore_state = VCORE_RUNNING; trace_kvmppc_run_core(vc, 0); - if (cpu_has_feature(CPU_FTR_HVMODE)) { - lpid = nested ? nested->shadow_lpid : kvm->arch.lpid; - mtspr(SPRN_LPID, lpid); - isync(); - kvmppc_check_need_tlb_flush(kvm, pcpu, nested); - } - guest_enter_irqoff(); srcu_idx = srcu_read_lock(&kvm->srcu);
Switching the MMU from radix<->radix mode is tricky particularly as the MMU can remain enabled and requires a certain sequence of SPR updates. Move these together into their own functions. This also includes the radix TLB check / flush because it's tied in to MMU switching due to tlbiel getting LPID from LPIDR. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- arch/powerpc/kvm/book3s_hv.c | 50 +++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-)