|
@@ -1266,7 +1266,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;
|
|
|
|
|
@@ -1305,7 +1305,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;
|
|
@@ -1495,16 +1495,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 {
|
|
@@ -1563,15 +1566,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);
|
|
@@ -1599,7 +1605,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;
|