]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kvm/book3s_hv.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[karo-tx-linux.git] / arch / powerpc / kvm / book3s_hv.c
index aba05bbb3e744b6e516afbe9093923793762040d..7a12edbb61e7c2c9f6851bc0ef01e6b0b398ed83 100644 (file)
@@ -1236,7 +1236,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,
        int core;
        struct kvmppc_vcore *vcore;
 
-       core = id / threads_per_core;
+       core = id / threads_per_subcore;
        if (core >= KVM_MAX_VCORES)
                goto out;
 
@@ -1286,7 +1286,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,
                        init_waitqueue_head(&vcore->wq);
                        vcore->preempt_tb = TB_NIL;
                        vcore->lpcr = kvm->arch.lpcr;
-                       vcore->first_vcpuid = core * threads_per_core;
+                       vcore->first_vcpuid = core * threads_per_subcore;
                        vcore->kvm = kvm;
                }
                kvm->arch.vcores[core] = vcore;
@@ -1476,16 +1476,19 @@ static void kvmppc_wait_for_nap(struct kvmppc_vcore *vc)
 static int on_primary_thread(void)
 {
        int cpu = smp_processor_id();
-       int thr = cpu_thread_in_core(cpu);
+       int thr;
 
-       if (thr)
+       /* Are we on a primary subcore? */
+       if (cpu_thread_in_subcore(cpu))
                return 0;
-       while (++thr < threads_per_core)
+
+       thr = 0;
+       while (++thr < threads_per_subcore)
                if (cpu_online(cpu + thr))
                        return 0;
 
        /* Grab all hw threads so they can't go into the kernel */
-       for (thr = 1; thr < threads_per_core; ++thr) {
+       for (thr = 1; thr < threads_per_subcore; ++thr) {
                if (kvmppc_grab_hwthread(cpu + thr)) {
                        /* Couldn't grab one; let the others go */
                        do {
@@ -1544,15 +1547,18 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
        }
 
        /*
-        * Make sure we are running on thread 0, and that
-        * secondary threads are offline.
+        * Make sure we are running on primary threads, and that secondary
+        * threads are offline.  Also check if the number of threads in this
+        * guest are greater than the current system threads per guest.
         */
-       if (threads_per_core > 1 && !on_primary_thread()) {
+       if ((threads_per_core > 1) &&
+           ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) {
                list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)
                        vcpu->arch.ret = -EBUSY;
                goto out;
        }
 
+
        vc->pcpu = smp_processor_id();
        list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
                kvmppc_start_thread(vcpu);
@@ -1580,7 +1586,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
        /* wait for secondary threads to finish writing their state to memory */
        if (vc->nap_count < vc->n_woken)
                kvmppc_wait_for_nap(vc);
-       for (i = 0; i < threads_per_core; ++i)
+       for (i = 0; i < threads_per_subcore; ++i)
                kvmppc_release_hwthread(vc->pcpu + i);
        /* prevent other vcpu threads from doing kvmppc_start_thread() now */
        vc->vcore_state = VCORE_EXITING;
@@ -2305,10 +2311,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
        spin_lock_init(&kvm->arch.slot_phys_lock);
 
        /*
-        * Don't allow secondary CPU threads to come online
-        * while any KVM VMs exist.
+        * Track that we now have a HV mode VM active. This blocks secondary
+        * CPU threads from coming online.
         */
-       inhibit_secondary_onlining();
+       kvm_hv_vm_activated();
 
        return 0;
 }
@@ -2324,7 +2330,7 @@ static void kvmppc_free_vcores(struct kvm *kvm)
 
 static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
 {
-       uninhibit_secondary_onlining();
+       kvm_hv_vm_deactivated();
 
        kvmppc_free_vcores(kvm);
        if (kvm->arch.rma) {