diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2013-02-07 05:52:10 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2013-06-12 11:42:17 -0400 |
commit | b4afad06c19e3489767532f86ff453a1d1e28b8c (patch) | |
tree | 2c504047919ed9f37d52f154118a7f733bf8d722 | |
parent | 06c7654d2fb8bac7b1af4340ad59434a5d89b86a (diff) |
arm64: KVM: 32bit specific register world switch
Allow registers specific to 32bit guests to be saved/restored
during the world switch.
Reviewed-by: Christopher Covington <cov@codeaurora.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r-- | arch/arm64/kvm/hyp.S | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 8b510835b440..ff985e3d8b72 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S | |||
@@ -266,6 +266,74 @@ __kvm_hyp_code_start: | |||
266 | msr cntkctl_el1, x23 | 266 | msr cntkctl_el1, x23 |
267 | .endm | 267 | .endm |
268 | 268 | ||
269 | .macro skip_32bit_state tmp, target | ||
270 | // Skip 32bit state if not needed | ||
271 | mrs \tmp, hcr_el2 | ||
272 | tbnz \tmp, #HCR_RW_SHIFT, \target | ||
273 | .endm | ||
274 | |||
275 | .macro skip_tee_state tmp, target | ||
276 | // Skip ThumbEE state if not needed | ||
277 | mrs \tmp, id_pfr0_el1 | ||
278 | tbz \tmp, #12, \target | ||
279 | .endm | ||
280 | |||
281 | .macro save_guest_32bit_state | ||
282 | skip_32bit_state x3, 1f | ||
283 | |||
284 | add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT) | ||
285 | mrs x4, spsr_abt | ||
286 | mrs x5, spsr_und | ||
287 | mrs x6, spsr_irq | ||
288 | mrs x7, spsr_fiq | ||
289 | stp x4, x5, [x3] | ||
290 | stp x6, x7, [x3, #16] | ||
291 | |||
292 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) | ||
293 | mrs x4, dacr32_el2 | ||
294 | mrs x5, ifsr32_el2 | ||
295 | mrs x6, fpexc32_el2 | ||
296 | mrs x7, dbgvcr32_el2 | ||
297 | stp x4, x5, [x3] | ||
298 | stp x6, x7, [x3, #16] | ||
299 | |||
300 | skip_tee_state x8, 1f | ||
301 | |||
302 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | ||
303 | mrs x4, teecr32_el1 | ||
304 | mrs x5, teehbr32_el1 | ||
305 | stp x4, x5, [x3] | ||
306 | 1: | ||
307 | .endm | ||
308 | |||
309 | .macro restore_guest_32bit_state | ||
310 | skip_32bit_state x3, 1f | ||
311 | |||
312 | add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT) | ||
313 | ldp x4, x5, [x3] | ||
314 | ldp x6, x7, [x3, #16] | ||
315 | msr spsr_abt, x4 | ||
316 | msr spsr_und, x5 | ||
317 | msr spsr_irq, x6 | ||
318 | msr spsr_fiq, x7 | ||
319 | |||
320 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) | ||
321 | ldp x4, x5, [x3] | ||
322 | ldp x6, x7, [x3, #16] | ||
323 | msr dacr32_el2, x4 | ||
324 | msr ifsr32_el2, x5 | ||
325 | msr fpexc32_el2, x6 | ||
326 | msr dbgvcr32_el2, x7 | ||
327 | |||
328 | skip_tee_state x8, 1f | ||
329 | |||
330 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | ||
331 | ldp x4, x5, [x3] | ||
332 | msr teecr32_el1, x4 | ||
333 | msr teehbr32_el1, x5 | ||
334 | 1: | ||
335 | .endm | ||
336 | |||
269 | .macro activate_traps | 337 | .macro activate_traps |
270 | ldr x2, [x0, #VCPU_IRQ_LINES] | 338 | ldr x2, [x0, #VCPU_IRQ_LINES] |
271 | ldr x1, [x0, #VCPU_HCR_EL2] | 339 | ldr x1, [x0, #VCPU_HCR_EL2] |
@@ -494,6 +562,7 @@ ENTRY(__kvm_vcpu_run) | |||
494 | 562 | ||
495 | bl __restore_sysregs | 563 | bl __restore_sysregs |
496 | bl __restore_fpsimd | 564 | bl __restore_fpsimd |
565 | restore_guest_32bit_state | ||
497 | restore_guest_regs | 566 | restore_guest_regs |
498 | 567 | ||
499 | // That's it, no more messing around. | 568 | // That's it, no more messing around. |
@@ -509,6 +578,7 @@ __kvm_vcpu_return: | |||
509 | save_guest_regs | 578 | save_guest_regs |
510 | bl __save_fpsimd | 579 | bl __save_fpsimd |
511 | bl __save_sysregs | 580 | bl __save_sysregs |
581 | save_guest_32bit_state | ||
512 | 582 | ||
513 | save_timer_state | 583 | save_timer_state |
514 | save_vgic_state | 584 | save_vgic_state |