| From 8fc1a52264317b1b864ca32cf40e1c10c30e337b Mon Sep 17 00:00:00 2001 |
| From: Paul Mackerras <paulus@ozlabs.org> |
| Date: Tue, 27 Aug 2019 11:31:37 +1000 |
| Subject: [PATCH] KVM: PPC: Book3S HV: Check for MMU ready on piggybacked |
| virtual cores |
| |
| commit d28eafc5a64045c78136162af9d4ba42f8230080 upstream. |
| |
| When we are running multiple vcores on the same physical core, they |
| could be from different VMs and so it is possible that one of the |
| VMs could have its arch.mmu_ready flag cleared (for example by a |
| concurrent HPT resize) when we go to run it on a physical core. |
| We currently check the arch.mmu_ready flag for the primary vcore |
| but not the flags for the other vcores that will be run alongside |
| it. This adds that check, and also a check when we select the |
| secondary vcores from the preempted vcores list. |
| |
| Cc: stable@vger.kernel.org # v4.14+ |
| Fixes: 38c53af85306 ("KVM: PPC: Book3S HV: Fix exclusion between HPT resizing and other HPT updates") |
| Signed-off-by: Paul Mackerras <paulus@ozlabs.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c |
| index cde3f5a4b3e4..36d72e9faddf 100644 |
| --- a/arch/powerpc/kvm/book3s_hv.c |
| +++ b/arch/powerpc/kvm/book3s_hv.c |
| @@ -2860,7 +2860,7 @@ static void collect_piggybacks(struct core_info *cip, int target_threads) |
| if (!spin_trylock(&pvc->lock)) |
| continue; |
| prepare_threads(pvc); |
| - if (!pvc->n_runnable) { |
| + if (!pvc->n_runnable || !pvc->kvm->arch.mmu_ready) { |
| list_del_init(&pvc->preempt_list); |
| if (pvc->runner == NULL) { |
| pvc->vcore_state = VCORE_INACTIVE; |
| @@ -2881,15 +2881,20 @@ static void collect_piggybacks(struct core_info *cip, int target_threads) |
| spin_unlock(&lp->lock); |
| } |
| |
| -static bool recheck_signals(struct core_info *cip) |
| +static bool recheck_signals_and_mmu(struct core_info *cip) |
| { |
| int sub, i; |
| struct kvm_vcpu *vcpu; |
| + struct kvmppc_vcore *vc; |
| |
| - for (sub = 0; sub < cip->n_subcores; ++sub) |
| - for_each_runnable_thread(i, vcpu, cip->vc[sub]) |
| + for (sub = 0; sub < cip->n_subcores; ++sub) { |
| + vc = cip->vc[sub]; |
| + if (!vc->kvm->arch.mmu_ready) |
| + return true; |
| + for_each_runnable_thread(i, vcpu, vc) |
| if (signal_pending(vcpu->arch.run_task)) |
| return true; |
| + } |
| return false; |
| } |
| |
| @@ -3119,7 +3124,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) |
| local_irq_disable(); |
| hard_irq_disable(); |
| if (lazy_irq_pending() || need_resched() || |
| - recheck_signals(&core_info) || !vc->kvm->arch.mmu_ready) { |
| + recheck_signals_and_mmu(&core_info)) { |
| local_irq_enable(); |
| vc->vcore_state = VCORE_INACTIVE; |
| /* Unlock all except the primary vcore */ |
| -- |
| 2.7.4 |
| |