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

KVM: PPC: Move mtspr/mfspr emulation into own functions

The mtspr/mfspr emulation code became quite big over time. Move it
into its own function so things stay more readable.

Signed-off-by: Alexander Graf <agraf@suse.de>

+121 -100
+121 -100
arch/powerpc/kvm/emulate.c
··· 131 131 return vcpu->arch.dec - jd; 132 132 } 133 133 134 + static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 135 + { 136 + enum emulation_result emulated = EMULATE_DONE; 137 + ulong spr_val = kvmppc_get_gpr(vcpu, rs); 138 + 139 + switch (sprn) { 140 + case SPRN_SRR0: 141 + vcpu->arch.shared->srr0 = spr_val; 142 + break; 143 + case SPRN_SRR1: 144 + vcpu->arch.shared->srr1 = spr_val; 145 + break; 146 + 147 + /* XXX We need to context-switch the timebase for 148 + * watchdog and FIT. */ 149 + case SPRN_TBWL: break; 150 + case SPRN_TBWU: break; 151 + 152 + case SPRN_MSSSR0: break; 153 + 154 + case SPRN_DEC: 155 + vcpu->arch.dec = spr_val; 156 + kvmppc_emulate_dec(vcpu); 157 + break; 158 + 159 + case SPRN_SPRG0: 160 + vcpu->arch.shared->sprg0 = spr_val; 161 + break; 162 + case SPRN_SPRG1: 163 + vcpu->arch.shared->sprg1 = spr_val; 164 + break; 165 + case SPRN_SPRG2: 166 + vcpu->arch.shared->sprg2 = spr_val; 167 + break; 168 + case SPRN_SPRG3: 169 + vcpu->arch.shared->sprg3 = spr_val; 170 + break; 171 + 172 + default: 173 + emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, 174 + spr_val); 175 + if (emulated == EMULATE_FAIL) 176 + printk(KERN_INFO "mtspr: unknown spr " 177 + "0x%x\n", sprn); 178 + break; 179 + } 180 + 181 + kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS); 182 + 183 + return emulated; 184 + } 185 + 186 + static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 187 + { 188 + enum emulation_result emulated = EMULATE_DONE; 189 + ulong spr_val = 0; 190 + 191 + switch (sprn) { 192 + case SPRN_SRR0: 193 + spr_val = vcpu->arch.shared->srr0; 194 + break; 195 + case SPRN_SRR1: 196 + spr_val = vcpu->arch.shared->srr1; 197 + break; 198 + case SPRN_PVR: 199 + spr_val = vcpu->arch.pvr; 200 + break; 201 + case SPRN_PIR: 202 + spr_val = vcpu->vcpu_id; 203 + break; 204 + case SPRN_MSSSR0: 205 + spr_val = 0; 206 + break; 207 + 208 + /* Note: mftb and TBRL/TBWL are user-accessible, so 209 + * the guest can always access the real TB anyways. 210 + * In fact, we probably will never see these traps. */ 211 + case SPRN_TBWL: 212 + spr_val = get_tb() >> 32; 213 + break; 214 + case SPRN_TBWU: 215 + spr_val = get_tb(); 216 + break; 217 + 218 + case SPRN_SPRG0: 219 + spr_val = vcpu->arch.shared->sprg0; 220 + break; 221 + case SPRN_SPRG1: 222 + spr_val = vcpu->arch.shared->sprg1; 223 + break; 224 + case SPRN_SPRG2: 225 + spr_val = vcpu->arch.shared->sprg2; 226 + break; 227 + case SPRN_SPRG3: 228 + spr_val = vcpu->arch.shared->sprg3; 229 + break; 230 + /* Note: SPRG4-7 are user-readable, so we don't get 231 + * a trap. */ 232 + 233 + case SPRN_DEC: 234 + spr_val = kvmppc_get_dec(vcpu, get_tb()); 235 + break; 236 + default: 237 + emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, 238 + &spr_val); 239 + if (unlikely(emulated == EMULATE_FAIL)) { 240 + printk(KERN_INFO "mfspr: unknown spr " 241 + "0x%x\n", sprn); 242 + } 243 + break; 244 + } 245 + 246 + if (emulated == EMULATE_DONE) 247 + kvmppc_set_gpr(vcpu, rt, spr_val); 248 + kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS); 249 + 250 + return emulated; 251 + } 252 + 134 253 /* XXX to do: 135 254 * lhax 136 255 * lhaux ··· 275 156 int sprn = get_sprn(inst); 276 157 enum emulation_result emulated = EMULATE_DONE; 277 158 int advance = 1; 278 - ulong spr_val = 0; 279 159 280 160 /* this default type might be overwritten by subcategories */ 281 161 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); ··· 354 236 break; 355 237 356 238 case OP_31_XOP_MFSPR: 357 - switch (sprn) { 358 - case SPRN_SRR0: 359 - spr_val = vcpu->arch.shared->srr0; 360 - break; 361 - case SPRN_SRR1: 362 - spr_val = vcpu->arch.shared->srr1; 363 - break; 364 - case SPRN_PVR: 365 - spr_val = vcpu->arch.pvr; 366 - break; 367 - case SPRN_PIR: 368 - spr_val = vcpu->vcpu_id; 369 - break; 370 - case SPRN_MSSSR0: 371 - spr_val = 0; 372 - break; 373 - 374 - /* Note: mftb and TBRL/TBWL are user-accessible, so 375 - * the guest can always access the real TB anyways. 376 - * In fact, we probably will never see these traps. */ 377 - case SPRN_TBWL: 378 - spr_val = get_tb() >> 32; 379 - break; 380 - case SPRN_TBWU: 381 - spr_val = get_tb(); 382 - break; 383 - 384 - case SPRN_SPRG0: 385 - spr_val = vcpu->arch.shared->sprg0; 386 - break; 387 - case SPRN_SPRG1: 388 - spr_val = vcpu->arch.shared->sprg1; 389 - break; 390 - case SPRN_SPRG2: 391 - spr_val = vcpu->arch.shared->sprg2; 392 - break; 393 - case SPRN_SPRG3: 394 - spr_val = vcpu->arch.shared->sprg3; 395 - break; 396 - /* Note: SPRG4-7 are user-readable, so we don't get 397 - * a trap. */ 398 - 399 - case SPRN_DEC: 400 - spr_val = kvmppc_get_dec(vcpu, get_tb()); 401 - break; 402 - default: 403 - emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, 404 - &spr_val); 405 - if (unlikely(emulated == EMULATE_FAIL)) { 406 - printk(KERN_INFO "mfspr: unknown spr " 407 - "0x%x\n", sprn); 408 - } 409 - break; 410 - } 411 - kvmppc_set_gpr(vcpu, rt, spr_val); 412 - kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS); 239 + emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt); 413 240 break; 414 241 415 242 case OP_31_XOP_STHX: ··· 371 308 break; 372 309 373 310 case OP_31_XOP_MTSPR: 374 - spr_val = kvmppc_get_gpr(vcpu, rs); 375 - switch (sprn) { 376 - case SPRN_SRR0: 377 - vcpu->arch.shared->srr0 = spr_val; 378 - break; 379 - case SPRN_SRR1: 380 - vcpu->arch.shared->srr1 = spr_val; 381 - break; 382 - 383 - /* XXX We need to context-switch the timebase for 384 - * watchdog and FIT. */ 385 - case SPRN_TBWL: break; 386 - case SPRN_TBWU: break; 387 - 388 - case SPRN_MSSSR0: break; 389 - 390 - case SPRN_DEC: 391 - vcpu->arch.dec = spr_val; 392 - kvmppc_emulate_dec(vcpu); 393 - break; 394 - 395 - case SPRN_SPRG0: 396 - vcpu->arch.shared->sprg0 = spr_val; 397 - break; 398 - case SPRN_SPRG1: 399 - vcpu->arch.shared->sprg1 = spr_val; 400 - break; 401 - case SPRN_SPRG2: 402 - vcpu->arch.shared->sprg2 = spr_val; 403 - break; 404 - case SPRN_SPRG3: 405 - vcpu->arch.shared->sprg3 = spr_val; 406 - break; 407 - 408 - default: 409 - emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, 410 - spr_val); 411 - if (emulated == EMULATE_FAIL) 412 - printk(KERN_INFO "mtspr: unknown spr " 413 - "0x%x\n", sprn); 414 - break; 415 - } 416 - kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS); 311 + emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs); 417 312 break; 418 313 419 314 case OP_31_XOP_DCBI: