#ifdef CONFIG_PPC_BOOK3S /* mtdec lowers the interrupt line when positive. */
kvmppc_core_dequeue_dec(vcpu); #endif
#ifdef CONFIG_BOOKE /* On BOOKE, DEC = 0 is as good as decrementer not enabled */ if (vcpu->arch.dec == 0) return; #endif
/* * The decrementer ticks at the same rate as the timebase, so * that's how we convert the guest DEC value to the number of * host ticks.
*/
dec_time = vcpu->arch.dec; /* * Guest timebase ticks at the same frequency as host timebase. * So use the host timebase calculations for decrementer emulation.
*/
dec_time = tb_to_ns(dec_time);
dec_nsec = do_div(dec_time, NSEC_PER_SEC);
hrtimer_start(&vcpu->arch.dec_timer,
ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
vcpu->arch.dec_jiffies = get_tb();
}
#ifdef CONFIG_BOOKE if (vcpu->arch.dec < jd) return 0; #endif
return vcpu->arch.dec - jd;
}
staticint kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
{ enum emulation_result emulated = EMULATE_DONE;
ulong spr_val = kvmppc_get_gpr(vcpu, rs);
switch (sprn) { case SPRN_SRR0:
kvmppc_set_srr0(vcpu, spr_val); break; case SPRN_SRR1:
kvmppc_set_srr1(vcpu, spr_val); break;
/* XXX We need to context-switch the timebase for
* watchdog and FIT. */ case SPRN_TBWL: break; case SPRN_TBWU: break;
case SPRN_DEC:
vcpu->arch.dec = (u32) spr_val;
kvmppc_emulate_dec(vcpu); break;
case SPRN_SPRG0:
kvmppc_set_sprg0(vcpu, spr_val); break; case SPRN_SPRG1:
kvmppc_set_sprg1(vcpu, spr_val); break; case SPRN_SPRG2:
kvmppc_set_sprg2(vcpu, spr_val); break; case SPRN_SPRG3:
kvmppc_set_sprg3(vcpu, spr_val); break;
/* PIR can legally be written, but we ignore it */ case SPRN_PIR: break;
staticint kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
{ enum emulation_result emulated = EMULATE_DONE;
ulong spr_val = 0;
switch (sprn) { case SPRN_SRR0:
spr_val = kvmppc_get_srr0(vcpu); break; case SPRN_SRR1:
spr_val = kvmppc_get_srr1(vcpu); break; case SPRN_PVR:
spr_val = vcpu->arch.pvr; break; case SPRN_PIR:
spr_val = vcpu->vcpu_id; 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:
spr_val = get_tb() >> 32; break; case SPRN_TBWU:
spr_val = get_tb(); break;
case SPRN_SPRG0:
spr_val = kvmppc_get_sprg0(vcpu); break; case SPRN_SPRG1:
spr_val = kvmppc_get_sprg1(vcpu); break; case SPRN_SPRG2:
spr_val = kvmppc_get_sprg2(vcpu); break; case SPRN_SPRG3:
spr_val = kvmppc_get_sprg3(vcpu); break; /* Note: SPRG4-7 are user-readable, so we don't get
* a trap. */
if (emulated == EMULATE_DONE)
kvmppc_set_gpr(vcpu, rt, spr_val);
kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
return emulated;
}
/* XXX Should probably auto-generate instruction decoding for a particular core
* from opcode tables in the future. */ int kvmppc_emulate_instruction(struct kvm_vcpu *vcpu)
{
u32 inst;
ppc_inst_t pinst; int rs, rt, sprn; enum emulation_result emulated; int advance = 1;
/* this default type might be overwritten by subcategories */
kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
/* Advance past emulated instruction. */ /* * If this ever handles prefixed instructions, the 4 * will need to become ppc_inst_len(pinst) instead.
*/ if (advance)
kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.