Re: [PATCH] KVM: PPC: Book3S PR: Refactor program interrupt related code into separate function

2017-01-27 Thread Paul Mackerras
On Wed, Jan 25, 2017 at 01:27:22PM +0100, Thomas Huth wrote:
> The function kvmppc_handle_exit_pr() is quite huge and thus hard to read,
> and even contains a "spaghetti-code"-like goto between the different case
> labels of the big switch statement. This can be made much more readable
> by moving the code related to injecting program interrupts / instruction
> emulation into a separate function instead.
> 
> Signed-off-by: Thomas Huth 

Thanks, applied to my kvm-ppc-next branch.

Paul.


[PATCH] KVM: PPC: Book3S PR: Refactor program interrupt related code into separate function

2017-01-25 Thread Thomas Huth
The function kvmppc_handle_exit_pr() is quite huge and thus hard to read,
and even contains a "spaghetti-code"-like goto between the different case
labels of the big switch statement. This can be made much more readable
by moving the code related to injecting program interrupts / instruction
emulation into a separate function instead.

Signed-off-by: Thomas Huth 
---
 arch/powerpc/kvm/book3s_pr.c | 130 +--
 1 file changed, 65 insertions(+), 65 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 1482961..d4dfc0c 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -902,6 +902,69 @@ static void kvmppc_clear_debug(struct kvm_vcpu *vcpu)
}
 }
 
+static int kvmppc_exit_pr_progint(struct kvm_run *run, struct kvm_vcpu *vcpu,
+ unsigned int exit_nr)
+{
+   enum emulation_result er;
+   ulong flags;
+   u32 last_inst;
+   int emul, r;
+
+   /*
+* shadow_srr1 only contains valid flags if we came here via a program
+* exception. The other exceptions (emulation assist, FP unavailable,
+* etc.) do not provide flags in SRR1, so use an illegal-instruction
+* exception when injecting a program interrupt into the guest.
+*/
+   if (exit_nr == BOOK3S_INTERRUPT_PROGRAM)
+   flags = vcpu->arch.shadow_srr1 & 0x1full;
+   else
+   flags = SRR1_PROGILL;
+
+   emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, _inst);
+   if (emul != EMULATE_DONE)
+   return RESUME_GUEST;
+
+   if (kvmppc_get_msr(vcpu) & MSR_PR) {
+#ifdef EXIT_DEBUG
+   pr_info("Userspace triggered 0x700 exception at\n 0x%lx 
(0x%x)\n",
+   kvmppc_get_pc(vcpu), last_inst);
+#endif
+   if ((last_inst & 0xff0007ff) != (INS_DCBZ & 0xfff7)) {
+   kvmppc_core_queue_program(vcpu, flags);
+   return RESUME_GUEST;
+   }
+   }
+
+   vcpu->stat.emulated_inst_exits++;
+   er = kvmppc_emulate_instruction(run, vcpu);
+   switch (er) {
+   case EMULATE_DONE:
+   r = RESUME_GUEST_NV;
+   break;
+   case EMULATE_AGAIN:
+   r = RESUME_GUEST;
+   break;
+   case EMULATE_FAIL:
+   pr_crit("%s: emulation at %lx failed (%08x)\n",
+   __func__, kvmppc_get_pc(vcpu), last_inst);
+   kvmppc_core_queue_program(vcpu, flags);
+   r = RESUME_GUEST;
+   break;
+   case EMULATE_DO_MMIO:
+   run->exit_reason = KVM_EXIT_MMIO;
+   r = RESUME_HOST_NV;
+   break;
+   case EMULATE_EXIT_USER:
+   r = RESUME_HOST_NV;
+   break;
+   default:
+   BUG();
+   }
+
+   return r;
+}
+
 int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
  unsigned int exit_nr)
 {
@@ -1044,71 +1107,8 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
break;
case BOOK3S_INTERRUPT_PROGRAM:
case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
-   {
-   enum emulation_result er;
-   ulong flags;
-   u32 last_inst;
-   int emul;
-
-program_interrupt:
-   /*
-* shadow_srr1 only contains valid flags if we came here via
-* a program exception. The other exceptions (emulation assist,
-* FP unavailable, etc.) do not provide flags in SRR1, so use
-* an illegal-instruction exception when injecting a program
-* interrupt into the guest.
-*/
-   if (exit_nr == BOOK3S_INTERRUPT_PROGRAM)
-   flags = vcpu->arch.shadow_srr1 & 0x1full;
-   else
-   flags = SRR1_PROGILL;
-
-   emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, _inst);
-   if (emul != EMULATE_DONE) {
-   r = RESUME_GUEST;
-   break;
-   }
-
-   if (kvmppc_get_msr(vcpu) & MSR_PR) {
-#ifdef EXIT_DEBUG
-   pr_info("Userspace triggered 0x700 exception at\n 0x%lx 
(0x%x)\n",
-   kvmppc_get_pc(vcpu), last_inst);
-#endif
-   if ((last_inst & 0xff0007ff) !=
-   (INS_DCBZ & 0xfff7)) {
-   kvmppc_core_queue_program(vcpu, flags);
-   r = RESUME_GUEST;
-   break;
-   }
-   }
-
-   vcpu->stat.emulated_inst_exits++;
-   er = kvmppc_emulate_instruction(run, vcpu);
-   switch (er) {
-   case EMULATE_DONE:
-   r =