arch/powerpc/kvm/e500_emulate.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/e500_emulate.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kvm/e500_emulate.c
Extension
.c
Size
9851 bytes
Lines
453
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((param & PPC_DBELL_MSG_BRDCAST) || (cpir == pir)) {
			set_bit(prio, &cvcpu->arch.pending_exceptions);
			kvm_vcpu_kick(cvcpu);
		}
	}

	return EMULATE_DONE;
}
#endif

static int kvmppc_e500_emul_ehpriv(struct kvm_vcpu *vcpu,
				   unsigned int inst, int *advance)
{
	int emulated = EMULATE_DONE;

	switch (get_oc(inst)) {
	case EHPRIV_OC_DEBUG:
		vcpu->run->exit_reason = KVM_EXIT_DEBUG;
		vcpu->run->debug.arch.address = vcpu->arch.regs.nip;
		vcpu->run->debug.arch.status = 0;
		kvmppc_account_exit(vcpu, DEBUG_EXITS);
		emulated = EMULATE_EXIT_USER;
		*advance = 0;
		break;
	default:
		emulated = EMULATE_FAIL;
	}
	return emulated;
}

static int kvmppc_e500_emul_dcbtls(struct kvm_vcpu *vcpu)
{
	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);

	/* Always fail to lock the cache */
	vcpu_e500->l1csr0 |= L1CSR0_CUL;
	return EMULATE_DONE;
}

static int kvmppc_e500_emul_mftmr(struct kvm_vcpu *vcpu, unsigned int inst,
				  int rt)
{
	/* Expose one thread per vcpu */
	if (get_tmrn(inst) == TMRN_TMCFG0) {
		kvmppc_set_gpr(vcpu, rt,
			       1 | (1 << TMRN_TMCFG0_NATHRD_SHIFT));
		return EMULATE_DONE;
	}

	return EMULATE_FAIL;
}

int kvmppc_core_emulate_op_e500(struct kvm_vcpu *vcpu,
				unsigned int inst, int *advance)
{
	int emulated = EMULATE_DONE;
	int ra = get_ra(inst);
	int rb = get_rb(inst);
	int rt = get_rt(inst);
	gva_t ea;

	switch (get_op(inst)) {
	case 31:
		switch (get_xop(inst)) {

		case XOP_DCBTLS:
			emulated = kvmppc_e500_emul_dcbtls(vcpu);
			break;

#ifdef CONFIG_KVM_E500MC
		case XOP_MSGSND:
			emulated = kvmppc_e500_emul_msgsnd(vcpu, rb);
			break;

		case XOP_MSGCLR:
			emulated = kvmppc_e500_emul_msgclr(vcpu, rb);
			break;
#endif

		case XOP_TLBRE:
			emulated = kvmppc_e500_emul_tlbre(vcpu);
			break;

		case XOP_TLBWE:
			emulated = kvmppc_e500_emul_tlbwe(vcpu);
			break;

		case XOP_TLBSX:
			ea = kvmppc_get_ea_indexed(vcpu, ra, rb);
			emulated = kvmppc_e500_emul_tlbsx(vcpu, ea);

Annotation

Implementation Notes