0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/jiffies.h>
0011 #include <linux/hrtimer.h>
0012 #include <linux/types.h>
0013 #include <linux/string.h>
0014 #include <linux/kvm_host.h>
0015 #include <linux/clockchips.h>
0016
0017 #include <asm/reg.h>
0018 #include <asm/time.h>
0019 #include <asm/byteorder.h>
0020 #include <asm/kvm_ppc.h>
0021 #include <asm/disassemble.h>
0022 #include <asm/ppc-opcode.h>
0023 #include "timing.h"
0024 #include "trace.h"
0025
0026 void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
0027 {
0028 unsigned long dec_nsec;
0029 unsigned long long dec_time;
0030
0031 pr_debug("mtDEC: %lx\n", vcpu->arch.dec);
0032 hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
0033
0034 #ifdef CONFIG_PPC_BOOK3S
0035
0036 kvmppc_core_dequeue_dec(vcpu);
0037 #endif
0038
0039 #ifdef CONFIG_BOOKE
0040
0041 if (vcpu->arch.dec == 0)
0042 return;
0043 #endif
0044
0045
0046
0047
0048
0049
0050
0051 dec_time = vcpu->arch.dec;
0052
0053
0054
0055
0056 dec_time = tb_to_ns(dec_time);
0057 dec_nsec = do_div(dec_time, NSEC_PER_SEC);
0058 hrtimer_start(&vcpu->arch.dec_timer,
0059 ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
0060 vcpu->arch.dec_jiffies = get_tb();
0061 }
0062
0063 u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
0064 {
0065 u64 jd = tb - vcpu->arch.dec_jiffies;
0066
0067 #ifdef CONFIG_BOOKE
0068 if (vcpu->arch.dec < jd)
0069 return 0;
0070 #endif
0071
0072 return vcpu->arch.dec - jd;
0073 }
0074
0075 static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
0076 {
0077 enum emulation_result emulated = EMULATE_DONE;
0078 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
0079
0080 switch (sprn) {
0081 case SPRN_SRR0:
0082 kvmppc_set_srr0(vcpu, spr_val);
0083 break;
0084 case SPRN_SRR1:
0085 kvmppc_set_srr1(vcpu, spr_val);
0086 break;
0087
0088
0089
0090 case SPRN_TBWL: break;
0091 case SPRN_TBWU: break;
0092
0093 case SPRN_DEC:
0094 vcpu->arch.dec = (u32) spr_val;
0095 kvmppc_emulate_dec(vcpu);
0096 break;
0097
0098 case SPRN_SPRG0:
0099 kvmppc_set_sprg0(vcpu, spr_val);
0100 break;
0101 case SPRN_SPRG1:
0102 kvmppc_set_sprg1(vcpu, spr_val);
0103 break;
0104 case SPRN_SPRG2:
0105 kvmppc_set_sprg2(vcpu, spr_val);
0106 break;
0107 case SPRN_SPRG3:
0108 kvmppc_set_sprg3(vcpu, spr_val);
0109 break;
0110
0111
0112 case SPRN_PIR: break;
0113
0114 default:
0115 emulated = vcpu->kvm->arch.kvm_ops->emulate_mtspr(vcpu, sprn,
0116 spr_val);
0117 if (emulated == EMULATE_FAIL)
0118 printk(KERN_INFO "mtspr: unknown spr "
0119 "0x%x\n", sprn);
0120 break;
0121 }
0122
0123 kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
0124
0125 return emulated;
0126 }
0127
0128 static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
0129 {
0130 enum emulation_result emulated = EMULATE_DONE;
0131 ulong spr_val = 0;
0132
0133 switch (sprn) {
0134 case SPRN_SRR0:
0135 spr_val = kvmppc_get_srr0(vcpu);
0136 break;
0137 case SPRN_SRR1:
0138 spr_val = kvmppc_get_srr1(vcpu);
0139 break;
0140 case SPRN_PVR:
0141 spr_val = vcpu->arch.pvr;
0142 break;
0143 case SPRN_PIR:
0144 spr_val = vcpu->vcpu_id;
0145 break;
0146
0147
0148
0149
0150 case SPRN_TBWL:
0151 spr_val = get_tb() >> 32;
0152 break;
0153 case SPRN_TBWU:
0154 spr_val = get_tb();
0155 break;
0156
0157 case SPRN_SPRG0:
0158 spr_val = kvmppc_get_sprg0(vcpu);
0159 break;
0160 case SPRN_SPRG1:
0161 spr_val = kvmppc_get_sprg1(vcpu);
0162 break;
0163 case SPRN_SPRG2:
0164 spr_val = kvmppc_get_sprg2(vcpu);
0165 break;
0166 case SPRN_SPRG3:
0167 spr_val = kvmppc_get_sprg3(vcpu);
0168 break;
0169
0170
0171
0172 case SPRN_DEC:
0173 spr_val = kvmppc_get_dec(vcpu, get_tb());
0174 break;
0175 default:
0176 emulated = vcpu->kvm->arch.kvm_ops->emulate_mfspr(vcpu, sprn,
0177 &spr_val);
0178 if (unlikely(emulated == EMULATE_FAIL)) {
0179 printk(KERN_INFO "mfspr: unknown spr "
0180 "0x%x\n", sprn);
0181 }
0182 break;
0183 }
0184
0185 if (emulated == EMULATE_DONE)
0186 kvmppc_set_gpr(vcpu, rt, spr_val);
0187 kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
0188
0189 return emulated;
0190 }
0191
0192
0193
0194 int kvmppc_emulate_instruction(struct kvm_vcpu *vcpu)
0195 {
0196 u32 inst;
0197 int rs, rt, sprn;
0198 enum emulation_result emulated;
0199 int advance = 1;
0200
0201
0202 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
0203
0204 emulated = kvmppc_get_last_inst(vcpu, INST_GENERIC, &inst);
0205 if (emulated != EMULATE_DONE)
0206 return emulated;
0207
0208 pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
0209
0210 rs = get_rs(inst);
0211 rt = get_rt(inst);
0212 sprn = get_sprn(inst);
0213
0214 switch (get_op(inst)) {
0215 case OP_TRAP:
0216 #ifdef CONFIG_PPC_BOOK3S
0217 case OP_TRAP_64:
0218 kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
0219 #else
0220 kvmppc_core_queue_program(vcpu,
0221 vcpu->arch.shared->esr | ESR_PTR);
0222 #endif
0223 advance = 0;
0224 break;
0225
0226 case 31:
0227 switch (get_xop(inst)) {
0228
0229 case OP_31_XOP_TRAP:
0230 #ifdef CONFIG_64BIT
0231 case OP_31_XOP_TRAP_64:
0232 #endif
0233 #ifdef CONFIG_PPC_BOOK3S
0234 kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
0235 #else
0236 kvmppc_core_queue_program(vcpu,
0237 vcpu->arch.shared->esr | ESR_PTR);
0238 #endif
0239 advance = 0;
0240 break;
0241
0242 case OP_31_XOP_MFSPR:
0243 emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt);
0244 if (emulated == EMULATE_AGAIN) {
0245 emulated = EMULATE_DONE;
0246 advance = 0;
0247 }
0248 break;
0249
0250 case OP_31_XOP_MTSPR:
0251 emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs);
0252 if (emulated == EMULATE_AGAIN) {
0253 emulated = EMULATE_DONE;
0254 advance = 0;
0255 }
0256 break;
0257
0258 case OP_31_XOP_TLBSYNC:
0259 break;
0260
0261 default:
0262
0263 emulated = EMULATE_FAIL;
0264 }
0265 break;
0266
0267 case 0:
0268
0269
0270
0271
0272 if (inst == KVMPPC_INST_SW_BREAKPOINT) {
0273 vcpu->run->exit_reason = KVM_EXIT_DEBUG;
0274 vcpu->run->debug.arch.status = 0;
0275 vcpu->run->debug.arch.address = kvmppc_get_pc(vcpu);
0276 emulated = EMULATE_EXIT_USER;
0277 advance = 0;
0278 } else
0279 emulated = EMULATE_FAIL;
0280
0281 break;
0282
0283 default:
0284 emulated = EMULATE_FAIL;
0285 }
0286
0287 if (emulated == EMULATE_FAIL) {
0288 emulated = vcpu->kvm->arch.kvm_ops->emulate_op(vcpu, inst,
0289 &advance);
0290 if (emulated == EMULATE_AGAIN) {
0291 advance = 0;
0292 } else if (emulated == EMULATE_FAIL) {
0293 advance = 0;
0294 printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
0295 "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
0296 }
0297 }
0298
0299 trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated);
0300
0301
0302 if (advance)
0303 kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
0304
0305 return emulated;
0306 }
0307 EXPORT_SYMBOL_GPL(kvmppc_emulate_instruction);