Merge tag 'hda-switcheroo' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / kvm / emulate.c
index 968f401018834aa4758ec45afeb32eee327a37c8..f90e86dea7a2cfdef3a3321a878a370cdde4b287 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kvm_host.h>
+#include <linux/clockchips.h>
 
 #include <asm/reg.h>
 #include <asm/time.h>
@@ -35,7 +36,9 @@
 #define OP_TRAP 3
 #define OP_TRAP_64 2
 
+#define OP_31_XOP_TRAP      4
 #define OP_31_XOP_LWZX      23
+#define OP_31_XOP_TRAP_64   68
 #define OP_31_XOP_LBZX      87
 #define OP_31_XOP_STWX      151
 #define OP_31_XOP_STBX      215
@@ -102,8 +105,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
         */
 
        dec_time = vcpu->arch.dec;
-       dec_time *= 1000;
-       do_div(dec_time, tb_ticks_per_usec);
+       /*
+        * Guest timebase ticks at the same frequency as host decrementer.
+        * So use the host decrementer calculations for decrementer emulation.
+        */
+       dec_time = dec_time << decrementer_clockevent.shift;
+       do_div(dec_time, decrementer_clockevent.mult);
        dec_nsec = do_div(dec_time, NSEC_PER_SEC);
        hrtimer_start(&vcpu->arch.dec_timer,
                ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
@@ -141,14 +148,13 @@ u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
 int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 {
        u32 inst = kvmppc_get_last_inst(vcpu);
-       u32 ea;
-       int ra;
-       int rb;
-       int rs;
-       int rt;
-       int sprn;
+       int ra = get_ra(inst);
+       int rs = get_rs(inst);
+       int rt = get_rt(inst);
+       int sprn = get_sprn(inst);
        enum emulation_result emulated = EMULATE_DONE;
        int advance = 1;
+       ulong spr_val = 0;
 
        /* this default type might be overwritten by subcategories */
        kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
@@ -170,173 +176,143 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
        case 31:
                switch (get_xop(inst)) {
 
+               case OP_31_XOP_TRAP:
+#ifdef CONFIG_64BIT
+               case OP_31_XOP_TRAP_64:
+#endif
+#ifdef CONFIG_PPC_BOOK3S
+                       kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
+#else
+                       kvmppc_core_queue_program(vcpu,
+                                       vcpu->arch.shared->esr | ESR_PTR);
+#endif
+                       advance = 0;
+                       break;
                case OP_31_XOP_LWZX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
                        break;
 
                case OP_31_XOP_LBZX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
                        break;
 
                case OP_31_XOP_LBZUX:
-                       rt = get_rt(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
-                       ea = kvmppc_get_gpr(vcpu, rb);
-                       if (ra)
-                               ea += kvmppc_get_gpr(vcpu, ra);
-
                        emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
-                       kvmppc_set_gpr(vcpu, ra, ea);
+                       kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                        break;
 
                case OP_31_XOP_STWX:
-                       rs = get_rs(inst);
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       4, 1);
                        break;
 
                case OP_31_XOP_STBX:
-                       rs = get_rs(inst);
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       1, 1);
                        break;
 
                case OP_31_XOP_STBUX:
-                       rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
-                       ea = kvmppc_get_gpr(vcpu, rb);
-                       if (ra)
-                               ea += kvmppc_get_gpr(vcpu, ra);
-
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       1, 1);
-                       kvmppc_set_gpr(vcpu, rs, ea);
+                       kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                        break;
 
                case OP_31_XOP_LHAX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
                        break;
 
                case OP_31_XOP_LHZX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
                        break;
 
                case OP_31_XOP_LHZUX:
-                       rt = get_rt(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
-                       ea = kvmppc_get_gpr(vcpu, rb);
-                       if (ra)
-                               ea += kvmppc_get_gpr(vcpu, ra);
-
                        emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
-                       kvmppc_set_gpr(vcpu, ra, ea);
+                       kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                        break;
 
                case OP_31_XOP_MFSPR:
-                       sprn = get_sprn(inst);
-                       rt = get_rt(inst);
-
                        switch (sprn) {
                        case SPRN_SRR0:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr0);
+                               spr_val = vcpu->arch.shared->srr0;
                                break;
                        case SPRN_SRR1:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr1);
+                               spr_val = vcpu->arch.shared->srr1;
                                break;
                        case SPRN_PVR:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
+                               spr_val = vcpu->arch.pvr;
+                               break;
                        case SPRN_PIR:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
+                               spr_val = vcpu->vcpu_id;
+                               break;
                        case SPRN_MSSSR0:
-                               kvmppc_set_gpr(vcpu, rt, 0); break;
+                               spr_val = 0;
+                               break;
 
                        /* Note: mftb and TBRL/TBWL are user-accessible, so
                         * the guest can always access the real TB anyways.
                         * In fact, we probably will never see these traps. */
                        case SPRN_TBWL:
-                               kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
+                               spr_val = get_tb() >> 32;
+                               break;
                        case SPRN_TBWU:
-                               kvmppc_set_gpr(vcpu, rt, get_tb()); break;
+                               spr_val = get_tb();
+                               break;
 
                        case SPRN_SPRG0:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg0);
+                               spr_val = vcpu->arch.shared->sprg0;
                                break;
                        case SPRN_SPRG1:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg1);
