diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/44x.c | 53 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 46 |
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 | ||
65 | extern int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu); | ||
65 | extern int kvmppc_core_check_processor_compat(void); | 66 | extern int kvmppc_core_check_processor_compat(void); |
67 | extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, | ||
68 | struct kvm_translation *tr); | ||
66 | 69 | ||
67 | extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | 70 | extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu); |
68 | extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); | 71 | extern 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 | |||
125 | int 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 . */ | ||
150 | int 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 */ |
480 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 480 | int 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 | ||
514 | int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 495 | int 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 . */ | ||
590 | int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | 570 | int 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 | ||
618 | static int kvmppc_booke_init(void) | 576 | static int kvmppc_booke_init(void) |