in kvm/vz.c [1904:2126]
static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg,
s64 *v)
{
struct mips_coproc *cop0 = vcpu->arch.cop0;
unsigned int idx;
switch (reg->id) {
case KVM_REG_MIPS_CP0_INDEX:
*v = (long)read_gc0_index();
break;
case KVM_REG_MIPS_CP0_ENTRYLO0:
*v = entrylo_kvm_to_user(read_gc0_entrylo0());
break;
case KVM_REG_MIPS_CP0_ENTRYLO1:
*v = entrylo_kvm_to_user(read_gc0_entrylo1());
break;
case KVM_REG_MIPS_CP0_CONTEXT:
*v = (long)read_gc0_context();
break;
case KVM_REG_MIPS_CP0_CONTEXTCONFIG:
if (!cpu_guest_has_contextconfig)
return -EINVAL;
*v = read_gc0_contextconfig();
break;
case KVM_REG_MIPS_CP0_USERLOCAL:
if (!cpu_guest_has_userlocal)
return -EINVAL;
*v = read_gc0_userlocal();
break;
#ifdef CONFIG_64BIT
case KVM_REG_MIPS_CP0_XCONTEXTCONFIG:
if (!cpu_guest_has_contextconfig)
return -EINVAL;
*v = read_gc0_xcontextconfig();
break;
#endif
case KVM_REG_MIPS_CP0_PAGEMASK:
*v = (long)read_gc0_pagemask();
break;
case KVM_REG_MIPS_CP0_PAGEGRAIN:
*v = (long)read_gc0_pagegrain();
break;
case KVM_REG_MIPS_CP0_SEGCTL0:
if (!cpu_guest_has_segments)
return -EINVAL;
*v = read_gc0_segctl0();
break;
case KVM_REG_MIPS_CP0_SEGCTL1:
if (!cpu_guest_has_segments)
return -EINVAL;
*v = read_gc0_segctl1();
break;
case KVM_REG_MIPS_CP0_SEGCTL2:
if (!cpu_guest_has_segments)
return -EINVAL;
*v = read_gc0_segctl2();
break;
case KVM_REG_MIPS_CP0_PWBASE:
if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwbase();
break;
case KVM_REG_MIPS_CP0_PWFIELD:
if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwfield();
break;
case KVM_REG_MIPS_CP0_PWSIZE:
if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwsize();
break;
case KVM_REG_MIPS_CP0_WIRED:
*v = (long)read_gc0_wired();
break;
case KVM_REG_MIPS_CP0_PWCTL:
if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwctl();
break;
case KVM_REG_MIPS_CP0_HWRENA:
*v = (long)read_gc0_hwrena();
break;
case KVM_REG_MIPS_CP0_BADVADDR:
*v = (long)read_gc0_badvaddr();
break;
case KVM_REG_MIPS_CP0_BADINSTR:
if (!cpu_guest_has_badinstr)
return -EINVAL;
*v = read_gc0_badinstr();
break;
case KVM_REG_MIPS_CP0_BADINSTRP:
if (!cpu_guest_has_badinstrp)
return -EINVAL;
*v = read_gc0_badinstrp();
break;
case KVM_REG_MIPS_CP0_COUNT:
*v = kvm_mips_read_count(vcpu);
break;
case KVM_REG_MIPS_CP0_ENTRYHI:
*v = (long)read_gc0_entryhi();
break;
case KVM_REG_MIPS_CP0_COMPARE:
*v = (long)read_gc0_compare();
break;
case KVM_REG_MIPS_CP0_STATUS:
*v = (long)read_gc0_status();
break;
case KVM_REG_MIPS_CP0_INTCTL:
*v = read_gc0_intctl();
break;
case KVM_REG_MIPS_CP0_CAUSE:
*v = (long)read_gc0_cause();
break;
case KVM_REG_MIPS_CP0_EPC:
*v = (long)read_gc0_epc();
break;
case KVM_REG_MIPS_CP0_PRID:
switch (boot_cpu_type()) {
case CPU_CAVIUM_OCTEON3:
/* Octeon III has a read-only guest.PRid */
*v = read_gc0_prid();
break;
default:
*v = (long)kvm_read_c0_guest_prid(cop0);
break;
}
break;
case KVM_REG_MIPS_CP0_EBASE:
*v = kvm_vz_read_gc0_ebase();
break;
case KVM_REG_MIPS_CP0_CONFIG:
*v = read_gc0_config();
break;
case KVM_REG_MIPS_CP0_CONFIG1:
if (!cpu_guest_has_conf1)
return -EINVAL;
*v = read_gc0_config1();
break;
case KVM_REG_MIPS_CP0_CONFIG2:
if (!cpu_guest_has_conf2)
return -EINVAL;
*v = read_gc0_config2();
break;
case KVM_REG_MIPS_CP0_CONFIG3:
if (!cpu_guest_has_conf3)
return -EINVAL;
*v = read_gc0_config3();
break;
case KVM_REG_MIPS_CP0_CONFIG4:
if (!cpu_guest_has_conf4)
return -EINVAL;
*v = read_gc0_config4();
break;
case KVM_REG_MIPS_CP0_CONFIG5:
if (!cpu_guest_has_conf5)
return -EINVAL;
*v = read_gc0_config5();
break;
case KVM_REG_MIPS_CP0_CONFIG6:
*v = kvm_read_sw_gc0_config6(cop0);
break;
case KVM_REG_MIPS_CP0_MAAR(0) ... KVM_REG_MIPS_CP0_MAAR(0x3f):
if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar)
return -EINVAL;
idx = reg->id - KVM_REG_MIPS_CP0_MAAR(0);
if (idx >= ARRAY_SIZE(vcpu->arch.maar))
return -EINVAL;
*v = vcpu->arch.maar[idx];
break;
case KVM_REG_MIPS_CP0_MAARI:
if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar)
return -EINVAL;
*v = kvm_read_sw_gc0_maari(vcpu->arch.cop0);
break;
#ifdef CONFIG_64BIT
case KVM_REG_MIPS_CP0_XCONTEXT:
*v = read_gc0_xcontext();
break;
#endif
case KVM_REG_MIPS_CP0_ERROREPC:
*v = (long)read_gc0_errorepc();
break;
case KVM_REG_MIPS_CP0_KSCRATCH1 ... KVM_REG_MIPS_CP0_KSCRATCH6:
idx = reg->id - KVM_REG_MIPS_CP0_KSCRATCH1 + 2;
if (!cpu_guest_has_kscr(idx))
return -EINVAL;
switch (idx) {
case 2:
*v = (long)read_gc0_kscratch1();
break;
case 3:
*v = (long)read_gc0_kscratch2();
break;
case 4:
*v = (long)read_gc0_kscratch3();
break;
case 5:
*v = (long)read_gc0_kscratch4();
break;
case 6:
*v = (long)read_gc0_kscratch5();
break;
case 7:
*v = (long)read_gc0_kscratch6();
break;
}
break;
case KVM_REG_MIPS_COUNT_CTL:
*v = vcpu->arch.count_ctl;
break;
case KVM_REG_MIPS_COUNT_RESUME:
*v = ktime_to_ns(vcpu->arch.count_resume);
break;
case KVM_REG_MIPS_COUNT_HZ:
*v = vcpu->arch.count_hz;
break;
default:
return -EINVAL;
}
return 0;
}