diff options
-rw-r--r-- | arch/powerpc/kvm/Kconfig | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/Makefile | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c (renamed from arch/powerpc/kvm/booke_guest.c) | 60 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke_host.c | 83 |
4 files changed, 66 insertions, 89 deletions
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 53aaa66b25e5..ffed96f817f7 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
@@ -20,7 +20,7 @@ config KVM | |||
20 | select PREEMPT_NOTIFIERS | 20 | select PREEMPT_NOTIFIERS |
21 | select ANON_INODES | 21 | select ANON_INODES |
22 | # We can only run on Book E hosts so far | 22 | # We can only run on Book E hosts so far |
23 | select KVM_BOOKE_HOST | 23 | select KVM_BOOKE |
24 | ---help--- | 24 | ---help--- |
25 | Support hosting virtualized guest machines. You will also | 25 | Support hosting virtualized guest machines. You will also |
26 | need to select one or more of the processor modules below. | 26 | need to select one or more of the processor modules below. |
@@ -30,8 +30,8 @@ config KVM | |||
30 | 30 | ||
31 | If unsure, say N. | 31 | If unsure, say N. |
32 | 32 | ||
33 | config KVM_BOOKE_HOST | 33 | config KVM_BOOKE |
34 | bool "KVM host support for Book E PowerPC processors" | 34 | bool "KVM support for Book E PowerPC processors" |
35 | depends on KVM && 44x | 35 | depends on KVM && 44x |
36 | ---help--- | 36 | ---help--- |
37 | Provides host support for KVM on Book E PowerPC processors. Currently | 37 | Provides host support for KVM on Book E PowerPC processors. Currently |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 2a5d4397ac4b..a7f857446c8a 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -8,10 +8,10 @@ common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) | |||
8 | 8 | ||
9 | common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) | 9 | common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) |
10 | 10 | ||
11 | kvm-objs := $(common-objs-y) powerpc.o emulate.o booke_guest.o | 11 | kvm-objs := $(common-objs-y) powerpc.o emulate.o |
12 | obj-$(CONFIG_KVM) += kvm.o | 12 | obj-$(CONFIG_KVM) += kvm.o |
13 | 13 | ||
14 | AFLAGS_booke_interrupts.o := -I$(obj) | 14 | AFLAGS_booke_interrupts.o := -I$(obj) |
15 | 15 | ||
16 | kvm-booke-host-objs := booke_host.o booke_interrupts.o 44x_tlb.o | 16 | kvm-booke-objs := booke.o booke_interrupts.o 44x_tlb.o |
17 | obj-$(CONFIG_KVM_BOOKE_HOST) += kvm-booke-host.o | 17 | obj-$(CONFIG_KVM_BOOKE) += kvm-booke.o |
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke.c index 41bbf4c78f88..b1e90a15155a 100644 --- a/arch/powerpc/kvm/booke_guest.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -27,9 +27,12 @@ | |||
27 | #include <asm/cputable.h> | 27 | #include <asm/cputable.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/kvm_ppc.h> | 29 | #include <asm/kvm_ppc.h> |
30 | #include <asm/cacheflush.h> | ||
30 | 31 | ||
31 | #include "44x_tlb.h" | 32 | #include "44x_tlb.h" |
32 | 33 | ||
34 | unsigned long kvmppc_booke_handlers; | ||
35 | |||
33 | #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM | 36 | #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM |
34 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | 37 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU |
35 | 38 | ||
@@ -577,3 +580,60 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | |||
577 | 580 | ||
578 | return 0; | 581 | return 0; |
579 | } | 582 | } |
583 | |||
584 | static int kvmppc_booke_init(void) | ||
585 | { | ||
586 | unsigned long ivor[16]; | ||
587 | unsigned long max_ivor = 0; | ||
588 | int i; | ||
589 | |||
590 | /* We install our own exception handlers by hijacking IVPR. IVPR must | ||
591 | * be 16-bit aligned, so we need a 64KB allocation. */ | ||
592 | kvmppc_booke_handlers = __get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
593 | VCPU_SIZE_ORDER); | ||
594 | if (!kvmppc_booke_handlers) | ||
595 | return -ENOMEM; | ||
596 | |||
597 | /* XXX make sure our handlers are smaller than Linux's */ | ||
598 | |||
599 | /* Copy our interrupt handlers to match host IVORs. That way we don't | ||
600 | * have to swap the IVORs on every guest/host transition. */ | ||
601 | ivor[0] = mfspr(SPRN_IVOR0); | ||
602 | ivor[1] = mfspr(SPRN_IVOR1); | ||
603 | ivor[2] = mfspr(SPRN_IVOR2); | ||
604 | ivor[3] = mfspr(SPRN_IVOR3); | ||
605 | ivor[4] = mfspr(SPRN_IVOR4); | ||
606 | ivor[5] = mfspr(SPRN_IVOR5); | ||
607 | ivor[6] = mfspr(SPRN_IVOR6); | ||
608 | ivor[7] = mfspr(SPRN_IVOR7); | ||
609 | ivor[8] = mfspr(SPRN_IVOR8); | ||
610 | ivor[9] = mfspr(SPRN_IVOR9); | ||
611 | ivor[10] = mfspr(SPRN_IVOR10); | ||
612 | ivor[11] = mfspr(SPRN_IVOR11); | ||
613 | ivor[12] = mfspr(SPRN_IVOR12); | ||
614 | ivor[13] = mfspr(SPRN_IVOR13); | ||
615 | ivor[14] = mfspr(SPRN_IVOR14); | ||
616 | ivor[15] = mfspr(SPRN_IVOR15); | ||
617 | |||
618 | for (i = 0; i < 16; i++) { | ||
619 | if (ivor[i] > max_ivor) | ||
620 | max_ivor = ivor[i]; | ||
621 | |||
622 | memcpy((void *)kvmppc_booke_handlers + ivor[i], | ||
623 | kvmppc_handlers_start + i * kvmppc_handler_len, | ||
624 | kvmppc_handler_len); | ||
625 | } | ||
626 | flush_icache_range(kvmppc_booke_handlers, | ||
627 | kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); | ||
628 | |||
629 | return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); | ||
630 | } | ||
631 | |||
632 | static void __exit kvmppc_booke_exit(void) | ||
633 | { | ||
634 | free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER); | ||
635 | kvm_exit(); | ||
636 | } | ||
637 | |||
638 | module_init(kvmppc_booke_init) | ||
639 | module_exit(kvmppc_booke_exit) | ||
diff --git a/arch/powerpc/kvm/booke_host.c b/arch/powerpc/kvm/booke_host.c deleted file mode 100644 index b480341bc31e..000000000000 --- a/arch/powerpc/kvm/booke_host.c +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2008 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #include <linux/errno.h> | ||
21 | #include <linux/kvm_host.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <asm/cacheflush.h> | ||
24 | #include <asm/kvm_ppc.h> | ||
25 | |||
26 | unsigned long kvmppc_booke_handlers; | ||
27 | |||
28 | static int kvmppc_booke_init(void) | ||
29 | { | ||
30 | unsigned long ivor[16]; | ||
31 | unsigned long max_ivor = 0; | ||
32 | int i; | ||
33 | |||
34 | /* We install our own exception handlers by hijacking IVPR. IVPR must | ||
35 | * be 16-bit aligned, so we need a 64KB allocation. */ | ||
36 | kvmppc_booke_handlers = __get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
37 | VCPU_SIZE_ORDER); | ||
38 | if (!kvmppc_booke_handlers) | ||
39 | return -ENOMEM; | ||
40 | |||
41 | /* XXX make sure our handlers are smaller than Linux's */ | ||
42 | |||
43 | /* Copy our interrupt handlers to match host IVORs. That way we don't | ||
44 | * have to swap the IVORs on every guest/host transition. */ | ||
45 | ivor[0] = mfspr(SPRN_IVOR0); | ||
46 | ivor[1] = mfspr(SPRN_IVOR1); | ||
47 | ivor[2] = mfspr(SPRN_IVOR2); | ||
48 | ivor[3] = mfspr(SPRN_IVOR3); | ||
49 | ivor[4] = mfspr(SPRN_IVOR4); | ||
50 | ivor[5] = mfspr(SPRN_IVOR5); | ||
51 | ivor[6] = mfspr(SPRN_IVOR6); | ||
52 | ivor[7] = mfspr(SPRN_IVOR7); | ||
53 | ivor[8] = mfspr(SPRN_IVOR8); | ||
54 | ivor[9] = mfspr(SPRN_IVOR9); | ||
55 | ivor[10] = mfspr(SPRN_IVOR10); | ||
56 | ivor[11] = mfspr(SPRN_IVOR11); | ||
57 | ivor[12] = mfspr(SPRN_IVOR12); | ||
58 | ivor[13] = mfspr(SPRN_IVOR13); | ||
59 | ivor[14] = mfspr(SPRN_IVOR14); | ||
60 | ivor[15] = mfspr(SPRN_IVOR15); | ||
61 | |||
62 | for (i = 0; i < 16; i++) { | ||
63 | if (ivor[i] > max_ivor) | ||
64 | max_ivor = ivor[i]; | ||
65 | |||
66 | memcpy((void *)kvmppc_booke_handlers + ivor[i], | ||
67 | kvmppc_handlers_start + i * kvmppc_handler_len, | ||
68 | kvmppc_handler_len); | ||
69 | } | ||
70 | flush_icache_range(kvmppc_booke_handlers, | ||
71 | kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); | ||
72 | |||
73 | return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); | ||
74 | } | ||
75 | |||
76 | static void __exit kvmppc_booke_exit(void) | ||
77 | { | ||
78 | free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER); | ||
79 | kvm_exit(); | ||
80 | } | ||
81 | |||
82 | module_init(kvmppc_booke_init) | ||
83 | module_exit(kvmppc_booke_exit) | ||