KVM: PPC: Book3S HV P9: Switch to guest MMU context as late as possible
authorNicholas Piggin <npiggin@gmail.com>
Fri, 28 May 2021 09:07:40 +0000 (19:07 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 10 Jun 2021 12:12:14 +0000 (22:12 +1000)
Move MMU context switch as late as reasonably possible to minimise code
running with guest context switched in. This becomes more important when
this code may run in real-mode, with later changes.

Move WARN_ON as early as possible so program check interrupts are less
likely to tangle everything up.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-21-npiggin@gmail.com
arch/powerpc/kvm/book3s_hv_p9_entry.c

index f24a126..0b5bd00 100644 (file)
@@ -138,8 +138,13 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
        if (hdec < 0)
                return BOOK3S_INTERRUPT_HV_DECREMENTER;
 
+       WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_HV);
+       WARN_ON_ONCE(!(vcpu->arch.shregs.msr & MSR_ME));
+
        start_timing(vcpu, &vcpu->arch.rm_entry);
 
+       vcpu->arch.ceded = 0;
+
        if (vc->tb_offset) {
                u64 new_tb = mftb() + vc->tb_offset;
                mtspr(SPRN_TBU40, new_tb);
@@ -188,26 +193,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
 
        mtspr(SPRN_HFSCR, vcpu->arch.hfscr);
 
-       mtspr(SPRN_SPRG0, vcpu->arch.shregs.sprg0);
-       mtspr(SPRN_SPRG1, vcpu->arch.shregs.sprg1);
-       mtspr(SPRN_SPRG2, vcpu->arch.shregs.sprg2);
-       mtspr(SPRN_SPRG3, vcpu->arch.shregs.sprg3);
-
-       mtspr(SPRN_AMOR, ~0UL);
-
-       switch_mmu_to_guest_radix(kvm, vcpu, lpcr);
-
-       /*
-        * P9 suppresses the HDEC exception when LPCR[HDICE] = 0,
-        * so set guest LPCR (with HDICE) before writing HDEC.
-        */
-       mtspr(SPRN_HDEC, hdec);
-
-       vcpu->arch.ceded = 0;
-
-       WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_HV);
-       WARN_ON_ONCE(!(vcpu->arch.shregs.msr & MSR_ME));
-
        mtspr(SPRN_HSRR0, vcpu->arch.regs.nip);
        mtspr(SPRN_HSRR1, (vcpu->arch.shregs.msr & ~MSR_HV) | MSR_ME);
 
@@ -226,6 +211,21 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
         */
        mtspr(SPRN_HDSISR, HDSISR_CANARY);
 
+       mtspr(SPRN_SPRG0, vcpu->arch.shregs.sprg0);
+       mtspr(SPRN_SPRG1, vcpu->arch.shregs.sprg1);
+       mtspr(SPRN_SPRG2, vcpu->arch.shregs.sprg2);
+       mtspr(SPRN_SPRG3, vcpu->arch.shregs.sprg3);
+
+       mtspr(SPRN_AMOR, ~0UL);
+
+       switch_mmu_to_guest_radix(kvm, vcpu, lpcr);
+
+       /*
+        * P9 suppresses the HDEC exception when LPCR[HDICE] = 0,
+        * so set guest LPCR (with HDICE) before writing HDEC.
+        */
+       mtspr(SPRN_HDEC, hdec);
+
        __mtmsrd(0, 1); /* clear RI */
 
        mtspr(SPRN_DAR, vcpu->arch.shregs.dar);