These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / arm64 / kvm / vgic-v2-switch.S
1 /*
2  * Copyright (C) 2012,2013 - ARM Ltd
3  * Author: Marc Zyngier <marc.zyngier@arm.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <linux/linkage.h>
19 #include <linux/irqchip/arm-gic.h>
20
21 #include <asm/assembler.h>
22 #include <asm/memory.h>
23 #include <asm/asm-offsets.h>
24 #include <asm/kvm.h>
25 #include <asm/kvm_asm.h>
26 #include <asm/kvm_arm.h>
27 #include <asm/kvm_mmu.h>
28
29         .text
30         .pushsection    .hyp.text, "ax"
31
32 /*
33  * Save the VGIC CPU state into memory
34  * x0: Register pointing to VCPU struct
35  * Do not corrupt x1!!!
36  */
37 ENTRY(__save_vgic_v2_state)
38 __save_vgic_v2_state:
39         /* Get VGIC VCTRL base into x2 */
40         ldr     x2, [x0, #VCPU_KVM]
41         kern_hyp_va     x2
42         ldr     x2, [x2, #KVM_VGIC_VCTRL]
43         kern_hyp_va     x2
44         cbz     x2, 2f          // disabled
45
46         /* Compute the address of struct vgic_cpu */
47         add     x3, x0, #VCPU_VGIC_CPU
48
49         /* Save all interesting registers */
50         ldr     w5, [x2, #GICH_VMCR]
51         ldr     w6, [x2, #GICH_MISR]
52         ldr     w7, [x2, #GICH_EISR0]
53         ldr     w8, [x2, #GICH_EISR1]
54         ldr     w9, [x2, #GICH_ELRSR0]
55         ldr     w10, [x2, #GICH_ELRSR1]
56         ldr     w11, [x2, #GICH_APR]
57 CPU_BE( rev     w5,  w5  )
58 CPU_BE( rev     w6,  w6  )
59 CPU_BE( rev     w7,  w7  )
60 CPU_BE( rev     w8,  w8  )
61 CPU_BE( rev     w9,  w9  )
62 CPU_BE( rev     w10, w10 )
63 CPU_BE( rev     w11, w11 )
64
65         str     w5, [x3, #VGIC_V2_CPU_VMCR]
66         str     w6, [x3, #VGIC_V2_CPU_MISR]
67 CPU_LE( str     w7, [x3, #VGIC_V2_CPU_EISR] )
68 CPU_LE( str     w8, [x3, #(VGIC_V2_CPU_EISR + 4)] )
69 CPU_LE( str     w9, [x3, #VGIC_V2_CPU_ELRSR] )
70 CPU_LE( str     w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
71 CPU_BE( str     w7, [x3, #(VGIC_V2_CPU_EISR + 4)] )
72 CPU_BE( str     w8, [x3, #VGIC_V2_CPU_EISR] )
73 CPU_BE( str     w9, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
74 CPU_BE( str     w10, [x3, #VGIC_V2_CPU_ELRSR] )
75         str     w11, [x3, #VGIC_V2_CPU_APR]
76
77         /* Clear GICH_HCR */
78         str     wzr, [x2, #GICH_HCR]
79
80         /* Save list registers */
81         add     x2, x2, #GICH_LR0
82         ldr     w4, [x3, #VGIC_CPU_NR_LR]
83         add     x3, x3, #VGIC_V2_CPU_LR
84 1:      ldr     w5, [x2], #4
85 CPU_BE( rev     w5, w5 )
86         str     w5, [x3], #4
87         sub     w4, w4, #1
88         cbnz    w4, 1b
89 2:
90         ret
91 ENDPROC(__save_vgic_v2_state)
92
93 /*
94  * Restore the VGIC CPU state from memory
95  * x0: Register pointing to VCPU struct
96  */
97 ENTRY(__restore_vgic_v2_state)
98 __restore_vgic_v2_state:
99         /* Get VGIC VCTRL base into x2 */
100         ldr     x2, [x0, #VCPU_KVM]
101         kern_hyp_va     x2
102         ldr     x2, [x2, #KVM_VGIC_VCTRL]
103         kern_hyp_va     x2
104         cbz     x2, 2f          // disabled
105
106         /* Compute the address of struct vgic_cpu */
107         add     x3, x0, #VCPU_VGIC_CPU
108
109         /* We only restore a minimal set of registers */
110         ldr     w4, [x3, #VGIC_V2_CPU_HCR]
111         ldr     w5, [x3, #VGIC_V2_CPU_VMCR]
112         ldr     w6, [x3, #VGIC_V2_CPU_APR]
113 CPU_BE( rev     w4, w4 )
114 CPU_BE( rev     w5, w5 )
115 CPU_BE( rev     w6, w6 )
116
117         str     w4, [x2, #GICH_HCR]
118         str     w5, [x2, #GICH_VMCR]
119         str     w6, [x2, #GICH_APR]
120
121         /* Restore list registers */
122         add     x2, x2, #GICH_LR0
123         ldr     w4, [x3, #VGIC_CPU_NR_LR]
124         add     x3, x3, #VGIC_V2_CPU_LR
125 1:      ldr     w5, [x3], #4
126 CPU_BE( rev     w5, w5 )
127         str     w5, [x2], #4
128         sub     w4, w4, #1
129         cbnz    w4, 1b
130 2:
131         ret
132 ENDPROC(__restore_vgic_v2_state)
133
134         .popsection