]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kvm/booke.c
KVM: ppc: Move the last bits of 44x code out of booke.c
[karo-tx-linux.git] / arch / powerpc / kvm / booke.c
index b1e90a15155a760b4ff168eb9a73fecf29a3a631..c619d1b912c57a5917fa06e30e12d7c623124be5 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/cacheflush.h>
 
+#include "booke.h"
 #include "44x_tlb.h"
 
 unsigned long kvmppc_booke_handlers;
@@ -134,6 +135,40 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
        }
 }
 
+static void kvmppc_booke_queue_exception(struct kvm_vcpu *vcpu, int exception)
+{
+       unsigned int priority = exception_priority[exception];
+       set_bit(priority, &vcpu->arch.pending_exceptions);
+}
+
+static void kvmppc_booke_clear_exception(struct kvm_vcpu *vcpu, int exception)
+{
+       unsigned int priority = exception_priority[exception];
+       clear_bit(priority, &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+{
+       kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
+}
+
+void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
+{
+       kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER);
+}
+
+int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
+{
+       unsigned int priority = exception_priority[BOOKE_INTERRUPT_DECREMENTER];
+       return test_bit(priority, &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
+                                struct kvm_interrupt *irq)
+{
+       kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL);
+}
+
 /* Check if we are ready to deliver the interrupt */
 static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
 {
@@ -168,7 +203,7 @@ static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
        return r;
 }
 
-static void kvmppc_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
+static void kvmppc_booke_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
 {
        switch (interrupt) {
        case BOOKE_INTERRUPT_DECREMENTER:
@@ -183,7 +218,7 @@ static void kvmppc_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
 }
 
 /* Check pending exceptions and deliver one, if possible. */
-void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu)
+void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
 {
        unsigned long *pending = &vcpu->arch.pending_exceptions;
        unsigned int exception;
@@ -193,8 +228,8 @@ void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu)
        while (priority <= BOOKE_MAX_INTERRUPT) {
                exception = priority_exception[priority];
                if (kvmppc_can_deliver_interrupt(vcpu, exception)) {
-                       kvmppc_clear_exception(vcpu, exception);
-                       kvmppc_deliver_interrupt(vcpu, exception);
+                       kvmppc_booke_clear_exception(vcpu, exception);
+                       kvmppc_booke_deliver_interrupt(vcpu, exception);
                        break;
                }
 
@@ -251,7 +286,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        /* Program traps generated by user-level software must be handled
                         * by the guest kernel. */
                        vcpu->arch.esr = vcpu->arch.fault_esr;
-                       kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
+                       kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
                        r = RESUME_GUEST;
                        break;
                }
@@ -284,27 +319,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                break;
 
        case BOOKE_INTERRUPT_FP_UNAVAIL:
-               kvmppc_queue_exception(vcpu, exit_nr);
+               kvmppc_booke_queue_exception(vcpu, exit_nr);
                r = RESUME_GUEST;
                break;
 
        case BOOKE_INTERRUPT_DATA_STORAGE:
                vcpu->arch.dear = vcpu->arch.fault_dear;
                vcpu->arch.esr = vcpu->arch.fault_esr;
-               kvmppc_queue_exception(vcpu, exit_nr);
+               kvmppc_booke_queue_exception(vcpu, exit_nr);
                vcpu->stat.dsi_exits++;
                r = RESUME_GUEST;
                break;
 
        case BOOKE_INTERRUPT_INST_STORAGE:
                vcpu->arch.esr = vcpu->arch.fault_esr;
-               kvmppc_queue_exception(vcpu, exit_nr);
+               kvmppc_booke_queue_exception(vcpu, exit_nr);
                vcpu->stat.isi_exits++;
                r = RESUME_GUEST;
                break;
 
        case BOOKE_INTERRUPT_SYSCALL:
-               kvmppc_queue_exception(vcpu, exit_nr);
+               kvmppc_booke_queue_exception(vcpu, exit_nr);
                vcpu->stat.syscall_exits++;
                r = RESUME_GUEST;
                break;
@@ -318,7 +353,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr);
                if (!gtlbe) {
                        /* The guest didn't have a mapping for it. */
-                       kvmppc_queue_exception(vcpu, exit_nr);
+                       kvmppc_booke_queue_exception(vcpu, exit_nr);
                        vcpu->arch.dear = vcpu->arch.fault_dear;
                        vcpu->arch.esr = vcpu->arch.fault_esr;
                        vcpu->stat.dtlb_real_miss_exits++;
@@ -360,7 +395,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr);
                if (!gtlbe) {
                        /* The guest didn't have a mapping for it. */
-                       kvmppc_queue_exception(vcpu, exit_nr);
+                       kvmppc_booke_queue_exception(vcpu, exit_nr);
                        vcpu->stat.itlb_real_miss_exits++;
                        break;
                }
@@ -380,8 +415,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                                       gtlbe->word2);
                } else {
                        /* Guest mapped and leaped at non-RAM! */
-                       kvmppc_queue_exception(vcpu,
-                                              BOOKE_INTERRUPT_MACHINE_CHECK);
+                       kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_MACHINE_CHECK);
                }
 
                break;
@@ -409,7 +443,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 
        local_irq_disable();
 
-       kvmppc_check_and_deliver_interrupts(vcpu);
+       kvmppc_core_deliver_interrupts(vcpu);
 
        /* Do some exit accounting. */
        vcpu->stat.sum_exits++;
@@ -445,20 +479,6 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 /* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
-       struct kvmppc_44x_tlbe *tlbe = &vcpu->arch.guest_tlb[0];
-
-       tlbe->tid = 0;
-       tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID;
-       tlbe->word1 = 0;
-       tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR;
-
-       tlbe++;
-       tlbe->tid = 0;
-       tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID;
-       tlbe->word1 = 0xef600000;
-       tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR
-                     | PPC44x_TLB_I | PPC44x_TLB_G;
-
        vcpu->arch.pc = 0;
        vcpu->arch.msr = 0;
        vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
@@ -469,12 +489,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
         * before it's programmed its own IVPR. */
        vcpu->arch.ivpr = 0x55550000;
 
-       /* Since the guest can directly access the timebase, it must know the
-        * real timebase frequency. Accordingly, it must see the state of
-        * CCR1[TCS]. */
-       vcpu->arch.ccr1 = mfspr(SPRN_CCR1);
-
-       return 0;
+       return kvmppc_core_vcpu_setup(vcpu);
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
@@ -552,33 +567,10 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
        return -ENOTSUPP;
 }
 
-/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
 int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
                                   struct kvm_translation *tr)
 {
-       struct kvmppc_44x_tlbe *gtlbe;
-       int index;
-       gva_t eaddr;
-       u8 pid;
-       u8 as;
-
-       eaddr = tr->linear_address;
-       pid = (tr->linear_address >> 32) & 0xff;
-       as = (tr->linear_address >> 40) & 0x1;
-
-       index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as);
-       if (index == -1) {
-               tr->valid = 0;
-               return 0;
-       }
-
-       gtlbe = &vcpu->arch.guest_tlb[index];
-
-       tr->physical_address = tlb_xlate(gtlbe, eaddr);
-       /* XXX what does "writeable" and "usermode" even mean? */
-       tr->valid = 1;
-
-       return 0;
+       return kvmppc_core_vcpu_translate(vcpu, tr);
 }
 
 static int kvmppc_booke_init(void)