There is generic entry framework to handle signals and check for
reschedule etc before entering the guest. Use that framework for
powerpc.

Advantages:
- Less code duplication.
- powerpc kvm now understands NR and NR_lazy bits.
- powerpc can enable HAVE_POSIX_CPU_TIMERS_TASK_WORK, currently the
  powerpc/kvm code doesn't handle TIF_NOTIFY_RESUME.

Testing: No splats seen in below cases.
- Booted KVM guest on PowerVM and PowerNV systems. 
- Ran stress-ng CPU stressors in each above case. 
- On PowerNV host, tried preempt=lazy/full and run stress-ng CPU stressor
  in the KVM guest. 

Signed-off-by: Shrikanth Hegde <sshe...@linux.ibm.com>
---
 arch/powerpc/Kconfig         |  1 +
 arch/powerpc/kvm/book3s_hv.c | 13 +++++++------
 arch/powerpc/kvm/powerpc.c   | 22 ++++++++--------------
 3 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6722625a4..83807ae44 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -299,6 +299,7 @@ config PPC
        select IRQ_DOMAIN
        select IRQ_FORCED_THREADING
        select KASAN_VMALLOC                    if KASAN && EXECMEM
+       select KVM_XFER_TO_GUEST_WORK
        select LOCK_MM_AND_FIND_VMA
        select MMU_GATHER_PAGE_SIZE
        select MMU_GATHER_RCU_TABLE_FREE
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 19f4d298d..123539642 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -80,8 +80,8 @@
 #include <asm/ultravisor.h>
 #include <asm/dtl.h>
 #include <asm/plpar_wrappers.h>
-
 #include <trace/events/ipi.h>
+#include <linux/entry-kvm.h>
 
 #include "book3s.h"
 #include "book3s_hv.h"
@@ -4901,7 +4901,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 
time_limit,
        }
 
        if (need_resched())
-               cond_resched();
+               schedule();
 
        kvmppc_update_vpas(vcpu);
 
@@ -5097,10 +5097,11 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu)
                return -EINVAL;
        }
 
-       /* No need to go into the guest when all we'll do is come back out */
-       if (signal_pending(current)) {
-               run->exit_reason = KVM_EXIT_INTR;
-               return -EINTR;
+       /* use generic frameworks to handle signals, need_resched  */
+       if (__xfer_to_guest_mode_work_pending()) {
+               r = xfer_to_guest_mode_handle_work(vcpu);
+               if (r)
+                       return r;
        }
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 153587741..4ff334532 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -34,6 +34,7 @@
 #endif
 #include <asm/ultravisor.h>
 #include <asm/setup.h>
+#include <linux/entry-kvm.h>
 
 #include "timing.h"
 #include "../mm/mmu_decl.h"
@@ -80,24 +81,17 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
 {
        int r;
 
+       /* use generic framework to handle need resched and signals */
+       if (__xfer_to_guest_mode_work_pending()) {
+               r = xfer_to_guest_mode_handle_work(vcpu);
+               if (r)
+                       return r;
+       }
+
        WARN_ON(irqs_disabled());
        hard_irq_disable();
 
        while (true) {
-               if (need_resched()) {
-                       local_irq_enable();
-                       cond_resched();
-                       hard_irq_disable();
-                       continue;
-               }
-
-               if (signal_pending(current)) {
-                       kvmppc_account_exit(vcpu, SIGNAL_EXITS);
-                       vcpu->run->exit_reason = KVM_EXIT_INTR;
-                       r = -EINTR;
-                       break;
-               }
-
                vcpu->mode = IN_GUEST_MODE;
 
                /*
-- 
2.48.1


Reply via email to