+                               spr_val = vcpu->arch.shared->sprg1;
                                break;
                        case SPRN_SPRG2:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg2);
+                               spr_val = vcpu->arch.shared->sprg2;
                                break;
                        case SPRN_SPRG3:
-                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg3);
+                               spr_val = vcpu->arch.shared->sprg3;
                                break;
                        /* Note: SPRG4-7 are user-readable, so we don't get
                         * a trap. */
 
                        case SPRN_DEC:
-                       {
-                               kvmppc_set_gpr(vcpu, rt,
-                                              kvmppc_get_dec(vcpu, get_tb()));
+                               spr_val = kvmppc_get_dec(vcpu, get_tb());
                                break;
-                       }
                        default:
-                               emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
-                               if (emulated == EMULATE_FAIL) {
-                                       printk("mfspr: unknown spr %x\n", sprn);
-                                       kvmppc_set_gpr(vcpu, rt, 0);
+                               emulated = kvmppc_core_emulate_mfspr(vcpu, sprn,
+                                                                    &spr_val);
+                               if (unlikely(emulated == EMULATE_FAIL)) {
+                                       printk(KERN_INFO "mfspr: unknown spr "
+                                               "0x%x\n", sprn);
                                }
                                break;
                        }
+                       kvmppc_set_gpr(vcpu, rt, spr_val);
                        kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
                        break;
 
                case OP_31_XOP_STHX:
-                       rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       2, 1);
                        break;
 
                case OP_31_XOP_STHUX:
-                       rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
-                       ea = kvmppc_get_gpr(vcpu, rb);
-                       if (ra)
-                               ea += kvmppc_get_gpr(vcpu, ra);
-
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       2, 1);
-                       kvmppc_set_gpr(vcpu, ra, ea);
+                       kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                        break;
 
                case OP_31_XOP_MTSPR:
-                       sprn = get_sprn(inst);
-                       rs = get_rs(inst);
+                       spr_val = kvmppc_get_gpr(vcpu, rs);
                        switch (sprn) {
                        case SPRN_SRR0:
-                               vcpu->arch.shared->srr0 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->srr0 = spr_val;
                                break;
                        case SPRN_SRR1:
-                               vcpu->arch.shared->srr1 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->srr1 = spr_val;
                                break;
 
                        /* XXX We need to context-switch the timebase for
@@ -347,27 +323,29 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        case SPRN_MSSSR0: break;
 
                        case SPRN_DEC:
-                               vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.dec = spr_val;
                                kvmppc_emulate_dec(vcpu);
                                break;
 
                        case SPRN_SPRG0:
-                               vcpu->arch.shared->sprg0 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->sprg0 = spr_val;
                                break;
                        case SPRN_SPRG1:
-                               vcpu->arch.shared->sprg1 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->sprg1 = spr_val;
                                break;
                        case SPRN_SPRG2:
-                               vcpu->arch.shared->sprg2 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->sprg2 = spr_val;
                                break;
                        case SPRN_SPRG3:
-                               vcpu->arch.shared->sprg3 = kvmppc_get_gpr(vcpu, rs);
+                               vcpu->arch.shared->sprg3 = spr_val;
                                break;
 
                        default:
-                               emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
+                               emulated = kvmppc_core_emulate_mtspr(vcpu, sprn,
+                                                                    spr_val);
                                if (emulated == EMULATE_FAIL)
-                                       printk("mtspr: unknown spr %x\n", sprn);
+                                       printk(KERN_INFO "mtspr: unknown spr "
+                                               "0x%x\n", sprn);
                                break;
                        }
                        kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
@@ -382,7 +360,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        break;
 
                case OP_31_XOP_LWBRX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
                        break;
 
@@ -390,25 +367,16 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        break;
 
                case OP_31_XOP_STWBRX:
-                       rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       4, 0);
                        break;
 
                case OP_31_XOP_LHBRX:
-                       rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
                        break;
 
                case OP_31_XOP_STHBRX:
-                       rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
-
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       kvmppc_get_gpr(vcpu, rs),
                                                       2, 0);
@@ -421,99 +389,78 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                break;
 
        case OP_LWZ:
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
                break;
 
        case OP_LWZU:
-               ra = get_ra(inst);
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_LBZ:
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
                break;
 
        case OP_LBZU:
-               ra = get_ra(inst);
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_STW:
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               4, 1);
                break;
 
        case OP_STWU:
-               ra = get_ra(inst);
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               4, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_STB:
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               1, 1);
                break;
 
        case OP_STBU:
-               ra = get_ra(inst);
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               1, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_LHZ:
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
                break;
 
        case OP_LHZU:
-               ra = get_ra(inst);
-               rt = get_rt(inst);
                emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_LHA:
-               rt = get_rt(inst);
                emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
                break;
 
        case OP_LHAU:
-               ra = get_ra(inst);
-               rt = get_rt(inst);
                emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        case OP_STH:
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               2, 1);
                break;
 
        case OP_STHU:
-               ra = get_ra(inst);
-               rs = get_rs(inst);
                emulated = kvmppc_handle_store(run, vcpu,
                                               kvmppc_get_gpr(vcpu, rs),
                                               2, 1);
-               kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
+               kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
                break;
 
        default: