16 #include <linux/slab.h>
18 #include <linux/export.h>
21 #include <asm/cputable.h>
22 #include <asm/tlbflush.h>
25 #include "../mm/mmu_decl.h"
72 static inline int local_sid_setup_one(
struct id *
entry)
106 static inline int local_sid_lookup(
struct id *entry)
108 if (entry && entry->
val != 0 &&
116 static inline void local_sid_destroy_all(
void)
125 return vcpu_e500->idt;
130 kfree(vcpu_e500->idt);
131 vcpu_e500->idt =
NULL;
138 static void kvmppc_e500_recalc_shadow_pid(
struct kvmppc_vcpu_e500 *vcpu_e500)
142 get_cur_as(&vcpu_e500->
vcpu),
143 get_cur_pid(&vcpu_e500->
vcpu),
144 get_cur_pr(&vcpu_e500->
vcpu), 1);
146 get_cur_as(&vcpu_e500->
vcpu), 0,
147 get_cur_pr(&vcpu_e500->
vcpu), 1);
152 static void kvmppc_e500_id_table_reset_all(
struct kvmppc_vcpu_e500 *vcpu_e500)
157 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
161 static inline void kvmppc_e500_id_table_reset_one(
175 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
188 unsigned int as,
unsigned int gid,
189 unsigned int pr,
int avoid_recursion)
198 sid = local_sid_lookup(&idt->
id[as][gid][pr]);
202 sid = local_sid_setup_one(&idt->
id[as][gid][pr]);
205 local_sid_destroy_all();
209 if (!avoid_recursion)
210 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
220 get_tlb_tid(gtlbe), get_cur_pr(vcpu), 0);
227 if (vcpu->
arch.pid != pid) {
228 vcpu_e500->pid[0] = vcpu->
arch.pid =
pid;
229 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
242 ts = get_tlb_ts(gtlbe);
243 tid = get_tlb_tid(gtlbe);
248 for (pr = 0; pr < 2; pr++) {
258 pid = local_sid_lookup(&idt->
id[ts][tid][pr]);
260 kvmppc_e500_id_table_reset_one(vcpu_e500, ts, tid, pr);
271 eaddr = get_tlb_eaddr(gtlbe);
275 mtspr(SPRN_MAS6, val);
276 asm volatile(
"tlbsx 0, %[eaddr]" : : [eaddr]
"r" (eaddr));
277 val =
mfspr(SPRN_MAS1);
279 mtspr(SPRN_MAS1, val & ~MAS1_VALID);
280 asm volatile(
"tlbwe");
291 kvmppc_e500_id_table_reset_all(vcpu_e500);
297 kvmppc_e500_recalc_shadow_pid(to_e500(vcpu));
313 kvmppc_e500_recalc_shadow_pid(to_e500(vcpu));
319 if (vcpu->
arch.shadow_msr & MSR_SPE)
359 kvmppc_e500_tlb_setup(vcpu_e500);
378 sregs->
u.
e.impl.fsl.features = 0;
379 sregs->
u.
e.impl.fsl.svr = vcpu_e500->
svr;
380 sregs->
u.
e.impl.fsl.hid0 = vcpu_e500->
hid0;
381 sregs->
u.
e.impl.fsl.mcar = vcpu_e500->
mcar;
386 sregs->
u.
e.ivor_high[3] =
399 vcpu_e500->
svr = sregs->
u.
e.impl.fsl.svr;
400 vcpu_e500->
hid0 = sregs->
u.
e.impl.fsl.hid0;
401 vcpu_e500->
mcar = sregs->
u.
e.impl.fsl.mcar;
413 sregs->
u.
e.ivor_high[0];
415 sregs->
u.
e.ivor_high[1];
417 sregs->
u.
e.ivor_high[2];
422 sregs->
u.
e.ivor_high[3];
440 vcpu = &vcpu_e500->
vcpu;
445 if (kvmppc_e500_id_table_alloc(vcpu_e500) ==
NULL)
453 if (!vcpu->
arch.shared)
461 kvmppc_e500_id_table_free(vcpu_e500);
476 kvmppc_e500_id_table_free(vcpu_e500);
490 static int __init kvmppc_e500_init(
void)
493 unsigned long ivor[3];
494 unsigned long max_ivor = 0;
505 ivor[0] =
mfspr(SPRN_IVOR32);
506 ivor[1] =
mfspr(SPRN_IVOR33);
507 ivor[2] =
mfspr(SPRN_IVOR34);
508 for (i = 0; i < 3; i++) {
509 if (ivor[i] > max_ivor)
513 kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
522 static void __exit kvmppc_e500_exit(
void)