]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: PPC: Book3S HV: Rename hpte_setup_done to mmu_ready
authorPaul Mackerras <paulus@ozlabs.org>
Wed, 13 Sep 2017 05:53:48 +0000 (15:53 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Wed, 1 Nov 2017 04:36:12 +0000 (15:36 +1100)
This renames the kvm->arch.hpte_setup_done field to mmu_ready because
we will want to use it for radix guests too -- both for setting things
up before vcpu execution, and for excluding vcpus from executing while
MMU-related things get changed, such as in future switching the MMU
from radix to HPT mode or vice-versa.

This also moves the call to kvmppc_setup_partition_table() that was
done in kvmppc_hv_setup_htab_rma() for HPT guests, and the setting
of mmu_ready, into the caller in kvmppc_vcpu_run_hv().

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c

index e372ed871c513b00e78f69898601c598ee5a026b..49493ea5520bc2da960d429820ded0ae94fe14fc 100644 (file)
@@ -276,7 +276,7 @@ struct kvm_arch {
        int tlbie_lock;
        unsigned long lpcr;
        unsigned long vrma_slb_v;
-       int hpte_setup_done;
+       int mmu_ready;
        atomic_t vcpus_running;
        u32 online_vcores;
        atomic_t hpte_mod_interest;
index cc21d3c71a8d6a7374603c7b5b931e656c0cdc44..84728038e943a9c7937e8f8c0a0527b451436db1 100644 (file)
@@ -140,12 +140,12 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
                return -EINVAL;
 
        mutex_lock(&kvm->lock);
-       if (kvm->arch.hpte_setup_done) {
-               kvm->arch.hpte_setup_done = 0;
-               /* order hpte_setup_done vs. vcpus_running */
+       if (kvm->arch.mmu_ready) {
+               kvm->arch.mmu_ready = 0;
+               /* order mmu_ready vs. vcpus_running */
                smp_mb();
                if (atomic_read(&kvm->arch.vcpus_running)) {
-                       kvm->arch.hpte_setup_done = 1;
+                       kvm->arch.mmu_ready = 1;
                        goto out;
                }
        }
@@ -1533,15 +1533,15 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm,
 
        /* This shouldn't be possible */
        ret = -EIO;
-       if (WARN_ON(!kvm->arch.hpte_setup_done))
+       if (WARN_ON(!kvm->arch.mmu_ready))
                goto out_no_hpt;
 
        /* Stop VCPUs from running while we mess with the HPT */
-       kvm->arch.hpte_setup_done = 0;
+       kvm->arch.mmu_ready = 0;
        smp_mb();
 
        /* Boot all CPUs out of the guest so they re-read
-        * hpte_setup_done */
+        * mmu_ready */
        on_each_cpu(resize_hpt_boot_vcpu, NULL, 1);
 
        ret = -ENXIO;
@@ -1564,7 +1564,7 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm,
 
 out:
        /* Let VCPUs run again */
-       kvm->arch.hpte_setup_done = 1;
+       kvm->arch.mmu_ready = 1;
        smp_mb();
 out_no_hpt:
        resize_hpt_release(kvm, resize);
@@ -1802,7 +1802,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
        unsigned long tmp[2];
        ssize_t nb;
        long int err, ret;
-       int hpte_setup;
+       int mmu_ready;
 
        if (!access_ok(VERIFY_READ, buf, count))
                return -EFAULT;
@@ -1811,13 +1811,13 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
 
        /* lock out vcpus from running while we're doing this */
        mutex_lock(&kvm->lock);
-       hpte_setup = kvm->arch.hpte_setup_done;
-       if (hpte_setup) {
-               kvm->arch.hpte_setup_done = 0;  /* temporarily */
-               /* order hpte_setup_done vs. vcpus_running */
+       mmu_ready = kvm->arch.mmu_ready;
+       if (mmu_ready) {
+               kvm->arch.mmu_ready = 0;        /* temporarily */
+               /* order mmu_ready vs. vcpus_running */
                smp_mb();
                if (atomic_read(&kvm->arch.vcpus_running)) {
-                       kvm->arch.hpte_setup_done = 1;
+                       kvm->arch.mmu_ready = 1;
                        mutex_unlock(&kvm->lock);
                        return -EBUSY;
                }
@@ -1870,7 +1870,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
                                       "r=%lx\n", ret, i, v, r);
                                goto out;
                        }
-                       if (!hpte_setup && is_vrma_hpte(v)) {
+                       if (!mmu_ready && is_vrma_hpte(v)) {
                                unsigned long psize = hpte_base_page_size(v, r);
                                unsigned long senc = slb_pgsize_encoding(psize);
                                unsigned long lpcr;
@@ -1879,7 +1879,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
                                        (VRMA_VSID << SLB_VSID_SHIFT_1T);
                                lpcr = senc << (LPCR_VRMASD_SH - 4);
                                kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
-                               hpte_setup = 1;
+                               mmu_ready = 1;
                        }
                        ++i;
                        hptp += 2;
@@ -1895,9 +1895,9 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
        }
 
  out:
-       /* Order HPTE updates vs. hpte_setup_done */
+       /* Order HPTE updates vs. mmu_ready */
        smp_wmb();
-       kvm->arch.hpte_setup_done = hpte_setup;
+       kvm->arch.mmu_ready = mmu_ready;
        mutex_unlock(&kvm->lock);
 
        if (err)
index b3817df58e0e4ac0c9a1601fbb0db4d809065167..f6522075edbe58cae9fb4b438f4d7ca0e27c6863 100644 (file)
@@ -115,6 +115,7 @@ MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
 
 static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
 static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
+static void kvmppc_setup_partition_table(struct kvm *kvm);
 
 static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc,
                int *ip)
@@ -3198,6 +3199,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
        unsigned long ebb_regs[3] = {}; /* shut up GCC */
        unsigned long user_tar = 0;
        unsigned int user_vrsave;
+       struct kvm *kvm;
 
        if (!vcpu->arch.sane) {
                run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
@@ -3235,13 +3237,25 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
                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 HTAB and VRMA */
-       if (!kvm_is_radix(vcpu->kvm) && !vcpu->kvm->arch.hpte_setup_done) {
-               r = kvmppc_hv_setup_htab_rma(vcpu);
+       /* 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;
        }
@@ -3530,6 +3544,10 @@ static void kvmppc_setup_partition_table(struct kvm *kvm)
        mmu_partition_table_set_entry(kvm->arch.lpid, dw0, dw1);
 }
 
+/*
+ * Set up HPT (hashed page table) and RMA (real-mode area).
+ * Must be called with kvm->lock held.
+ */
 static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
 {
        int err = 0;
@@ -3541,10 +3559,6 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
        unsigned long psize, porder;
        int srcu_idx;
 
-       mutex_lock(&kvm->lock);
-       if (kvm->arch.hpte_setup_done)
-               goto out;       /* another vcpu beat us to it */
-
        /* Allocate hashed page table (if not done already) and reset it */
        if (!kvm->arch.hpt.virt) {
                int order = KVM_DEFAULT_HPT_ORDER;
@@ -3603,18 +3617,14 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
                /* the -4 is to account for senc values starting at 0x10 */
                lpcr = senc << (LPCR_VRMASD_SH - 4);
                kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
-       } else {
-               kvmppc_setup_partition_table(kvm);
        }
 
-       /* Order updates to kvm->arch.lpcr etc. vs. hpte_setup_done */
+       /* Order updates to kvm->arch.lpcr etc. vs. mmu_ready */
        smp_wmb();
-       kvm->arch.hpte_setup_done = 1;
        err = 0;
  out_srcu:
        srcu_read_unlock(&kvm->srcu, srcu_idx);
  out:
-       mutex_unlock(&kvm->lock);
        return err;
 
  up_out:
@@ -3769,6 +3779,7 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
         */
        if (radix_enabled()) {
                kvm->arch.radix = 1;
+               kvm->arch.mmu_ready = 1;
                lpcr &= ~LPCR_VPM1;
                lpcr |= LPCR_UPRT | LPCR_GTSE | LPCR_HR;
                ret = kvmppc_init_vm_radix(kvm);