aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-01-15 08:49:10 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:35:52 -0500
commitd5e528136cda31a32ff7d1eaa8d06220eb443781 (patch)
tree07a90874f9885e26e2089f4cdf473675d01859a9 /arch/powerpc
parentfbad5f1dfdd097ca282ee3a796986e11eb5a971f (diff)
KVM: PPC: Add helper functions to call real mode loaders
Linux contains quite some bits of code to load FPU, Altivec and VSX lazily for a task. It calls those bits in real mode, coming from an interrupt handler. For KVM we better reuse those, so let's wrap a bit of trampoline magic around them and then we can call them from normal module code. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h3
-rw-r--r--arch/powerpc/kvm/book3s_64_exports.c7
-rw-r--r--arch/powerpc/kvm/book3s_64_rmhandlers.S34
3 files changed, 44 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index c7db69f1e779..e1b441cce416 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -124,6 +124,9 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
124extern u32 kvmppc_trampoline_lowmem; 124extern u32 kvmppc_trampoline_lowmem;
125extern u32 kvmppc_trampoline_enter; 125extern u32 kvmppc_trampoline_enter;
126extern void kvmppc_rmcall(ulong srr0, ulong srr1); 126extern void kvmppc_rmcall(ulong srr0, ulong srr1);
127extern void kvmppc_load_up_fpu(void);
128extern void kvmppc_load_up_altivec(void);
129extern void kvmppc_load_up_vsx(void);
127 130
128static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) 131static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
129{ 132{
diff --git a/arch/powerpc/kvm/book3s_64_exports.c b/arch/powerpc/kvm/book3s_64_exports.c
index 99b07125c529..1dd5a1ddfd0d 100644
--- a/arch/powerpc/kvm/book3s_64_exports.c
+++ b/arch/powerpc/kvm/book3s_64_exports.c
@@ -23,3 +23,10 @@
23EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter); 23EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
24EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem); 24EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
25EXPORT_SYMBOL_GPL(kvmppc_rmcall); 25EXPORT_SYMBOL_GPL(kvmppc_rmcall);
26EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);
27#ifdef CONFIG_ALTIVEC
28EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec);
29#endif
30#ifdef CONFIG_VSX
31EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx);
32#endif
diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S
index e7091c9459a8..c83c60ad96c5 100644
--- a/arch/powerpc/kvm/book3s_64_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_64_rmhandlers.S
@@ -158,6 +158,40 @@ _GLOBAL(kvmppc_rmcall)
158 mtsrr1 r4 158 mtsrr1 r4
159 RFI 159 RFI
160 160
161/*
162 * Activate current's external feature (FPU/Altivec/VSX)
163 */
164#define define_load_up(what) \
165 \
166_GLOBAL(kvmppc_load_up_ ## what); \
167 subi r1, r1, INT_FRAME_SIZE; \
168 mflr r3; \
169 std r3, _LINK(r1); \
170 mfmsr r4; \
171 std r31, GPR3(r1); \
172 mr r31, r4; \
173 li r5, MSR_DR; \
174 oris r5, r5, MSR_EE@h; \
175 andc r4, r4, r5; \
176 mtmsr r4; \
177 \
178 bl .load_up_ ## what; \
179 \
180 mtmsr r31; \
181 ld r3, _LINK(r1); \
182 ld r31, GPR3(r1); \
183 addi r1, r1, INT_FRAME_SIZE; \
184 mtlr r3; \
185 blr
186
187define_load_up(fpu)
188#ifdef CONFIG_ALTIVEC
189define_load_up(altivec)
190#endif
191#ifdef CONFIG_VSX
192define_load_up(vsx)
193#endif
194
161.global kvmppc_trampoline_lowmem 195.global kvmppc_trampoline_lowmem
162kvmppc_trampoline_lowmem: 196kvmppc_trampoline_lowmem:
163 .long kvmppc_handler_lowmem_trampoline - _stext 197 .long kvmppc_handler_lowmem_trampoline - _stext