Пример #1
0
static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
				    int rs, ulong addr, bool w, int i)
{
	int emulated = EMULATE_FAIL;
	int r;
	u32 tmp[2];
	int len = w ? sizeof(u32) : sizeof(u64);

	kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0]);
	tmp[1] = vcpu->arch.qpr[rs];

	r = kvmppc_st(vcpu, &addr, len, tmp, true);
	vcpu->arch.paddr_accessed = addr;
	if (r < 0) {
		kvmppc_inject_pf(vcpu, addr, true);
	} else if ((r == EMULATE_DO_MMIO) && w) {
		emulated = kvmppc_handle_store(run, vcpu, tmp[0], 4, 1);
	} else if (r == EMULATE_DO_MMIO) {
		u64 val = ((u64)tmp[0] << 32) | tmp[1];
		emulated = kvmppc_handle_store(run, vcpu, val, 8, 1);
	} else {
		emulated = EMULATE_DONE;
	}

	dprintk(KERN_INFO "KVM: PSQ_ST [0x%x, 0x%x] at 0x%lx (%d)\n",
			  tmp[0], tmp[1], addr, len);

	return emulated;
}
Пример #2
0
static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
				    int rs, ulong addr, int ls_type)
{
	int emulated = EMULATE_FAIL;
	int r;
	char tmp[8];
	u64 val;
	int len;

	switch (ls_type) {
	case FPU_LS_SINGLE:
		kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp);
		val = *((u32*)tmp);
		len = sizeof(u32);
		break;
	case FPU_LS_SINGLE_LOW:
		*((u32*)tmp) = vcpu->arch.fpr[rs];
		val = vcpu->arch.fpr[rs] & 0xffffffff;
		len = sizeof(u32);
		break;
	case FPU_LS_DOUBLE:
		*((u64*)tmp) = vcpu->arch.fpr[rs];
		val = vcpu->arch.fpr[rs];
		len = sizeof(u64);
		break;
	default:
		val = 0;
		len = 0;
	}

	r = kvmppc_st(vcpu, &addr, len, tmp, true);
	vcpu->arch.paddr_accessed = addr;
	if (r < 0) {
		kvmppc_inject_pf(vcpu, addr, true);
	} else if (r == EMULATE_DO_MMIO) {
		emulated = kvmppc_handle_store(run, vcpu, val, len, 1);
	} else {
		emulated = EMULATE_DONE;
	}

	dprintk(KERN_INFO "KVM: FPR_ST [0x%llx] at 0x%lx (%d)\n",
			  val, addr, len);

	return emulated;
}
Пример #3
0
static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
				   int rs, ulong addr, int ls_type)
{
	int emulated = EMULATE_FAIL;
	int r;
	char tmp[8];
	int len = sizeof(u32);

	if (ls_type == FPU_LS_DOUBLE)
		len = sizeof(u64);

	/* read from memory */
	r = kvmppc_ld(vcpu, &addr, len, tmp, true);
	vcpu->arch.paddr_accessed = addr;

	if (r < 0) {
		kvmppc_inject_pf(vcpu, addr, false);
		goto done_load;
	} else if (r == EMULATE_DO_MMIO) {
		emulated = kvmppc_handle_load(run, vcpu, KVM_MMIO_REG_FPR | rs,
					      len, 1);
		goto done_load;
	}

	emulated = EMULATE_DONE;

	/* put in registers */
	switch (ls_type) {
	case FPU_LS_SINGLE:
		kvm_cvt_fd((u32*)tmp, &VCPU_FPR(vcpu, rs));
		vcpu->arch.qpr[rs] = *((u32*)tmp);
		break;
	case FPU_LS_DOUBLE:
		VCPU_FPR(vcpu, rs) = *((u64*)tmp);
		break;
	}

	dprintk(KERN_INFO "KVM: FPR_LD [0x%llx] at 0x%lx (%d)\n", *(u64*)tmp,
			  addr, len);

done_load:
	return emulated;
}
Пример #4
0
static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
				   int rs, ulong addr, bool w, int i)
{
	int emulated = EMULATE_FAIL;
	int r;
	float one = 1.0;
	u32 tmp[2];

	/* read from memory */
	if (w) {
		r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true);
		memcpy(&tmp[1], &one, sizeof(u32));
	} else {
		r = kvmppc_ld(vcpu, &addr, sizeof(u32) * 2, tmp, true);
	}
	vcpu->arch.paddr_accessed = addr;
	if (r < 0) {
		kvmppc_inject_pf(vcpu, addr, false);
		goto done_load;
	} else if ((r == EMULATE_DO_MMIO) && w) {
		emulated = kvmppc_handle_load(run, vcpu, KVM_MMIO_REG_FPR | rs,
					      4, 1);
		vcpu->arch.qpr[rs] = tmp[1];
		goto done_load;
	} else if (r == EMULATE_DO_MMIO) {
		emulated = kvmppc_handle_load(run, vcpu, KVM_MMIO_REG_FQPR | rs,
					      8, 1);
		goto done_load;
	}

	emulated = EMULATE_DONE;

	/* put in registers */
	kvm_cvt_fd(&tmp[0], &VCPU_FPR(vcpu, rs));
	vcpu->arch.qpr[rs] = tmp[1];

	dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0],
			  tmp[1], addr, w ? 4 : 8);

done_load:
	return emulated;
}