Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: e500mc: Add support for single threaded vcpus on e6500 core

ePAPR represents hardware threads as cpu node properties in device tree.
So with existing QEMU, hardware threads are simply exposed as vcpus with
one hardware thread.

The e6500 core shares TLBs between hardware threads. Without tlb write
conditional instruction, the Linux kernel uses per core mechanisms to
protect against duplicate TLB entries.

The guest is unable to detect real siblings threads, so it can't use the
TLB protection mechanism. An alternative solution is to use the hypervisor
to allocate different lpids to guest's vcpus that runs simultaneous on real
siblings threads. On systems with two threads per core this patch halves
the size of the lpid pool that the allocator sees and use two lpids per VM.
Use even numbers to speedup vcpu lpid computation with consecutive lpids
per VM: vm1 will use lpids 2 and 3, vm2 lpids 4 and 5, and so on.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
[agraf: fix spelling]
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Mihai Caraman and committed by
Alexander Graf
188e267c 9333e6c4

+65 -24
+4 -1
arch/powerpc/include/asm/kvm_booke.h
··· 23 23 #include <linux/types.h> 24 24 #include <linux/kvm_host.h> 25 25 26 - /* LPIDs we support with this build -- runtime limit may be lower */ 26 + /* 27 + * Number of available lpids. Only the low-order 6 bits of LPID rgister are 28 + * implemented on e500mc+ cores. 29 + */ 27 30 #define KVMPPC_NR_LPIDS 64 28 31 29 32 #define KVMPPC_INST_EHPRIV 0x7c00021c
+20
arch/powerpc/kvm/e500.h
··· 22 22 #include <linux/kvm_host.h> 23 23 #include <asm/mmu-book3e.h> 24 24 #include <asm/tlb.h> 25 + #include <asm/cputhreads.h> 25 26 26 27 enum vcpu_ftr { 27 28 VCPU_FTR_MMU_V2 ··· 290 289 #define kvmppc_e500_get_tlb_stid(vcpu, gtlbe) get_tlb_tid(gtlbe) 291 290 #define get_tlbmiss_tid(vcpu) get_cur_pid(vcpu) 292 291 #define get_tlb_sts(gtlbe) (gtlbe->mas1 & MAS1_TS) 292 + 293 + /* 294 + * These functions should be called with preemption disabled 295 + * and the returned value is valid only in that context 296 + */ 297 + static inline int get_thread_specific_lpid(int vm_lpid) 298 + { 299 + int vcpu_lpid = vm_lpid; 300 + 301 + if (threads_per_core == 2) 302 + vcpu_lpid |= smp_processor_id() & 1; 303 + 304 + return vcpu_lpid; 305 + } 306 + 307 + static inline int get_lpid(struct kvm_vcpu *vcpu) 308 + { 309 + return get_thread_specific_lpid(vcpu->kvm->arch.lpid); 310 + } 293 311 #else 294 312 unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu, 295 313 struct kvm_book3e_206_tlb_entry *gtlbe);
+8 -10
arch/powerpc/kvm/e500_mmu_host.c
··· 69 69 * writing shadow tlb entry to host TLB 70 70 */ 71 71 static inline void __write_host_tlbe(struct kvm_book3e_206_tlb_entry *stlbe, 72 - uint32_t mas0) 72 + uint32_t mas0, 73 + uint32_t lpid) 73 74 { 74 75 unsigned long flags; 75 76 ··· 81 80 mtspr(SPRN_MAS3, (u32)stlbe->mas7_3); 82 81 mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32)); 83 82 #ifdef CONFIG_KVM_BOOKE_HV 84 - mtspr(SPRN_MAS8, stlbe->mas8); 83 + mtspr(SPRN_MAS8, MAS8_TGS | get_thread_specific_lpid(lpid)); 85 84 #endif 86 85 asm volatile("isync; tlbwe" : : : "memory"); 87 86 ··· 130 129 131 130 if (tlbsel == 0) { 132 131 mas0 = get_host_mas0(stlbe->mas2); 133 - __write_host_tlbe(stlbe, mas0); 132 + __write_host_tlbe(stlbe, mas0, vcpu_e500->vcpu.kvm->arch.lpid); 134 133 } else { 135 134 __write_host_tlbe(stlbe, 136 135 MAS0_TLBSEL(1) | 137 - MAS0_ESEL(to_htlb1_esel(sesel))); 136 + MAS0_ESEL(to_htlb1_esel(sesel)), 137 + vcpu_e500->vcpu.kvm->arch.lpid); 138 138 } 139 139 } 140 140 ··· 178 176 MAS3_SW | MAS3_SR | MAS3_UW | MAS3_UR; 179 177 magic.mas8 = 0; 180 178 181 - __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index)); 179 + __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index), 0); 182 180 preempt_enable(); 183 181 } 184 182 #endif ··· 319 317 stlbe->mas2 = (gvaddr & MAS2_EPN) | (ref->flags & E500_TLB_MAS2_ATTR); 320 318 stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) | 321 319 e500_shadow_mas3_attrib(gtlbe->mas7_3, pr); 322 - 323 - #ifdef CONFIG_KVM_BOOKE_HV 324 - stlbe->mas8 = MAS8_TGS | vcpu->kvm->arch.lpid; 325 - #endif 326 320 } 327 321 328 322 static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, ··· 631 633 632 634 local_irq_save(flags); 633 635 mtspr(SPRN_MAS6, (vcpu->arch.pid << MAS6_SPID_SHIFT) | addr_space); 634 - mtspr(SPRN_MAS5, MAS5_SGS | vcpu->kvm->arch.lpid); 636 + mtspr(SPRN_MAS5, MAS5_SGS | get_lpid(vcpu)); 635 637 asm volatile("tlbsx 0, %[geaddr]\n" : : 636 638 [geaddr] "r" (geaddr)); 637 639 mtspr(SPRN_MAS5, 0);
+33 -13
arch/powerpc/kvm/e500mc.c
··· 48 48 return; 49 49 } 50 50 51 - 52 - tag = PPC_DBELL_LPID(vcpu->kvm->arch.lpid) | vcpu->vcpu_id; 51 + preempt_disable(); 52 + tag = PPC_DBELL_LPID(get_lpid(vcpu)) | vcpu->vcpu_id; 53 53 mb(); 54 54 ppc_msgsnd(dbell_type, 0, tag); 55 + preempt_enable(); 55 56 } 56 57 57 58 /* gtlbe must not be mapped by more than one host tlb entry */ ··· 61 60 { 62 61 unsigned int tid, ts; 63 62 gva_t eaddr; 64 - u32 val, lpid; 63 + u32 val; 65 64 unsigned long flags; 66 65 67 66 ts = get_tlb_ts(gtlbe); 68 67 tid = get_tlb_tid(gtlbe); 69 - lpid = vcpu_e500->vcpu.kvm->arch.lpid; 70 68 71 69 /* We search the host TLB to invalidate its shadow TLB entry */ 72 70 val = (tid << 16) | ts; ··· 74 74 local_irq_save(flags); 75 75 76 76 mtspr(SPRN_MAS6, val); 77 - mtspr(SPRN_MAS5, MAS5_SGS | lpid); 77 + mtspr(SPRN_MAS5, MAS5_SGS | get_lpid(&vcpu_e500->vcpu)); 78 78 79 79 asm volatile("tlbsx 0, %[eaddr]\n" : : [eaddr] "r" (eaddr)); 80 80 val = mfspr(SPRN_MAS1); ··· 95 95 unsigned long flags; 96 96 97 97 local_irq_save(flags); 98 - mtspr(SPRN_MAS5, MAS5_SGS | vcpu_e500->vcpu.kvm->arch.lpid); 98 + mtspr(SPRN_MAS5, MAS5_SGS | get_lpid(&vcpu_e500->vcpu)); 99 99 asm volatile("tlbilxlpid"); 100 100 mtspr(SPRN_MAS5, 0); 101 101 local_irq_restore(flags); ··· 110 110 { 111 111 } 112 112 113 + /* We use two lpids per VM */ 113 114 static DEFINE_PER_CPU(struct kvm_vcpu *[KVMPPC_NR_LPIDS], last_vcpu_of_lpid); 114 115 115 116 static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) ··· 119 118 120 119 kvmppc_booke_vcpu_load(vcpu, cpu); 121 120 122 - mtspr(SPRN_LPID, vcpu->kvm->arch.lpid); 121 + mtspr(SPRN_LPID, get_lpid(vcpu)); 123 122 mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr); 124 123 mtspr(SPRN_GPIR, vcpu->vcpu_id); 125 124 mtspr(SPRN_MSRP, vcpu->arch.shadow_msrp); 125 + vcpu->arch.eplc = EPC_EGS | (get_lpid(vcpu) << EPC_ELPID_SHIFT); 126 + vcpu->arch.epsc = vcpu->arch.eplc; 126 127 mtspr(SPRN_EPLC, vcpu->arch.eplc); 127 128 mtspr(SPRN_EPSC, vcpu->arch.epsc); 128 129 ··· 144 141 mtspr(SPRN_GESR, vcpu->arch.shared->esr); 145 142 146 143 if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || 147 - __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] != vcpu) { 144 + __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] != vcpu) { 148 145 kvmppc_e500_tlbil_all(vcpu_e500); 149 - __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] = vcpu; 146 + __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] = vcpu; 150 147 } 151 148 } 152 149 ··· 196 193 vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM; 197 194 #endif 198 195 vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_PMMP; 199 - vcpu->arch.eplc = EPC_EGS | (vcpu->kvm->arch.lpid << EPC_ELPID_SHIFT); 200 - vcpu->arch.epsc = vcpu->arch.eplc; 201 196 202 197 vcpu->arch.pvr = mfspr(SPRN_PVR); 203 198 vcpu_e500->svr = mfspr(SPRN_SVR); ··· 355 354 if (lpid < 0) 356 355 return lpid; 357 356 357 + /* 358 + * Use two lpids per VM on cores with two threads like e6500. Use 359 + * even numbers to speedup vcpu lpid computation with consecutive lpids 360 + * per VM. vm1 will use lpids 2 and 3, vm2 lpids 4 and 5, and so on. 361 + */ 362 + if (threads_per_core == 2) 363 + lpid <<= 1; 364 + 358 365 kvm->arch.lpid = lpid; 359 366 return 0; 360 367 } 361 368 362 369 static void kvmppc_core_destroy_vm_e500mc(struct kvm *kvm) 363 370 { 364 - kvmppc_free_lpid(kvm->arch.lpid); 371 + int lpid = kvm->arch.lpid; 372 + 373 + if (threads_per_core == 2) 374 + lpid >>= 1; 375 + 376 + kvmppc_free_lpid(lpid); 365 377 } 366 378 367 379 static struct kvmppc_ops kvm_ops_e500mc = { ··· 402 388 if (r) 403 389 goto err_out; 404 390 405 - kvmppc_init_lpid(64); 391 + /* 392 + * Use two lpids per VM on dual threaded processors like e6500 393 + * to workarround the lack of tlb write conditional instruction. 394 + * Expose half the number of available hardware lpids to the lpid 395 + * allocator. 396 + */ 397 + kvmppc_init_lpid(KVMPPC_NR_LPIDS/threads_per_core); 406 398 kvmppc_claim_lpid(0); /* host */ 407 399 408 400 r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);