aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_hv_rmhandlers.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv_rmhandlers.S')
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S92
1 files changed, 54 insertions, 38 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b70bf22a3ff3..d595033bd449 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -26,6 +26,7 @@
26#include <asm/hvcall.h> 26#include <asm/hvcall.h>
27#include <asm/asm-offsets.h> 27#include <asm/asm-offsets.h>
28#include <asm/exception-64s.h> 28#include <asm/exception-64s.h>
29#include <asm/kvm_book3s_asm.h>
29 30
30/***************************************************************************** 31/*****************************************************************************
31 * * 32 * *
@@ -82,6 +83,7 @@ _GLOBAL(kvmppc_hv_entry_trampoline)
82 83
83#define XICS_XIRR 4 84#define XICS_XIRR 4
84#define XICS_QIRR 0xc 85#define XICS_QIRR 0xc
86#define XICS_IPI 2 /* interrupt source # for IPIs */
85 87
86/* 88/*
87 * We come in here when wakened from nap mode on a secondary hw thread. 89 * We come in here when wakened from nap mode on a secondary hw thread.
@@ -94,26 +96,54 @@ kvm_start_guest:
94 subi r1,r1,STACK_FRAME_OVERHEAD 96 subi r1,r1,STACK_FRAME_OVERHEAD
95 ld r2,PACATOC(r13) 97 ld r2,PACATOC(r13)
96 98
97 /* were we napping due to cede? */ 99 li r0,KVM_HWTHREAD_IN_KVM
98 lbz r0,HSTATE_NAPPING(r13) 100 stb r0,HSTATE_HWTHREAD_STATE(r13)
99 cmpwi r0,0
100 bne kvm_end_cede
101 101
102 /* get vcpu pointer */ 102 /* NV GPR values from power7_idle() will no longer be valid */
103 ld r4, HSTATE_KVM_VCPU(r13) 103 li r0,1
104 stb r0,PACA_NAPSTATELOST(r13)
104 105
105 /* We got here with an IPI; clear it */ 106 /* get vcpu pointer, NULL if we have no vcpu to run */
106 ld r5, HSTATE_XICS_PHYS(r13) 107 ld r4,HSTATE_KVM_VCPU(r13)
107 li r0, 0xff 108 cmpdi cr1,r4,0
108 li r6, XICS_QIRR 109
109 li r7, XICS_XIRR 110 /* Check the wake reason in SRR1 to see why we got here */
110 lwzcix r8, r5, r7 /* ack the interrupt */ 111 mfspr r3,SPRN_SRR1
112 rlwinm r3,r3,44-31,0x7 /* extract wake reason field */
113 cmpwi r3,4 /* was it an external interrupt? */
114 bne 27f
115
116 /*
117 * External interrupt - for now assume it is an IPI, since we
118 * should never get any other interrupts sent to offline threads.
119 * Only do this for secondary threads.
120 */
121 beq cr1,25f
122 lwz r3,VCPU_PTID(r4)
123 cmpwi r3,0
124 beq 27f
12525: ld r5,HSTATE_XICS_PHYS(r13)
126 li r0,0xff
127 li r6,XICS_QIRR
128 li r7,XICS_XIRR
129 lwzcix r8,r5,r7 /* get and ack the interrupt */
111 sync 130 sync
112 stbcix r0, r5, r6 /* clear it */ 131 clrldi. r9,r8,40 /* get interrupt source ID. */
113 stwcix r8, r5, r7 /* EOI it */ 132 beq 27f /* none there? */
133 cmpwi r9,XICS_IPI
134 bne 26f
135 stbcix r0,r5,r6 /* clear IPI */
13626: stwcix r8,r5,r7 /* EOI the interrupt */
114 137
115 /* NV GPR values from power7_idle() will no longer be valid */ 13827: /* XXX should handle hypervisor maintenance interrupts etc. here */
116 stb r0, PACA_NAPSTATELOST(r13) 139
140 /* if we have no vcpu to run, go back to sleep */
141 beq cr1,kvm_no_guest
142
143 /* were we napping due to cede? */
144 lbz r0,HSTATE_NAPPING(r13)
145 cmpwi r0,0
146 bne kvm_end_cede
117 147
118.global kvmppc_hv_entry 148.global kvmppc_hv_entry
119kvmppc_hv_entry: 149kvmppc_hv_entry:
@@ -1445,8 +1475,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
1445 * Take a nap until a decrementer or external interrupt occurs, 1475 * Take a nap until a decrementer or external interrupt occurs,
1446 * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR 1476 * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR
1447 */ 1477 */
1448 li r0,0x80 1478 li r0,1
1449 stb r0,PACAPROCSTART(r13) 1479 stb r0,HSTATE_HWTHREAD_REQ(r13)
1450 mfspr r5,SPRN_LPCR 1480 mfspr r5,SPRN_LPCR
1451 ori r5,r5,LPCR_PECE0 | LPCR_PECE1 1481 ori r5,r5,LPCR_PECE0 | LPCR_PECE1
1452 mtspr SPRN_LPCR,r5 1482 mtspr SPRN_LPCR,r5
@@ -1463,26 +1493,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
1463kvm_end_cede: 1493kvm_end_cede:
1464 /* Woken by external or decrementer interrupt */ 1494 /* Woken by external or decrementer interrupt */
1465 ld r1, HSTATE_HOST_R1(r13) 1495 ld r1, HSTATE_HOST_R1(r13)
1466 ld r2, PACATOC(r13)
1467 1496
1468 /* If we're a secondary thread and we got here by an IPI, ack it */
1469 ld r4,HSTATE_KVM_VCPU(r13)
1470 lwz r3,VCPU_PTID(r4)
1471 cmpwi r3,0
1472 beq 27f
1473 mfspr r3,SPRN_SRR1
1474 rlwinm r3,r3,44-31,0x7 /* extract wake reason field */
1475 cmpwi r3,4 /* was it an external interrupt? */
1476 bne 27f
1477 ld r5, HSTATE_XICS_PHYS(r13)
1478 li r0,0xff
1479 li r6,XICS_QIRR
1480 li r7,XICS_XIRR
1481 lwzcix r8,r5,r7 /* ack the interrupt */
1482 sync
1483 stbcix r0,r5,r6 /* clear it */
1484 stwcix r8,r5,r7 /* EOI it */
148527:
1486 /* load up FP state */ 1497 /* load up FP state */
1487 bl kvmppc_load_fp 1498 bl kvmppc_load_fp
1488 1499
@@ -1580,12 +1591,17 @@ secondary_nap:
1580 stwcx. r3, 0, r4 1591 stwcx. r3, 0, r4
1581 bne 51b 1592 bne 51b
1582 1593
1594kvm_no_guest:
1595 li r0, KVM_HWTHREAD_IN_NAP
1596 stb r0, HSTATE_HWTHREAD_STATE(r13)
1597 li r0, 0
1598 std r0, HSTATE_KVM_VCPU(r13)
1599
1583 li r3, LPCR_PECE0 1600 li r3, LPCR_PECE0
1584 mfspr r4, SPRN_LPCR 1601 mfspr r4, SPRN_LPCR
1585 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 1602 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
1586 mtspr SPRN_LPCR, r4 1603 mtspr SPRN_LPCR, r4
1587 isync 1604 isync
1588 li r0, 0
1589 std r0, HSTATE_SCRATCH0(r13) 1605 std r0, HSTATE_SCRATCH0(r13)
1590 ptesync 1606 ptesync
1591 ld r0, HSTATE_SCRATCH0(r13) 1607 ld r0, HSTATE_SCRATCH0(r13)