KVM: PPC: Make ONE_REG powerpc generic
Make ONE_REG generic for server and embedded architectures by moving kvm_vcpu_ioctl_get_one_reg() and kvm_vcpu_ioctl_set_one_reg() functions to powerpc layer. Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
95d80a294b
commit
8a41ea53b3
3 changed files with 138 additions and 129 deletions
|
@ -535,33 +535,28 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
|
union kvmppc_one_reg *val)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
union kvmppc_one_reg val;
|
|
||||||
int size;
|
|
||||||
long int i;
|
long int i;
|
||||||
|
|
||||||
size = one_reg_size(reg->id);
|
r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val);
|
||||||
if (size > sizeof(val))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val);
|
|
||||||
if (r == -EINVAL) {
|
if (r == -EINVAL) {
|
||||||
r = 0;
|
r = 0;
|
||||||
switch (reg->id) {
|
switch (id) {
|
||||||
case KVM_REG_PPC_DAR:
|
case KVM_REG_PPC_DAR:
|
||||||
val = get_reg_val(reg->id, kvmppc_get_dar(vcpu));
|
*val = get_reg_val(id, kvmppc_get_dar(vcpu));
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_DSISR:
|
case KVM_REG_PPC_DSISR:
|
||||||
val = get_reg_val(reg->id, kvmppc_get_dsisr(vcpu));
|
*val = get_reg_val(id, kvmppc_get_dsisr(vcpu));
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
|
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
|
||||||
i = reg->id - KVM_REG_PPC_FPR0;
|
i = id - KVM_REG_PPC_FPR0;
|
||||||
val = get_reg_val(reg->id, VCPU_FPR(vcpu, i));
|
*val = get_reg_val(id, VCPU_FPR(vcpu, i));
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_FPSCR:
|
case KVM_REG_PPC_FPSCR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.fp.fpscr);
|
*val = get_reg_val(id, vcpu->arch.fp.fpscr);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_ALTIVEC
|
#ifdef CONFIG_ALTIVEC
|
||||||
case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
|
case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
|
||||||
|
@ -569,110 +564,94 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
|
val->vval = vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0];
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VSCR:
|
case KVM_REG_PPC_VSCR:
|
||||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
|
*val = get_reg_val(id, vcpu->arch.vr.vscr.u[3]);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VRSAVE:
|
case KVM_REG_PPC_VRSAVE:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.vrsave);
|
*val = get_reg_val(id, vcpu->arch.vrsave);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
#ifdef CONFIG_VSX
|
#ifdef CONFIG_VSX
|
||||||
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
|
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
|
||||||
if (cpu_has_feature(CPU_FTR_VSX)) {
|
if (cpu_has_feature(CPU_FTR_VSX)) {
|
||||||
long int i = reg->id - KVM_REG_PPC_VSR0;
|
i = id - KVM_REG_PPC_VSR0;
|
||||||
val.vsxval[0] = vcpu->arch.fp.fpr[i][0];
|
val->vsxval[0] = vcpu->arch.fp.fpr[i][0];
|
||||||
val.vsxval[1] = vcpu->arch.fp.fpr[i][1];
|
val->vsxval[1] = vcpu->arch.fp.fpr[i][1];
|
||||||
} else {
|
} else {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_VSX */
|
#endif /* CONFIG_VSX */
|
||||||
case KVM_REG_PPC_DEBUG_INST: {
|
case KVM_REG_PPC_DEBUG_INST:
|
||||||
u32 opcode = INS_TW;
|
*val = get_reg_val(id, INS_TW);
|
||||||
r = copy_to_user((u32 __user *)(long)reg->addr,
|
|
||||||
&opcode, sizeof(u32));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#ifdef CONFIG_KVM_XICS
|
#ifdef CONFIG_KVM_XICS
|
||||||
case KVM_REG_PPC_ICP_STATE:
|
case KVM_REG_PPC_ICP_STATE:
|
||||||
if (!vcpu->arch.icp) {
|
if (!vcpu->arch.icp) {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val = get_reg_val(reg->id, kvmppc_xics_get_icp(vcpu));
|
*val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_KVM_XICS */
|
#endif /* CONFIG_KVM_XICS */
|
||||||
case KVM_REG_PPC_FSCR:
|
case KVM_REG_PPC_FSCR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.fscr);
|
*val = get_reg_val(id, vcpu->arch.fscr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_TAR:
|
case KVM_REG_PPC_TAR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.tar);
|
*val = get_reg_val(id, vcpu->arch.tar);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EBBHR:
|
case KVM_REG_PPC_EBBHR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.ebbhr);
|
*val = get_reg_val(id, vcpu->arch.ebbhr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EBBRR:
|
case KVM_REG_PPC_EBBRR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.ebbrr);
|
*val = get_reg_val(id, vcpu->arch.ebbrr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_BESCR:
|
case KVM_REG_PPC_BESCR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.bescr);
|
*val = get_reg_val(id, vcpu->arch.bescr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VTB:
|
case KVM_REG_PPC_VTB:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.vtb);
|
*val = get_reg_val(id, vcpu->arch.vtb);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IC:
|
case KVM_REG_PPC_IC:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.ic);
|
*val = get_reg_val(id, vcpu->arch.ic);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
|
|
||||||
r = -EFAULT;
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
|
union kvmppc_one_reg *val)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
union kvmppc_one_reg val;
|
|
||||||
int size;
|
|
||||||
long int i;
|
long int i;
|
||||||
|
|
||||||
size = one_reg_size(reg->id);
|
r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val);
|
||||||
if (size > sizeof(val))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val);
|
|
||||||
if (r == -EINVAL) {
|
if (r == -EINVAL) {
|
||||||
r = 0;
|
r = 0;
|
||||||
switch (reg->id) {
|
switch (id) {
|
||||||
case KVM_REG_PPC_DAR:
|
case KVM_REG_PPC_DAR:
|
||||||
kvmppc_set_dar(vcpu, set_reg_val(reg->id, val));
|
kvmppc_set_dar(vcpu, set_reg_val(id, *val));
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_DSISR:
|
case KVM_REG_PPC_DSISR:
|
||||||
kvmppc_set_dsisr(vcpu, set_reg_val(reg->id, val));
|
kvmppc_set_dsisr(vcpu, set_reg_val(id, *val));
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
|
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
|
||||||
i = reg->id - KVM_REG_PPC_FPR0;
|
i = id - KVM_REG_PPC_FPR0;
|
||||||
VCPU_FPR(vcpu, i) = set_reg_val(reg->id, val);
|
VCPU_FPR(vcpu, i) = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_FPSCR:
|
case KVM_REG_PPC_FPSCR:
|
||||||
vcpu->arch.fp.fpscr = set_reg_val(reg->id, val);
|
vcpu->arch.fp.fpscr = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_ALTIVEC
|
#ifdef CONFIG_ALTIVEC
|
||||||
case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
|
case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
|
||||||
|
@ -680,29 +659,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
|
vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0] = val->vval;
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VSCR:
|
case KVM_REG_PPC_VSCR:
|
||||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
|
vcpu->arch.vr.vscr.u[3] = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VRSAVE:
|
case KVM_REG_PPC_VRSAVE:
|
||||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vcpu->arch.vrsave = set_reg_val(reg->id, val);
|
vcpu->arch.vrsave = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
#ifdef CONFIG_VSX
|
#ifdef CONFIG_VSX
|
||||||
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
|
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
|
||||||
if (cpu_has_feature(CPU_FTR_VSX)) {
|
if (cpu_has_feature(CPU_FTR_VSX)) {
|
||||||
long int i = reg->id - KVM_REG_PPC_VSR0;
|
i = id - KVM_REG_PPC_VSR0;
|
||||||
vcpu->arch.fp.fpr[i][0] = val.vsxval[0];
|
vcpu->arch.fp.fpr[i][0] = val->vsxval[0];
|
||||||
vcpu->arch.fp.fpr[i][1] = val.vsxval[1];
|
vcpu->arch.fp.fpr[i][1] = val->vsxval[1];
|
||||||
} else {
|
} else {
|
||||||
r = -ENXIO;
|
r = -ENXIO;
|
||||||
}
|
}
|
||||||
|
@ -715,29 +694,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r = kvmppc_xics_set_icp(vcpu,
|
r = kvmppc_xics_set_icp(vcpu,
|
||||||
set_reg_val(reg->id, val));
|
set_reg_val(id, *val));
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_KVM_XICS */
|
#endif /* CONFIG_KVM_XICS */
|
||||||
case KVM_REG_PPC_FSCR:
|
case KVM_REG_PPC_FSCR:
|
||||||
vcpu->arch.fscr = set_reg_val(reg->id, val);
|
vcpu->arch.fscr = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_TAR:
|
case KVM_REG_PPC_TAR:
|
||||||
vcpu->arch.tar = set_reg_val(reg->id, val);
|
vcpu->arch.tar = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EBBHR:
|
case KVM_REG_PPC_EBBHR:
|
||||||
vcpu->arch.ebbhr = set_reg_val(reg->id, val);
|
vcpu->arch.ebbhr = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EBBRR:
|
case KVM_REG_PPC_EBBRR:
|
||||||
vcpu->arch.ebbrr = set_reg_val(reg->id, val);
|
vcpu->arch.ebbrr = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_BESCR:
|
case KVM_REG_PPC_BESCR:
|
||||||
vcpu->arch.bescr = set_reg_val(reg->id, val);
|
vcpu->arch.bescr = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VTB:
|
case KVM_REG_PPC_VTB:
|
||||||
vcpu->arch.vtb = set_reg_val(reg->id, val);
|
vcpu->arch.vtb = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IC:
|
case KVM_REG_PPC_IC:
|
||||||
vcpu->arch.ic = set_reg_val(reg->id, val);
|
vcpu->arch.ic = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
|
|
|
@ -1564,150 +1564,125 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
|
||||||
return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs);
|
return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
|
union kvmppc_one_reg *val)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
union kvmppc_one_reg val;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
size = one_reg_size(reg->id);
|
switch (id) {
|
||||||
if (size > sizeof(val))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
switch (reg->id) {
|
|
||||||
case KVM_REG_PPC_IAC1:
|
case KVM_REG_PPC_IAC1:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac1);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.iac1);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IAC2:
|
case KVM_REG_PPC_IAC2:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac2);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.iac2);
|
||||||
break;
|
break;
|
||||||
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
||||||
case KVM_REG_PPC_IAC3:
|
case KVM_REG_PPC_IAC3:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac3);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.iac3);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IAC4:
|
case KVM_REG_PPC_IAC4:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac4);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.iac4);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KVM_REG_PPC_DAC1:
|
case KVM_REG_PPC_DAC1:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac1);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.dac1);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_DAC2:
|
case KVM_REG_PPC_DAC2:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2);
|
*val = get_reg_val(id, vcpu->arch.dbg_reg.dac2);
|
||||||
break;
|
|
||||||
case KVM_REG_PPC_DBSR:
|
|
||||||
val = get_reg_val(reg->id, vcpu->arch.dbsr);
|
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EPR: {
|
case KVM_REG_PPC_EPR: {
|
||||||
u32 epr = kvmppc_get_epr(vcpu);
|
u32 epr = kvmppc_get_epr(vcpu);
|
||||||
val = get_reg_val(reg->id, epr);
|
*val = get_reg_val(id, epr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_64BIT)
|
#if defined(CONFIG_64BIT)
|
||||||
case KVM_REG_PPC_EPCR:
|
case KVM_REG_PPC_EPCR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.epcr);
|
*val = get_reg_val(id, vcpu->arch.epcr);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KVM_REG_PPC_TCR:
|
case KVM_REG_PPC_TCR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.tcr);
|
*val = get_reg_val(id, vcpu->arch.tcr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_TSR:
|
case KVM_REG_PPC_TSR:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.tsr);
|
*val = get_reg_val(id, vcpu->arch.tsr);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_DEBUG_INST:
|
case KVM_REG_PPC_DEBUG_INST:
|
||||||
val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV_DEBUG);
|
*val = get_reg_val(id, KVMPPC_INST_EHPRIV_DEBUG);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_VRSAVE:
|
case KVM_REG_PPC_VRSAVE:
|
||||||
val = get_reg_val(reg->id, vcpu->arch.vrsave);
|
*val = get_reg_val(id, vcpu->arch.vrsave);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val);
|
r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
|
|
||||||
r = -EFAULT;
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
|
union kvmppc_one_reg *val)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
union kvmppc_one_reg val;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
size = one_reg_size(reg->id);
|
switch (id) {
|
||||||
if (size > sizeof(val))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
switch (reg->id) {
|
|
||||||
case KVM_REG_PPC_IAC1:
|
case KVM_REG_PPC_IAC1:
|
||||||
vcpu->arch.dbg_reg.iac1 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.iac1 = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IAC2:
|
case KVM_REG_PPC_IAC2:
|
||||||
vcpu->arch.dbg_reg.iac2 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.iac2 = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
||||||
case KVM_REG_PPC_IAC3:
|
case KVM_REG_PPC_IAC3:
|
||||||
vcpu->arch.dbg_reg.iac3 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.iac3 = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_IAC4:
|
case KVM_REG_PPC_IAC4:
|
||||||
vcpu->arch.dbg_reg.iac4 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.iac4 = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KVM_REG_PPC_DAC1:
|
case KVM_REG_PPC_DAC1:
|
||||||
vcpu->arch.dbg_reg.dac1 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.dac1 = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_DAC2:
|
case KVM_REG_PPC_DAC2:
|
||||||
vcpu->arch.dbg_reg.dac2 = set_reg_val(reg->id, val);
|
vcpu->arch.dbg_reg.dac2 = set_reg_val(id, *val);
|
||||||
break;
|
|
||||||
case KVM_REG_PPC_DBSR:
|
|
||||||
vcpu->arch.dbsr = set_reg_val(reg->id, val);
|
|
||||||
break;
|
break;
|
||||||
case KVM_REG_PPC_EPR: {
|
case KVM_REG_PPC_EPR: {
|
||||||
u32 new_epr = set_reg_val(reg->id, val);
|
u32 new_epr = set_reg_val(id, *val);
|
||||||
kvmppc_set_epr(vcpu, new_epr);
|
kvmppc_set_epr(vcpu, new_epr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_64BIT)
|
#if defined(CONFIG_64BIT)
|
||||||
case KVM_REG_PPC_EPCR: {
|
case KVM_REG_PPC_EPCR: {
|
||||||
u32 new_epcr = set_reg_val(reg->id, val);
|
u32 new_epcr = set_reg_val(id, *val);
|
||||||
kvmppc_set_epcr(vcpu, new_epcr);
|
kvmppc_set_epcr(vcpu, new_epcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case KVM_REG_PPC_OR_TSR: {
|
case KVM_REG_PPC_OR_TSR: {
|
||||||
u32 tsr_bits = set_reg_val(reg->id, val);
|
u32 tsr_bits = set_reg_val(id, *val);
|
||||||
kvmppc_set_tsr_bits(vcpu, tsr_bits);
|
kvmppc_set_tsr_bits(vcpu, tsr_bits);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KVM_REG_PPC_CLEAR_TSR: {
|
case KVM_REG_PPC_CLEAR_TSR: {
|
||||||
u32 tsr_bits = set_reg_val(reg->id, val);
|
u32 tsr_bits = set_reg_val(id, *val);
|
||||||
kvmppc_clr_tsr_bits(vcpu, tsr_bits);
|
kvmppc_clr_tsr_bits(vcpu, tsr_bits);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KVM_REG_PPC_TSR: {
|
case KVM_REG_PPC_TSR: {
|
||||||
u32 tsr = set_reg_val(reg->id, val);
|
u32 tsr = set_reg_val(id, *val);
|
||||||
kvmppc_set_tsr(vcpu, tsr);
|
kvmppc_set_tsr(vcpu, tsr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KVM_REG_PPC_TCR: {
|
case KVM_REG_PPC_TCR: {
|
||||||
u32 tcr = set_reg_val(reg->id, val);
|
u32 tcr = set_reg_val(id, *val);
|
||||||
kvmppc_set_tcr(vcpu, tcr);
|
kvmppc_set_tcr(vcpu, tcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KVM_REG_PPC_VRSAVE:
|
case KVM_REG_PPC_VRSAVE:
|
||||||
vcpu->arch.vrsave = set_reg_val(reg->id, val);
|
vcpu->arch.vrsave = set_reg_val(id, *val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val);
|
r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -907,6 +907,61 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(kvmppc_handle_store);
|
EXPORT_SYMBOL_GPL(kvmppc_handle_store);
|
||||||
|
|
||||||
|
int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
union kvmppc_one_reg val;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = one_reg_size(reg->id);
|
||||||
|
if (size > sizeof(val))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = kvmppc_get_one_reg(vcpu, reg->id, &val);
|
||||||
|
if (r == -EINVAL) {
|
||||||
|
r = 0;
|
||||||
|
switch (reg->id) {
|
||||||
|
default:
|
||||||
|
r = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
|
||||||
|
r = -EFAULT;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
union kvmppc_one_reg val;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = one_reg_size(reg->id);
|
||||||
|
if (size > sizeof(val))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
r = kvmppc_set_one_reg(vcpu, reg->id, &val);
|
||||||
|
if (r == -EINVAL) {
|
||||||
|
r = 0;
|
||||||
|
switch (reg->id) {
|
||||||
|
default:
|
||||||
|
r = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
Loading…
Add table
Reference in a new issue