Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/kvm/book3s_rmhandlers.S
26424 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
*
4
* Copyright SUSE Linux Products GmbH 2009
5
*
6
* Authors: Alexander Graf <[email protected]>
7
*/
8
9
#include <asm/ppc_asm.h>
10
#include <asm/kvm_asm.h>
11
#include <asm/reg.h>
12
#include <asm/mmu.h>
13
#include <asm/page.h>
14
#include <asm/asm-offsets.h>
15
#include <asm/asm-compat.h>
16
17
#ifdef CONFIG_PPC_BOOK3S_64
18
#include <asm/exception-64s.h>
19
#endif
20
21
/*****************************************************************************
22
* *
23
* Real Mode handlers that need to be in low physical memory *
24
* *
25
****************************************************************************/
26
27
#if defined(CONFIG_PPC_BOOK3S_64)
28
29
#ifdef CONFIG_PPC64_ELF_ABI_V2
30
#define FUNC(name) name
31
#else
32
#define FUNC(name) GLUE(.,name)
33
#endif
34
35
#elif defined(CONFIG_PPC_BOOK3S_32)
36
37
#define FUNC(name) name
38
39
#define RFI_TO_KERNEL rfi
40
#define RFI_TO_GUEST rfi
41
42
.macro INTERRUPT_TRAMPOLINE intno
43
44
.global kvmppc_trampoline_\intno
45
kvmppc_trampoline_\intno:
46
47
mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */
48
49
/*
50
* First thing to do is to find out if we're coming
51
* from a KVM guest or a Linux process.
52
*
53
* To distinguish, we check a magic byte in the PACA/current
54
*/
55
mfspr r13, SPRN_SPRG_THREAD
56
lwz r13, THREAD_KVM_SVCPU(r13)
57
/* PPC32 can have a NULL pointer - let's check for that */
58
mtspr SPRN_SPRG_SCRATCH1, r12 /* Save r12 */
59
mfcr r12
60
cmpwi r13, 0
61
bne 1f
62
2: mtcr r12
63
mfspr r12, SPRN_SPRG_SCRATCH1
64
mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */
65
b kvmppc_resume_\intno /* Get back original handler */
66
67
1: tophys(r13, r13)
68
stw r12, HSTATE_SCRATCH1(r13)
69
mfspr r12, SPRN_SPRG_SCRATCH1
70
stw r12, HSTATE_SCRATCH0(r13)
71
lbz r12, HSTATE_IN_GUEST(r13)
72
cmpwi r12, KVM_GUEST_MODE_NONE
73
bne ..kvmppc_handler_hasmagic_\intno
74
/* No KVM guest? Then jump back to the Linux handler! */
75
lwz r12, HSTATE_SCRATCH1(r13)
76
b 2b
77
78
/* Now we know we're handling a KVM guest */
79
..kvmppc_handler_hasmagic_\intno:
80
81
/* Should we just skip the faulting instruction? */
82
cmpwi r12, KVM_GUEST_MODE_SKIP
83
beq kvmppc_handler_skip_ins
84
85
/* Let's store which interrupt we're handling */
86
li r12, \intno
87
88
/* Jump into the SLB exit code that goes to the highmem handler */
89
b kvmppc_handler_trampoline_exit
90
91
.endm
92
93
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET
94
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK
95
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE
96
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE
97
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL
98
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT
99
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM
100
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL
101
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER
102
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL
103
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE
104
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON
105
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
106
107
/*
108
* Bring us back to the faulting code, but skip the
109
* faulting instruction.
110
*
111
* This is a generic exit path from the interrupt
112
* trampolines above.
113
*
114
* Input Registers:
115
*
116
* R12 = free
117
* R13 = Shadow VCPU (PACA)
118
* HSTATE.SCRATCH0 = guest R12
119
* HSTATE.SCRATCH1 = guest CR
120
* SPRG_SCRATCH0 = guest R13
121
*
122
*/
123
kvmppc_handler_skip_ins:
124
125
/* Patch the IP to the next instruction */
126
/* Note that prefixed instructions are disabled in PR KVM for now */
127
mfsrr0 r12
128
addi r12, r12, 4
129
mtsrr0 r12
130
131
/* Clean up all state */
132
lwz r12, HSTATE_SCRATCH1(r13)
133
mtcr r12
134
PPC_LL r12, HSTATE_SCRATCH0(r13)
135
GET_SCRATCH0(r13)
136
137
/* And get back into the code */
138
RFI_TO_KERNEL
139
#endif
140
141
/*
142
* Call kvmppc_handler_trampoline_enter in real mode
143
*
144
* On entry, r4 contains the guest shadow MSR
145
* MSR.EE has to be 0 when calling this function
146
*/
147
_GLOBAL_TOC(kvmppc_entry_trampoline)
148
mfmsr r5
149
LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
150
toreal(r7)
151
152
li r6, MSR_IR | MSR_DR
153
andc r6, r5, r6 /* Clear DR and IR in MSR value */
154
/*
155
* Set EE in HOST_MSR so that it's enabled when we get into our
156
* C exit handler function.
157
*/
158
ori r5, r5, MSR_EE
159
mtsrr0 r7
160
mtsrr1 r6
161
RFI_TO_KERNEL
162
163
#include "book3s_segment.S"
164
165