aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h3
-rw-r--r--arch/powerpc/kvm/44x.c53
-rw-r--r--arch/powerpc/kvm/booke.c46
3 files changed, 58 insertions, 44 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index aecf95d5fede..d59332575b4d 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -62,7 +62,10 @@ extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
62 62
63/* Core-specific hooks */ 63/* Core-specific hooks */
64 64
65extern int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu);
65extern int kvmppc_core_check_processor_compat(void); 66extern int kvmppc_core_check_processor_compat(void);
67extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
68 struct kvm_translation *tr);
66 69
67extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu); 70extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
68extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); 71extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index fcf8c7d0af45..f5d7028eeb09 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -121,3 +121,56 @@ int kvmppc_core_check_processor_compat(void)
121 121
122 return r; 122 return r;
123} 123}
124
125int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
126{
127 struct kvmppc_44x_tlbe *tlbe = &vcpu->arch.guest_tlb[0];
128
129 tlbe->tid = 0;
130 tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID;
131 tlbe->word1 = 0;
132 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR;
133
134 tlbe++;
135 tlbe->tid = 0;
136 tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID;
137 tlbe->word1 = 0xef600000;
138 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR
139 | PPC44x_TLB_I | PPC44x_TLB_G;
140
141 /* Since the guest can directly access the timebase, it must know the
142 * real timebase frequency. Accordingly, it must see the state of
143 * CCR1[TCS]. */
144 vcpu->arch.ccr1 = mfspr(SPRN_CCR1);
145
146 return 0;
147}
148
149/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
150int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
151 struct kvm_translation *tr)
152{
153 struct kvmppc_44x_tlbe *gtlbe;
154 int index;
155 gva_t eaddr;
156 u8 pid;
157 u8 as;
158
159 eaddr = tr->linear_address;
160 pid = (tr->linear_address >> 32) & 0xff;
161 as = (tr->linear_address >> 40) & 0x1;
162
163 index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as);
164 if (index == -1) {
165 tr->valid = 0;
166 return 0;
167 }
168
169 gtlbe = &vcpu->arch.guest_tlb[index];
170
171 tr->physical_address = tlb_xlate(gtlbe, eaddr);
172 /* XXX what does "writeable" and "usermode" even mean? */
173 tr->valid = 1;
174
175 return 0;
176}
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index ea630095e280..c619d1b912c5 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -479,20 +479,6 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
479/* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */ 479/* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */
480int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 480int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
481{ 481{
482 struct kvmppc_44x_tlbe *tlbe = &vcpu->arch.guest_tlb[0];
483
484 tlbe->tid = 0;
485 tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID;
486 tlbe->word1 = 0;
487 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR;
488
489 tlbe++;
490 tlbe->tid = 0;
491 tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID;
492 tlbe->word1 = 0xef600000;
493 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR
494 | PPC44x_TLB_I | PPC44x_TLB_G;
495
496 vcpu->arch.pc = 0; 482 vcpu->arch.pc = 0;
497 vcpu->arch.msr = 0; 483 vcpu->arch.msr = 0;
498 vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */ 484 vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
@@ -503,12 +489,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
503 * before it's programmed its own IVPR. */ 489 * before it's programmed its own IVPR. */
504 vcpu->arch.ivpr = 0x55550000; 490 vcpu->arch.ivpr = 0x55550000;
505 491
506 /* Since the guest can directly access the timebase, it must know the 492 return kvmppc_core_vcpu_setup(vcpu);
507 * real timebase frequency. Accordingly, it must see the state of
508 * CCR1[TCS]. */
509 vcpu->arch.ccr1 = mfspr(SPRN_CCR1);
510
511 return 0;
512} 493}
513 494
514int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 495int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
@@ -586,33 +567,10 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
586 return -ENOTSUPP; 567 return -ENOTSUPP;
587} 568}
588 569
589/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
590int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, 570int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
591 struct kvm_translation *tr) 571 struct kvm_translation *tr)
592{ 572{
593 struct kvmppc_44x_tlbe *gtlbe; 573 return kvmppc_core_vcpu_translate(vcpu, tr);
594 int index;
595 gva_t eaddr;
596 u8 pid;
597 u8 as;
598
599 eaddr = tr->linear_address;
600 pid = (tr->linear_address >> 32) & 0xff;
601 as = (tr->linear_address >> 40) & 0x1;
602
603 index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as);
604 if (index == -1) {
605 tr->valid = 0;
606 return 0;
607 }
608
609 gtlbe = &vcpu->arch.guest_tlb[index];
610
611 tr->physical_address = tlb_xlate(gtlbe, eaddr);
612 /* XXX what does "writeable" and "usermode" even mean? */
613 tr->valid = 1;
614
615 return 0;
616} 574}
617 575
618static int kvmppc_booke_init(void) 576static int kvmppc_booke_init(void)