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