GNU Linux-libre 5.15.72-gnu
[releases.git] / arch / powerpc / kvm / book3s_64_slb.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *
4  * Copyright SUSE Linux Products GmbH 2009
5  *
6  * Authors: Alexander Graf <agraf@suse.de>
7  */
8
9 #include <asm/asm-compat.h>
10 #include <asm/feature-fixups.h>
11
12 #define SHADOW_SLB_ENTRY_LEN    0x10
13 #define OFFSET_ESID(x)          (SHADOW_SLB_ENTRY_LEN * x)
14 #define OFFSET_VSID(x)          ((SHADOW_SLB_ENTRY_LEN * x) + 8)
15
16 /******************************************************************************
17  *                                                                            *
18  *                               Entry code                                   *
19  *                                                                            *
20  *****************************************************************************/
21
22 .macro LOAD_GUEST_SEGMENTS
23
24         /* Required state:
25          *
26          * MSR = ~IR|DR
27          * R13 = PACA
28          * R1 = host R1
29          * R2 = host R2
30          * R3 = shadow vcpu
31          * all other volatile GPRS = free except R4, R6
32          * SVCPU[CR]  = guest CR
33          * SVCPU[XER] = guest XER
34          * SVCPU[CTR] = guest CTR
35          * SVCPU[LR]  = guest LR
36          */
37
38 BEGIN_FW_FTR_SECTION
39
40         /* Declare SLB shadow as 0 entries big */
41
42         ld      r11, PACA_SLBSHADOWPTR(r13)
43         li      r8, 0
44         stb     r8, 3(r11)
45
46 END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR)
47
48         /* Flush SLB */
49
50         li      r10, 0
51         slbmte  r10, r10
52         slbia
53
54         /* Fill SLB with our shadow */
55
56         lbz     r12, SVCPU_SLB_MAX(r3)
57         mulli   r12, r12, 16
58         addi    r12, r12, SVCPU_SLB
59         add     r12, r12, r3
60
61         /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
62         li      r11, SVCPU_SLB
63         add     r11, r11, r3
64
65 slb_loop_enter:
66
67         ld      r10, 0(r11)
68
69         andis.  r9, r10, SLB_ESID_V@h
70         beq     slb_loop_enter_skip
71
72         ld      r9, 8(r11)
73         slbmte  r9, r10
74
75 slb_loop_enter_skip:
76         addi    r11, r11, 16
77         cmpd    cr0, r11, r12
78         blt     slb_loop_enter
79
80 slb_do_enter:
81
82 .endm
83
84 /******************************************************************************
85  *                                                                            *
86  *                               Exit code                                    *
87  *                                                                            *
88  *****************************************************************************/
89
90 .macro LOAD_HOST_SEGMENTS
91
92         /* Register usage at this point:
93          *
94          * R1         = host R1
95          * R2         = host R2
96          * R12        = exit handler id
97          * R13        = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64]
98          * SVCPU.*    = guest *
99          * SVCPU[CR]  = guest CR
100          * SVCPU[XER] = guest XER
101          * SVCPU[CTR] = guest CTR
102          * SVCPU[LR]  = guest LR
103          *
104          */
105
106         /* Remove all SLB entries that are in use. */
107
108         li      r0, 0
109         slbmte  r0, r0
110         slbia
111
112         /* Restore bolted entries from the shadow */
113
114         ld      r11, PACA_SLBSHADOWPTR(r13)
115
116 BEGIN_FW_FTR_SECTION
117
118         /* Declare SLB shadow as SLB_NUM_BOLTED entries big */
119
120         li      r8, SLB_NUM_BOLTED
121         stb     r8, 3(r11)
122
123 END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR)
124
125         /* Manually load all entries from shadow SLB */
126
127         li      r8, SLBSHADOW_SAVEAREA
128         li      r7, SLBSHADOW_SAVEAREA + 8
129
130         .rept   SLB_NUM_BOLTED
131         LDX_BE  r10, r11, r8
132         cmpdi   r10, 0
133         beq     1f
134         LDX_BE  r9, r11, r7
135         slbmte  r9, r10
136 1:      addi    r7, r7, SHADOW_SLB_ENTRY_LEN
137         addi    r8, r8, SHADOW_SLB_ENTRY_LEN
138         .endr
139
140         isync
141         sync
142
143 slb_do_exit:
144
145 .endm