@@ -185,7 +185,7 @@ kvmppc_primary_no_guest:
185
185
or r3, r3, r0
186
186
stwcx. r3, 0 , r6
187
187
bne 1b
188
- /* order napping_threads update vs testing entry_exit_count */
188
+ /* order napping_threads update vs testing entry_exit_map */
189
189
isync
190
190
li r12, 0
191
191
lwz r7, VCORE_ENTRY_EXIT(r5)
@@ -406,19 +406,21 @@ kvmppc_hv_entry:
406
406
* We don't have to lock against concurrent tlbies,
407
407
* but we do have to coordinate across hardware threads.
408
408
*/
409
- /* Increment entry count iff exit count is zero. */
410
- ld r5,HSTATE_KVM_VCORE(r13)
411
- addi r9,r5,VCORE_ENTRY_EXIT
412
- 21: lwarx r3,0 ,r9
413
- cmpwi r3,0x100 /* any threads starting to exit? */
409
+ /* Set bit in entry map iff exit map is zero. */
410
+ ld r5, HSTATE_KVM_VCORE(r13)
411
+ li r7, 1
412
+ lbz r6, HSTATE_PTID(r13)
413
+ sld r7, r7, r6
414
+ addi r9, r5, VCORE_ENTRY_EXIT
415
+ 21: lwarx r3, 0 , r9
416
+ cmpwi r3, 0x100 /* any threads starting to exit? */
414
417
bge secondary_too_late /* if so we're too late to the party */
415
- addi r3,r3,1
416
- stwcx. r3,0 , r9
418
+ or r3, r3, r7
419
+ stwcx. r3, 0 , r9
417
420
bne 21b
418
421
419
422
/* Primary thread switches to guest partition. */
420
423
ld r9,VCORE_KVM(r5) /* pointer to struct kvm */
421
- lbz r6,HSTATE_PTID(r13)
422
424
cmpwi r6,0
423
425
bne 20f
424
426
ld r6,KVM_SDR1(r9)
@@ -1477,13 +1479,16 @@ kvmhv_do_exit: /* r12 = trap, r13 = paca */
1477
1479
* We don't have to lock against tlbies but we do
1478
1480
* have to coordinate the hardware threads.
1479
1481
*/
1480
- /* Increment the threads-exiting-guest count in the 0xff00
1481
- bits of vcore->entry_exit_count */
1482
- ld r5,HSTATE_KVM_VCORE(r13)
1483
- addi r6,r5,VCORE_ENTRY_EXIT
1484
- 41: lwarx r3,0 ,r6
1485
- addi r0,r3,0x100
1486
- stwcx. r0,0 ,r6
1482
+ /* Set our bit in the threads-exiting-guest map in the 0xff00
1483
+ bits of vcore->entry_exit_map */
1484
+ ld r5, HSTATE_KVM_VCORE(r13)
1485
+ lbz r4, HSTATE_PTID(r13)
1486
+ li r7, 0x100
1487
+ sld r7, r7, r4
1488
+ addi r6, r5, VCORE_ENTRY_EXIT
1489
+ 41: lwarx r3, 0 , r6
1490
+ or r0, r3, r7
1491
+ stwcx. r0, 0 , r6
1487
1492
bne 41b
1488
1493
isync /* order stwcx. vs. reading napping_threads */
1489
1494
@@ -1492,9 +1497,9 @@ kvmhv_do_exit: /* r12 = trap, r13 = paca */
1492
1497
* up to the kernel or qemu; we can't handle it in real mode.
1493
1498
* Thus we have to do a partition switch, so we have to
1494
1499
* collect the other threads, if we are the first thread
1495
- * to take an interrupt. To do this, we set the HDEC to 0,
1496
- * which causes an HDEC interrupt in all threads within 2ns
1497
- * because the HDEC register is shared between all 4 threads .
1500
+ * to take an interrupt. To do this, we send a message or
1501
+ * IPI to all the threads that have their bit set in the entry
1502
+ * map in vcore->entry_exit_map (other than ourselves) .
1498
1503
* However, we don't need to bother if this is an HDEC
1499
1504
* interrupt, since the other threads will already be on their
1500
1505
* way here in that case.
@@ -1503,17 +1508,8 @@ kvmhv_do_exit: /* r12 = trap, r13 = paca */
1503
1508
bge 43f
1504
1509
cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER
1505
1510
beq 43f
1506
- li r0,0
1507
- mtspr SPRN_HDEC,r0
1508
1511
1509
- /*
1510
- * Send an IPI to any napping threads, since an HDEC interrupt
1511
- * doesn't wake CPUs up from nap.
1512
- */
1513
- lwz r3,VCORE_NAPPING_THREADS(r5)
1514
- lbz r4,HSTATE_PTID(r13)
1515
- li r0,1
1516
- sld r0,r0,r4
1512
+ srwi r0,r7,8
1517
1513
andc. r3,r3,r0 /* no sense IPI'ing ourselves */
1518
1514
beq 43f
1519
1515
/* Order entry/exit update vs. IPIs */
@@ -2091,12 +2087,11 @@ _GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */
2091
2087
addi r6,r5,VCORE_NAPPING_THREADS
2092
2088
31: lwarx r4,0 ,r6
2093
2089
or r4,r4,r0
2094
- PPC_POPCNTW(R7,R4)
2095
- cmpw r7,r8
2096
- bge kvm_cede_exit
2090
+ cmpw r4,r8
2091
+ beq kvm_cede_exit
2097
2092
stwcx. r4,0 ,r6
2098
2093
bne 31b
2099
- /* order napping_threads update vs testing entry_exit_count */
2094
+ /* order napping_threads update vs testing entry_exit_map */
2100
2095
isync
2101
2096
li r0,NAPPING_CEDE
2102
2097
stb r0,HSTATE_NAPPING(r13)
0 commit comments