aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLiu Yu-B13201 <Yu.Liu@freescale.com>2012-03-15 06:52:13 -0400
committerAlexander Graf <agraf@suse.de>2012-05-30 05:43:10 -0400
commit2e1ae9c07df5956ebab19144aa0da58ea37c9f69 (patch)
tree5ec9b74d22b72af3691897921ca6bce76ea7d4aa /arch/powerpc
parentb48b2c3e50433ff6f7e46186daa7f986bd960215 (diff)
KVM: PPC: Factor out guest epapr initialization
epapr paravirtualization support is now a Kconfig selectable option Signed-off-by: Liu Yu <yu.liu@freescale.com> [stuart.yoder@freescale.com: misc minor fixes, description update] Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/epapr_hcalls.h2
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/epapr_hcalls.S25
-rw-r--r--arch/powerpc/kernel/epapr_paravirt.c52
-rw-r--r--arch/powerpc/kernel/kvm.c28
-rw-r--r--arch/powerpc/kernel/kvm_emul.S10
-rw-r--r--arch/powerpc/platforms/Kconfig9
7 files changed, 92 insertions, 35 deletions
diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h
index 976835d8f22e..bf2c06c33871 100644
--- a/arch/powerpc/include/asm/epapr_hcalls.h
+++ b/arch/powerpc/include/asm/epapr_hcalls.h
@@ -153,6 +153,8 @@
153#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" 153#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
154#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" 154#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
155 155
156extern bool epapr_paravirt_enabled;
157extern u32 epapr_hypercall_start[];
156 158
157/* 159/*
158 * We use "uintptr_t" to define a register because it's guaranteed to be a 160 * We use "uintptr_t" to define a register because it's guaranteed to be a
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 83afacd3ba7b..bb282dd81612 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -128,6 +128,7 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
128obj-y += ppc_save_regs.o 128obj-y += ppc_save_regs.o
129endif 129endif
130 130
131obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o
131obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o 132obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
132 133
133# Disable GCOV in odd or sensitive code 134# Disable GCOV in odd or sensitive code
diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S
new file mode 100644
index 000000000000..697b390ebfd8
--- /dev/null
+++ b/arch/powerpc/kernel/epapr_hcalls.S
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/threads.h>
11#include <asm/reg.h>
12#include <asm/page.h>
13#include <asm/cputable.h>
14#include <asm/thread_info.h>
15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h>
17
18/* Hypercall entry point. Will be patched with device tree instructions. */
19.global epapr_hypercall_start
20epapr_hypercall_start:
21 li r3, -1
22 nop
23 nop
24 nop
25 blr
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c
new file mode 100644
index 000000000000..028aeae370b6
--- /dev/null
+++ b/arch/powerpc/kernel/epapr_paravirt.c
@@ -0,0 +1,52 @@
1/*
2 * ePAPR para-virtualization support.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 *
17 * Copyright (C) 2012 Freescale Semiconductor, Inc.
18 */
19
20#include <linux/of.h>
21#include <asm/epapr_hcalls.h>
22#include <asm/cacheflush.h>
23#include <asm/code-patching.h>
24
25bool epapr_paravirt_enabled;
26
27static int __init epapr_paravirt_init(void)
28{
29 struct device_node *hyper_node;
30 const u32 *insts;
31 int len, i;
32
33 hyper_node = of_find_node_by_path("/hypervisor");
34 if (!hyper_node)
35 return -ENODEV;
36
37 insts = of_get_property(hyper_node, "hcall-instructions", &len);
38 if (!insts)
39 return -ENODEV;
40
41 if (len % 4 || len > (4 * 4))
42 return -ENODEV;
43
44 for (i = 0; i < (len / 4); i++)
45 patch_instruction(epapr_hypercall_start + i, insts[i]);
46
47 epapr_paravirt_enabled = true;
48
49 return 0;
50}
51
52early_initcall(epapr_paravirt_init);
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
index 62bdf2389669..1c13307e0308 100644
--- a/arch/powerpc/kernel/kvm.c
+++ b/arch/powerpc/kernel/kvm.c
@@ -31,6 +31,7 @@
31#include <asm/cacheflush.h> 31#include <asm/cacheflush.h>
32#include <asm/disassemble.h> 32#include <asm/disassemble.h>
33#include <asm/ppc-opcode.h> 33#include <asm/ppc-opcode.h>
34#include <asm/epapr_hcalls.h>
34 35
35#define KVM_MAGIC_PAGE (-4096L) 36#define KVM_MAGIC_PAGE (-4096L)
36#define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) 37#define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x)
@@ -726,7 +727,7 @@ unsigned long kvm_hypercall(unsigned long *in,
726 unsigned long register r11 asm("r11") = nr; 727 unsigned long register r11 asm("r11") = nr;
727 unsigned long register r12 asm("r12"); 728 unsigned long register r12 asm("r12");
728 729
729 asm volatile("bl kvm_hypercall_start" 730 asm volatile("bl epapr_hypercall_start"
730 : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), 731 : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6),
731 "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), 732 "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11),
732 "=r"(r12) 733 "=r"(r12)
@@ -747,29 +748,6 @@ unsigned long kvm_hypercall(unsigned long *in,
747} 748}
748EXPORT_SYMBOL_GPL(kvm_hypercall); 749EXPORT_SYMBOL_GPL(kvm_hypercall);
749 750
750static int kvm_para_setup(void)
751{
752 extern u32 kvm_hypercall_start;
753 struct device_node *hyper_node;
754 u32 *insts;
755 int len, i;
756
757 hyper_node = of_find_node_by_path("/hypervisor");
758 if (!hyper_node)
759 return -1;
760
761 insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);
762 if (len % 4)
763 return -1;
764 if (len > (4 * 4))
765 return -1;
766
767 for (i = 0; i < (len / 4); i++)
768 kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]);
769
770 return 0;
771}
772
773static __init void kvm_free_tmp(void) 751static __init void kvm_free_tmp(void)
774{ 752{
775 unsigned long start, end; 753 unsigned long start, end;
@@ -791,7 +769,7 @@ static int __init kvm_guest_init(void)
791 if (!kvm_para_available()) 769 if (!kvm_para_available())
792 goto free_tmp; 770 goto free_tmp;
793 771
794 if (kvm_para_setup()) 772 if (!epapr_paravirt_enabled)
795 goto free_tmp; 773 goto free_tmp;
796 774
797 if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE)) 775 if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE))
diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S
index e291cf3cf954..62ceb2ac82cf 100644
--- a/arch/powerpc/kernel/kvm_emul.S
+++ b/arch/powerpc/kernel/kvm_emul.S
@@ -24,16 +24,6 @@
24#include <asm/page.h> 24#include <asm/page.h>
25#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
26 26
27/* Hypercall entry point. Will be patched with device tree instructions. */
28
29.global kvm_hypercall_start
30kvm_hypercall_start:
31 li r3, -1
32 nop
33 nop
34 nop
35 blr
36
37#define KVM_MAGIC_PAGE (-4096) 27#define KVM_MAGIC_PAGE (-4096)
38 28
39#ifdef CONFIG_64BIT 29#ifdef CONFIG_64BIT
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index a35ca44ade66..e7a896acd982 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -25,6 +25,7 @@ source "arch/powerpc/platforms/wsp/Kconfig"
25config KVM_GUEST 25config KVM_GUEST
26 bool "KVM Guest support" 26 bool "KVM Guest support"
27 default n 27 default n
28 select EPAPR_PARAVIRT
28 ---help--- 29 ---help---
29 This option enables various optimizations for running under the KVM 30 This option enables various optimizations for running under the KVM
30 hypervisor. Overhead for the kernel when not running inside KVM should 31 hypervisor. Overhead for the kernel when not running inside KVM should
@@ -32,6 +33,14 @@ config KVM_GUEST
32 33
33 In case of doubt, say Y 34 In case of doubt, say Y
34 35
36config EPAPR_PARAVIRT
37 bool "ePAPR para-virtualization support"
38 default n
39 help
40 Enables ePAPR para-virtualization support for guests.
41
42 In case of doubt, say Y
43
35config PPC_NATIVE 44config PPC_NATIVE
36 bool 45 bool
37 depends on 6xx || PPC64 46 depends on 6xx || PPC64