hnow_v = hpte_new_to_old_v(hnow_v, hnow_r);
hnow_r = hpte_new_to_old_r(hnow_r);
}
- * The synchronization for hpte_setup_done test vs. set is provided
+
+ /*
+ * If the HPT is being resized, don't update the HPTE,
+ * instead let the guest retry after the resize operation is complete.
- if (!kvm->arch.hpte_setup_done)
++ * The synchronization for mmu_ready test vs. set is provided
+ * by the HPTE lock.
+ */
++ if (!kvm->arch.mmu_ready)
+ goto out_unlock;
+
if ((hnow_v & ~HPTE_V_HVLOCK) != hpte[0] || hnow_r != hpte[1] ||
rev->guest_rpte != hpte[2])
/* HPTE has been changed under us; let the guest retry */
* Hard-disable interrupts, and check resched flag and signals.
* If we need to reschedule or deliver a signal, clean up
* and return without going into the guest(s).
- * If the hpte_setup_done flag has been cleared, don't go into the
++ * If the mmu_ready flag has been cleared, don't go into the
+ * guest because that means a HPT resize operation is in progress.
*/
local_irq_disable();
hard_irq_disable();
if (lazy_irq_pending() || need_resched() ||
- recheck_signals(&core_info)) {
- recheck_signals(&core_info) ||
- (!kvm_is_radix(vc->kvm) && !vc->kvm->arch.hpte_setup_done)) {
++ recheck_signals(&core_info) || !vc->kvm->arch.mmu_ready) {
local_irq_enable();
vc->vcore_state = VCORE_INACTIVE;
/* Unlock all except the primary vcore */
while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&
!signal_pending(current)) {
- /* See if the HPT and VRMA are ready to go */
- if (!kvm_is_radix(vcpu->kvm) &&
- !vcpu->kvm->arch.hpte_setup_done) {
++ /* See if the MMU is ready to go */
++ if (!vcpu->kvm->arch.mmu_ready) {
+ spin_unlock(&vc->lock);
- r = kvmppc_hv_setup_htab_rma(vcpu);
++ mutex_lock(&vcpu->kvm->lock);
++ r = 0;
++ if (!vcpu->kvm->arch.mmu_ready) {
++ if (!kvm_is_radix(vcpu->kvm))
++ r = kvmppc_hv_setup_htab_rma(vcpu);
++ if (!r) {
++ if (cpu_has_feature(CPU_FTR_ARCH_300))
++ kvmppc_setup_partition_table(vcpu->kvm);
++ vcpu->kvm->arch.mmu_ready = 1;
++ }
++ }
++ mutex_unlock(&vcpu->kvm->lock);
+ spin_lock(&vc->lock);
+ if (r) {
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ kvm_run->fail_entry.hardware_entry_failure_reason = 0;
+ vcpu->arch.ret = r;
+ break;
+ }
+ }
+
if (vc->vcore_state == VCORE_PREEMPT && vc->runner == NULL)
kvmppc_vcore_end_preempt(vc);
return -EINTR;
}
- atomic_inc(&vcpu->kvm->arch.vcpus_running);
- /* Order vcpus_running vs. hpte_setup_done, see kvmppc_alloc_reset_hpt */
+ kvm = vcpu->kvm;
+ atomic_inc(&kvm->arch.vcpus_running);
+ /* Order vcpus_running vs. mmu_ready, see kvmppc_alloc_reset_hpt */
smp_mb();
- /* On the first time here, set up MMU if necessary */
- if (!vcpu->kvm->arch.mmu_ready) {
- mutex_lock(&kvm->lock);
- r = 0;
- if (!kvm->arch.mmu_ready) {
- if (!kvm_is_radix(vcpu->kvm))
- r = kvmppc_hv_setup_htab_rma(vcpu);
- if (!r) {
- if (cpu_has_feature(CPU_FTR_ARCH_300))
- kvmppc_setup_partition_table(kvm);
- kvm->arch.mmu_ready = 1;
- }
- }
- mutex_unlock(&kvm->lock);
- if (r)
- goto out;
- }
-
flush_all_to_thread(current);
/* Save userspace EBB and other register values */