[PATCH v2 2/6] ARM: KVM: introduce {save, restore}_host_regs macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Host and guest registers are saved/restored using the same set
of macros. This makes it quite difficult to modify the layout of
struct kvm_cpu_regs without impacting the stack layout as well
(which is where the host registers are saved).

Introduce a separate set of macros that are used to save and
restore the host registers using the stack, allowing the guest
macros to be rewritten independently in a subsequent patch.

Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
---
 arch/arm/kvm/interrupts.S      | 27 ++---------------
 arch/arm/kvm/interrupts_head.S | 67 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 2bca622..8d11bc0 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -86,22 +86,10 @@ ENDPROC(__kvm_flush_vm_context)
  * int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
  */
 ENTRY(__kvm_vcpu_run)
-	@ Preserve ELR_hyp to return to the HYP trampoline
-	mrs	r1, ELR_hyp
-	push	{r1}
-
 	@ Save the vcpu pointer
 	mcr	p15, 4, r0, c13, c0, 2	@ HTPIDR
 
-	@ Now we're in Hyp-mode and ELR_hyp, spsr_hyp are on the stack
-	store_mode_state sp, usr
-	push	{r4-r12}		@ Push r4-r12
-
-	store_mode_state sp, svc
-	store_mode_state sp, abt
-	store_mode_state sp, und
-	store_mode_state sp, irq
-	store_mode_state sp, fiq
+	save_host_regs
 
 	restore_vgic_state r0
 	restore_timer_state r0
@@ -226,18 +214,7 @@ after_vfp_restore:
 	save_timer_state r1
 	save_vgic_state	r1
 
-	load_mode_state sp, fiq
-	load_mode_state sp, irq
-	load_mode_state sp, und
-	load_mode_state sp, abt
-	load_mode_state sp, svc
-
-	pop	{r4-r12}		@ Pop r4-r12
-	load_mode_state sp, usr		@ SP_usr, LR_usr
-
-	pop	{r2}
-	msr	ELR_hyp, r2
-
+	restore_host_regs
 	clrex				@ Clear exclusive monitor
 	bx	lr			@ return to IOCTL
 
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 514a75a..5b55cd6 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -50,6 +50,73 @@
 .equ irq, 4
 .equ fiq, 5
 
+.macro push_host_regs_mode mode
+	mrs	r2, SP_\mode
+	mrs	r3, LR_\mode
+	mrs	r4, SPSR_\mode
+	push	{r2, r3, r4}
+.endm
+
+.macro save_host_regs
+	/* Hyp regs. Only ELR_hyp (SPSR_hyp already saved) */
+	mrs	r2, ELR_hyp
+	push	{r2}
+
+	/* usr regs */
+	push	{r4-r12}	@ r0-r3 are always clobbered
+	mrs	r2, SP_usr
+	mov	r3, lr
+	push	{r2, r3}
+
+	push_host_regs_mode svc
+	push_host_regs_mode abt
+	push_host_regs_mode und
+	push_host_regs_mode irq
+
+	/* fiq regs */
+	mrs	r2, r8_fiq
+	mrs	r3, r9_fiq
+	mrs	r4, r10_fiq
+	mrs	r5, r11_fiq
+	mrs	r6, r12_fiq
+	mrs	r7, SP_fiq
+	mrs	r8, LR_fiq
+	mrs	r9, SPSR_fiq
+	push	{r2-r9}
+.endm
+
+.macro pop_host_regs_mode mode
+	pop	{r2, r3, r4}
+	msr	SP_\mode, r2
+	msr	LR_\mode, r3
+	msr	SPSR_\mode, r4
+.endm
+
+.macro restore_host_regs
+	pop	{r2-r9}
+	msr	r8_fiq, r2
+	msr	r9_fiq, r3
+	msr	r10_fiq, r4
+	msr	r11_fiq, r5
+	msr	r12_fiq, r6
+	msr	SP_fiq, r7
+	msr	LR_fiq, r8
+	msr	SPSR_fiq, r9
+
+	pop_host_regs_mode irq
+	pop_host_regs_mode und
+	pop_host_regs_mode abt
+	pop_host_regs_mode svc
+
+	pop	{r2, r3}
+	msr	SP_usr, r2
+	mov	lr, r3
+	pop	{r4-r12}
+
+	pop	{r2}
+	msr	ELR_hyp, r2
+.endm
+
 .macro store_mode_state base_reg, mode
 	.if \mode == usr
 	mrs	r2, SP_usr
-- 
1.7.12



_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux