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

KVM: PPC: Make SLB switching code the new segment framework

We just introduced generic segment switching code that only needs to call
small macros to do the actual switching, but keeps most of the entry / exit
code generic.

So let's move the SLB switching code over to use this new mechanism.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>

authored by

Alexander Graf and committed by
Avi Kivity
53e5b8bb b79fcdf6

+25 -160
+24 -159
arch/powerpc/kvm/book3s_64_slb.S
··· 44 44 * * 45 45 *****************************************************************************/ 46 46 47 - .global kvmppc_handler_trampoline_enter 48 - kvmppc_handler_trampoline_enter: 47 + .macro LOAD_GUEST_SEGMENTS 49 48 50 49 /* Required state: 51 50 * ··· 52 53 * R13 = PACA 53 54 * R1 = host R1 54 55 * R2 = host R2 55 - * R9 = guest IP 56 - * R10 = guest MSR 57 - * all other GPRS = free 58 - * PACA[KVM_CR] = guest CR 59 - * PACA[KVM_XER] = guest XER 56 + * R3 = shadow vcpu 57 + * all other volatile GPRS = free 58 + * SVCPU[CR] = guest CR 59 + * SVCPU[XER] = guest XER 60 + * SVCPU[CTR] = guest CTR 61 + * SVCPU[LR] = guest LR 60 62 */ 61 - 62 - mtsrr0 r9 63 - mtsrr1 r10 64 - 65 - /* Activate guest mode, so faults get handled by KVM */ 66 - li r11, KVM_GUEST_MODE_GUEST 67 - stb r11, PACA_KVM_IN_GUEST(r13) 68 63 69 64 /* Remove LPAR shadow entries */ 70 65 ··· 94 101 95 102 /* Fill SLB with our shadow */ 96 103 97 - lbz r12, PACA_KVM_SLB_MAX(r13) 104 + lbz r12, SVCPU_SLB_MAX(r3) 98 105 mulli r12, r12, 16 99 - addi r12, r12, PACA_KVM_SLB 100 - add r12, r12, r13 106 + addi r12, r12, SVCPU_SLB 107 + add r12, r12, r3 101 108 102 109 /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */ 103 - li r11, PACA_KVM_SLB 104 - add r11, r11, r13 110 + li r11, SVCPU_SLB 111 + add r11, r11, r3 105 112 106 113 slb_loop_enter: 107 114 ··· 120 127 121 128 slb_do_enter: 122 129 123 - /* Enter guest */ 124 - 125 - ld r0, (PACA_KVM_R0)(r13) 126 - ld r1, (PACA_KVM_R1)(r13) 127 - ld r2, (PACA_KVM_R2)(r13) 128 - ld r3, (PACA_KVM_R3)(r13) 129 - ld r4, (PACA_KVM_R4)(r13) 130 - ld r5, (PACA_KVM_R5)(r13) 131 - ld r6, (PACA_KVM_R6)(r13) 132 - ld r7, (PACA_KVM_R7)(r13) 133 - ld r8, (PACA_KVM_R8)(r13) 134 - ld r9, (PACA_KVM_R9)(r13) 135 - ld r10, (PACA_KVM_R10)(r13) 136 - ld r12, (PACA_KVM_R12)(r13) 137 - 138 - lwz r11, (PACA_KVM_CR)(r13) 139 - mtcr r11 140 - 141 - lwz r11, (PACA_KVM_XER)(r13) 142 - mtxer r11 143 - 144 - ld r11, (PACA_KVM_R11)(r13) 145 - ld r13, (PACA_KVM_R13)(r13) 146 - 147 - RFI 148 - kvmppc_handler_trampoline_enter_end: 149 - 150 - 130 + .endm 151 131 152 132 /****************************************************************************** 153 133 * * ··· 128 162 * * 129 163 *****************************************************************************/ 130 164 131 - .global kvmppc_handler_trampoline_exit 132 - kvmppc_handler_trampoline_exit: 165 + .macro LOAD_HOST_SEGMENTS 133 166 134 167 /* Register usage at this point: 135 168 * 136 - * SPRG_SCRATCH0 = guest R13 137 - * R12 = exit handler id 138 - * R13 = PACA 139 - * PACA.KVM.SCRATCH0 = guest R12 140 - * PACA.KVM.SCRATCH1 = guest CR 169 + * R1 = host R1 170 + * R2 = host R2 171 + * R12 = exit handler id 172 + * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] 173 + * SVCPU.* = guest * 174 + * SVCPU[CR] = guest CR 175 + * SVCPU[XER] = guest XER 176 + * SVCPU[CTR] = guest CTR 177 + * SVCPU[LR] = guest LR 141 178 * 142 179 */ 143 - 144 - /* Save registers */ 145 - 146 - std r0, PACA_KVM_R0(r13) 147 - std r1, PACA_KVM_R1(r13) 148 - std r2, PACA_KVM_R2(r13) 149 - std r3, PACA_KVM_R3(r13) 150 - std r4, PACA_KVM_R4(r13) 151 - std r5, PACA_KVM_R5(r13) 152 - std r6, PACA_KVM_R6(r13) 153 - std r7, PACA_KVM_R7(r13) 154 - std r8, PACA_KVM_R8(r13) 155 - std r9, PACA_KVM_R9(r13) 156 - std r10, PACA_KVM_R10(r13) 157 - std r11, PACA_KVM_R11(r13) 158 - 159 - /* Restore R1/R2 so we can handle faults */ 160 - ld r1, PACA_KVM_HOST_R1(r13) 161 - ld r2, PACA_KVM_HOST_R2(r13) 162 - 163 - /* Save guest PC and MSR in GPRs */ 164 - mfsrr0 r3 165 - mfsrr1 r4 166 - 167 - /* Get scratch'ed off registers */ 168 - mfspr r9, SPRN_SPRG_SCRATCH0 169 - std r9, PACA_KVM_R13(r13) 170 - 171 - ld r8, PACA_KVM_SCRATCH0(r13) 172 - std r8, PACA_KVM_R12(r13) 173 - 174 - lwz r7, PACA_KVM_SCRATCH1(r13) 175 - stw r7, PACA_KVM_CR(r13) 176 - 177 - /* Save more register state */ 178 - 179 - mfxer r6 180 - stw r6, PACA_KVM_XER(r13) 181 - 182 - mfdar r5 183 - mfdsisr r6 184 - 185 - /* 186 - * In order for us to easily get the last instruction, 187 - * we got the #vmexit at, we exploit the fact that the 188 - * virtual layout is still the same here, so we can just 189 - * ld from the guest's PC address 190 - */ 191 - 192 - /* We only load the last instruction when it's safe */ 193 - cmpwi r12, BOOK3S_INTERRUPT_DATA_STORAGE 194 - beq ld_last_inst 195 - cmpwi r12, BOOK3S_INTERRUPT_PROGRAM 196 - beq ld_last_inst 197 - 198 - b no_ld_last_inst 199 - 200 - ld_last_inst: 201 - /* Save off the guest instruction we're at */ 202 - 203 - /* Set guest mode to 'jump over instruction' so if lwz faults 204 - * we'll just continue at the next IP. */ 205 - li r9, KVM_GUEST_MODE_SKIP 206 - stb r9, PACA_KVM_IN_GUEST(r13) 207 - 208 - /* 1) enable paging for data */ 209 - mfmsr r9 210 - ori r11, r9, MSR_DR /* Enable paging for data */ 211 - mtmsr r11 212 - /* 2) fetch the instruction */ 213 - li r0, KVM_INST_FETCH_FAILED /* In case lwz faults */ 214 - lwz r0, 0(r3) 215 - /* 3) disable paging again */ 216 - mtmsr r9 217 - 218 - no_ld_last_inst: 219 - 220 - /* Unset guest mode */ 221 - li r9, KVM_GUEST_MODE_NONE 222 - stb r9, PACA_KVM_IN_GUEST(r13) 223 180 224 181 /* Restore bolted entries from the shadow and fix it along the way */ 225 182 ··· 164 275 165 276 slb_do_exit: 166 277 167 - /* Register usage at this point: 168 - * 169 - * R0 = guest last inst 170 - * R1 = host R1 171 - * R2 = host R2 172 - * R3 = guest PC 173 - * R4 = guest MSR 174 - * R5 = guest DAR 175 - * R6 = guest DSISR 176 - * R12 = exit handler id 177 - * R13 = PACA 178 - * PACA.KVM.* = guest * 179 - * 180 - */ 181 - 182 - /* RFI into the highmem handler */ 183 - mfmsr r7 184 - ori r7, r7, MSR_IR|MSR_DR|MSR_RI /* Enable paging */ 185 - mtsrr1 r7 186 - ld r8, PACA_KVM_VMHANDLER(r13) /* Highmem handler address */ 187 - mtsrr0 r8 188 - 189 - RFI 190 - kvmppc_handler_trampoline_exit_end: 191 - 278 + .endm
+1 -1
arch/powerpc/kvm/book3s_rmhandlers.S
··· 248 248 kvmppc_trampoline_enter: 249 249 .long kvmppc_handler_trampoline_enter - _stext 250 250 251 - #include "book3s_64_slb.S" 251 + #include "book3s_segment.S"