aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kvm/Kconfig6
-rw-r--r--arch/powerpc/kvm/Makefile6
-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.c83
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
33config KVM_BOOKE_HOST 33config 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
9common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) 9common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o)
10 10
11kvm-objs := $(common-objs-y) powerpc.o emulate.o booke_guest.o 11kvm-objs := $(common-objs-y) powerpc.o emulate.o
12obj-$(CONFIG_KVM) += kvm.o 12obj-$(CONFIG_KVM) += kvm.o
13 13
14AFLAGS_booke_interrupts.o := -I$(obj) 14AFLAGS_booke_interrupts.o := -I$(obj)
15 15
16kvm-booke-host-objs := booke_host.o booke_interrupts.o 44x_tlb.o 16kvm-booke-objs := booke.o booke_interrupts.o 44x_tlb.o
17obj-$(CONFIG_KVM_BOOKE_HOST) += kvm-booke-host.o 17obj-$(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
34unsigned 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
584static 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
632static void __exit kvmppc_booke_exit(void)
633{
634 free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER);
635 kvm_exit();
636}
637
638module_init(kvmppc_booke_init)
639module_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
26unsigned long kvmppc_booke_handlers;
27
28static 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
76static void __exit kvmppc_booke_exit(void)
77{
78 free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER);
79 kvm_exit();
80}
81
82module_init(kvmppc_booke_init)
83module_exit(kvmppc_booke_exit)