diff options
Diffstat (limited to 'arch/powerpc/kvm/44x.c')
-rw-r--r-- | arch/powerpc/kvm/44x.c | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c deleted file mode 100644 index 9cb4b0a36031..000000000000 --- a/arch/powerpc/kvm/44x.c +++ /dev/null | |||
@@ -1,237 +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/kvm_host.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/miscdevice.h> | ||
26 | |||
27 | #include <asm/reg.h> | ||
28 | #include <asm/cputable.h> | ||
29 | #include <asm/tlbflush.h> | ||
30 | #include <asm/kvm_44x.h> | ||
31 | #include <asm/kvm_ppc.h> | ||
32 | |||
33 | #include "44x_tlb.h" | ||
34 | #include "booke.h" | ||
35 | |||
36 | static void kvmppc_core_vcpu_load_44x(struct kvm_vcpu *vcpu, int cpu) | ||
37 | { | ||
38 | kvmppc_booke_vcpu_load(vcpu, cpu); | ||
39 | kvmppc_44x_tlb_load(vcpu); | ||
40 | } | ||
41 | |||
42 | static void kvmppc_core_vcpu_put_44x(struct kvm_vcpu *vcpu) | ||
43 | { | ||
44 | kvmppc_44x_tlb_put(vcpu); | ||
45 | kvmppc_booke_vcpu_put(vcpu); | ||
46 | } | ||
47 | |||
48 | int kvmppc_core_check_processor_compat(void) | ||
49 | { | ||
50 | int r; | ||
51 | |||
52 | if (strncmp(cur_cpu_spec->platform, "ppc440", 6) == 0) | ||
53 | r = 0; | ||
54 | else | ||
55 | r = -ENOTSUPP; | ||
56 | |||
57 | return r; | ||
58 | } | ||
59 | |||
60 | int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | ||
61 | { | ||
62 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
63 | struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[0]; | ||
64 | int i; | ||
65 | |||
66 | tlbe->tid = 0; | ||
67 | tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; | ||
68 | tlbe->word1 = 0; | ||
69 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; | ||
70 | |||
71 | tlbe++; | ||
72 | tlbe->tid = 0; | ||
73 | tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; | ||
74 | tlbe->word1 = 0xef600000; | ||
75 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR | ||
76 | | PPC44x_TLB_I | PPC44x_TLB_G; | ||
77 | |||
78 | /* Since the guest can directly access the timebase, it must know the | ||
79 | * real timebase frequency. Accordingly, it must see the state of | ||
80 | * CCR1[TCS]. */ | ||
81 | /* XXX CCR1 doesn't exist on all 440 SoCs. */ | ||
82 | vcpu->arch.ccr1 = mfspr(SPRN_CCR1); | ||
83 | |||
84 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) | ||
85 | vcpu_44x->shadow_refs[i].gtlb_index = -1; | ||
86 | |||
87 | vcpu->arch.cpu_type = KVM_CPU_440; | ||
88 | vcpu->arch.pvr = mfspr(SPRN_PVR); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | /* 'linear_address' is actually an encoding of AS|PID|EADDR . */ | ||
94 | int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, | ||
95 | struct kvm_translation *tr) | ||
96 | { | ||
97 | int index; | ||
98 | gva_t eaddr; | ||
99 | u8 pid; | ||
100 | u8 as; | ||
101 | |||
102 | eaddr = tr->linear_address; | ||
103 | pid = (tr->linear_address >> 32) & 0xff; | ||
104 | as = (tr->linear_address >> 40) & 0x1; | ||
105 | |||
106 | index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as); | ||
107 | if (index == -1) { | ||
108 | tr->valid = 0; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); | ||
113 | /* XXX what does "writeable" and "usermode" even mean? */ | ||
114 | tr->valid = 1; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int kvmppc_core_get_sregs_44x(struct kvm_vcpu *vcpu, | ||
120 | struct kvm_sregs *sregs) | ||
121 | { | ||
122 | return kvmppc_get_sregs_ivor(vcpu, sregs); | ||
123 | } | ||
124 | |||
125 | static int kvmppc_core_set_sregs_44x(struct kvm_vcpu *vcpu, | ||
126 | struct kvm_sregs *sregs) | ||
127 | { | ||
128 | return kvmppc_set_sregs_ivor(vcpu, sregs); | ||
129 | } | ||
130 | |||
131 | static int kvmppc_get_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
132 | union kvmppc_one_reg *val) | ||
133 | { | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | static int kvmppc_set_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
138 | union kvmppc_one_reg *val) | ||
139 | { | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | static struct kvm_vcpu *kvmppc_core_vcpu_create_44x(struct kvm *kvm, | ||
144 | unsigned int id) | ||
145 | { | ||
146 | struct kvmppc_vcpu_44x *vcpu_44x; | ||
147 | struct kvm_vcpu *vcpu; | ||
148 | int err; | ||
149 | |||
150 | vcpu_44x = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | ||
151 | if (!vcpu_44x) { | ||
152 | err = -ENOMEM; | ||
153 | goto out; | ||
154 | } | ||
155 | |||
156 | vcpu = &vcpu_44x->vcpu; | ||
157 | err = kvm_vcpu_init(vcpu, kvm, id); | ||
158 | if (err) | ||
159 | goto free_vcpu; | ||
160 | |||
161 | vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); | ||
162 | if (!vcpu->arch.shared) | ||
163 | goto uninit_vcpu; | ||
164 | |||
165 | return vcpu; | ||
166 | |||
167 | uninit_vcpu: | ||
168 | kvm_vcpu_uninit(vcpu); | ||
169 | free_vcpu: | ||
170 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
171 | out: | ||
172 | return ERR_PTR(err); | ||
173 | } | ||
174 | |||
175 | static void kvmppc_core_vcpu_free_44x(struct kvm_vcpu *vcpu) | ||
176 | { | ||
177 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
178 | |||
179 | free_page((unsigned long)vcpu->arch.shared); | ||
180 | kvm_vcpu_uninit(vcpu); | ||
181 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
182 | } | ||
183 | |||
184 | static int kvmppc_core_init_vm_44x(struct kvm *kvm) | ||
185 | { | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void kvmppc_core_destroy_vm_44x(struct kvm *kvm) | ||
190 | { | ||
191 | } | ||
192 | |||
193 | static struct kvmppc_ops kvm_ops_44x = { | ||
194 | .get_sregs = kvmppc_core_get_sregs_44x, | ||
195 | .set_sregs = kvmppc_core_set_sregs_44x, | ||
196 | .get_one_reg = kvmppc_get_one_reg_44x, | ||
197 | .set_one_reg = kvmppc_set_one_reg_44x, | ||
198 | .vcpu_load = kvmppc_core_vcpu_load_44x, | ||
199 | .vcpu_put = kvmppc_core_vcpu_put_44x, | ||
200 | .vcpu_create = kvmppc_core_vcpu_create_44x, | ||
201 | .vcpu_free = kvmppc_core_vcpu_free_44x, | ||
202 | .mmu_destroy = kvmppc_mmu_destroy_44x, | ||
203 | .init_vm = kvmppc_core_init_vm_44x, | ||
204 | .destroy_vm = kvmppc_core_destroy_vm_44x, | ||
205 | .emulate_op = kvmppc_core_emulate_op_44x, | ||
206 | .emulate_mtspr = kvmppc_core_emulate_mtspr_44x, | ||
207 | .emulate_mfspr = kvmppc_core_emulate_mfspr_44x, | ||
208 | }; | ||
209 | |||
210 | static int __init kvmppc_44x_init(void) | ||
211 | { | ||
212 | int r; | ||
213 | |||
214 | r = kvmppc_booke_init(); | ||
215 | if (r) | ||
216 | goto err_out; | ||
217 | |||
218 | r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); | ||
219 | if (r) | ||
220 | goto err_out; | ||
221 | kvm_ops_44x.owner = THIS_MODULE; | ||
222 | kvmppc_pr_ops = &kvm_ops_44x; | ||
223 | |||
224 | err_out: | ||
225 | return r; | ||
226 | } | ||
227 | |||
228 | static void __exit kvmppc_44x_exit(void) | ||
229 | { | ||
230 | kvmppc_pr_ops = NULL; | ||
231 | kvmppc_booke_exit(); | ||
232 | } | ||
233 | |||
234 | module_init(kvmppc_44x_init); | ||
235 | module_exit(kvmppc_44x_exit); | ||
236 | MODULE_ALIAS_MISCDEV(KVM_MINOR); | ||
237 | MODULE_ALIAS("devname:kvm"); | ||