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
38BEGIN_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
46END_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
65slb_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
75slb_loop_enter_skip:
76 addi r11, r11, 16
77 cmpd cr0, r11, r12
78 blt slb_loop_enter
79
80slb_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
116BEGIN_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
123END_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
1361: addi r7, r7, SHADOW_SLB_ENTRY_LEN
137 addi r8, r8, SHADOW_SLB_ENTRY_LEN
138 .endr
139
140 isync
141 sync
142
143slb_do_exit:
144
145.endm
146

source code of linux/arch/powerpc/kvm/book3s_64_slb.S