Commit 3210e2c2 authored by Huacai Chen's avatar Huacai Chen Committed by Paolo Bonzini

KVM: MIPS: Introduce and use cpu_guest_has_ldpte

Loongson-3 has lddir/ldpte instructions and their related CP0 registers
are the same as HTW. So we introduce a cpu_guest_has_ldpte flag and use
it to indicate whether we need to save/restore HTW related CP0 registers
(PWBase, PWSize, PWField and PWCtl).
Acked-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
Reviewed-by: default avatarAleksandar Markovic <aleksandar.qemu.devel@gmail.com>
Signed-off-by: default avatarHuacai Chen <chenhc@lemote.com>
Co-developed-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
Message-Id: <1590220602-3547-7-git-send-email-chenhc@lemote.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 8bf31295
...@@ -682,6 +682,9 @@ ...@@ -682,6 +682,9 @@
#ifndef cpu_guest_has_htw #ifndef cpu_guest_has_htw
#define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW) #define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW)
#endif #endif
#ifndef cpu_guest_has_ldpte
#define cpu_guest_has_ldpte (cpu_data[0].guest.options & MIPS_CPU_LDPTE)
#endif
#ifndef cpu_guest_has_mvh #ifndef cpu_guest_has_mvh
#define cpu_guest_has_mvh (cpu_data[0].guest.options & MIPS_CPU_MVH) #define cpu_guest_has_mvh (cpu_data[0].guest.options & MIPS_CPU_MVH)
#endif #endif
......
...@@ -2017,8 +2017,10 @@ static inline void decode_cpucfg(struct cpuinfo_mips *c) ...@@ -2017,8 +2017,10 @@ static inline void decode_cpucfg(struct cpuinfo_mips *c)
if (cfg2 & LOONGSON_CFG2_LEXT2) if (cfg2 & LOONGSON_CFG2_LEXT2)
c->ases |= MIPS_ASE_LOONGSON_EXT2; c->ases |= MIPS_ASE_LOONGSON_EXT2;
if (cfg2 & LOONGSON_CFG2_LSPW) if (cfg2 & LOONGSON_CFG2_LSPW) {
c->options |= MIPS_CPU_LDPTE; c->options |= MIPS_CPU_LDPTE;
c->guest.options |= MIPS_CPU_LDPTE;
}
if (cfg3 & LOONGSON_CFG3_LCAMP) if (cfg3 & LOONGSON_CFG3_LCAMP)
c->ases |= MIPS_ASE_LOONGSON_CAM; c->ases |= MIPS_ASE_LOONGSON_CAM;
......
...@@ -1706,7 +1706,7 @@ static unsigned long kvm_vz_num_regs(struct kvm_vcpu *vcpu) ...@@ -1706,7 +1706,7 @@ static unsigned long kvm_vz_num_regs(struct kvm_vcpu *vcpu)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig); ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig);
if (cpu_guest_has_segments) if (cpu_guest_has_segments)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_segments); ret += ARRAY_SIZE(kvm_vz_get_one_regs_segments);
if (cpu_guest_has_htw) if (cpu_guest_has_htw || cpu_guest_has_ldpte)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_htw); ret += ARRAY_SIZE(kvm_vz_get_one_regs_htw);
if (cpu_guest_has_maar && !cpu_guest_has_dyn_maar) if (cpu_guest_has_maar && !cpu_guest_has_dyn_maar)
ret += 1 + ARRAY_SIZE(vcpu->arch.maar); ret += 1 + ARRAY_SIZE(vcpu->arch.maar);
...@@ -1755,7 +1755,7 @@ static int kvm_vz_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices) ...@@ -1755,7 +1755,7 @@ static int kvm_vz_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices)
return -EFAULT; return -EFAULT;
indices += ARRAY_SIZE(kvm_vz_get_one_regs_segments); indices += ARRAY_SIZE(kvm_vz_get_one_regs_segments);
} }
if (cpu_guest_has_htw) { if (cpu_guest_has_htw || cpu_guest_has_ldpte) {
if (copy_to_user(indices, kvm_vz_get_one_regs_htw, if (copy_to_user(indices, kvm_vz_get_one_regs_htw,
sizeof(kvm_vz_get_one_regs_htw))) sizeof(kvm_vz_get_one_regs_htw)))
return -EFAULT; return -EFAULT;
...@@ -1878,17 +1878,17 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, ...@@ -1878,17 +1878,17 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu,
*v = read_gc0_segctl2(); *v = read_gc0_segctl2();
break; break;
case KVM_REG_MIPS_CP0_PWBASE: case KVM_REG_MIPS_CP0_PWBASE:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
*v = read_gc0_pwbase(); *v = read_gc0_pwbase();
break; break;
case KVM_REG_MIPS_CP0_PWFIELD: case KVM_REG_MIPS_CP0_PWFIELD:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
*v = read_gc0_pwfield(); *v = read_gc0_pwfield();
break; break;
case KVM_REG_MIPS_CP0_PWSIZE: case KVM_REG_MIPS_CP0_PWSIZE:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
*v = read_gc0_pwsize(); *v = read_gc0_pwsize();
break; break;
...@@ -1896,7 +1896,7 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, ...@@ -1896,7 +1896,7 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu,
*v = (long)read_gc0_wired(); *v = (long)read_gc0_wired();
break; break;
case KVM_REG_MIPS_CP0_PWCTL: case KVM_REG_MIPS_CP0_PWCTL:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
*v = read_gc0_pwctl(); *v = read_gc0_pwctl();
break; break;
...@@ -2101,17 +2101,17 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, ...@@ -2101,17 +2101,17 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu,
write_gc0_segctl2(v); write_gc0_segctl2(v);
break; break;
case KVM_REG_MIPS_CP0_PWBASE: case KVM_REG_MIPS_CP0_PWBASE:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
write_gc0_pwbase(v); write_gc0_pwbase(v);
break; break;
case KVM_REG_MIPS_CP0_PWFIELD: case KVM_REG_MIPS_CP0_PWFIELD:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
write_gc0_pwfield(v); write_gc0_pwfield(v);
break; break;
case KVM_REG_MIPS_CP0_PWSIZE: case KVM_REG_MIPS_CP0_PWSIZE:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
write_gc0_pwsize(v); write_gc0_pwsize(v);
break; break;
...@@ -2119,7 +2119,7 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, ...@@ -2119,7 +2119,7 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu,
change_gc0_wired(MIPSR6_WIRED_WIRED, v); change_gc0_wired(MIPSR6_WIRED_WIRED, v);
break; break;
case KVM_REG_MIPS_CP0_PWCTL: case KVM_REG_MIPS_CP0_PWCTL:
if (!cpu_guest_has_htw) if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL; return -EINVAL;
write_gc0_pwctl(v); write_gc0_pwctl(v);
break; break;
...@@ -2580,7 +2580,7 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu) ...@@ -2580,7 +2580,7 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
} }
/* restore HTW registers */ /* restore HTW registers */
if (cpu_guest_has_htw) { if (cpu_guest_has_htw || cpu_guest_has_ldpte) {
kvm_restore_gc0_pwbase(cop0); kvm_restore_gc0_pwbase(cop0);
kvm_restore_gc0_pwfield(cop0); kvm_restore_gc0_pwfield(cop0);
kvm_restore_gc0_pwsize(cop0); kvm_restore_gc0_pwsize(cop0);
...@@ -2685,8 +2685,8 @@ static int kvm_vz_vcpu_put(struct kvm_vcpu *vcpu, int cpu) ...@@ -2685,8 +2685,8 @@ static int kvm_vz_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
} }
/* save HTW registers if enabled in guest */ /* save HTW registers if enabled in guest */
if (cpu_guest_has_htw && if (cpu_guest_has_ldpte || (cpu_guest_has_htw &&
kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW) { kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW)) {
kvm_save_gc0_pwbase(cop0); kvm_save_gc0_pwbase(cop0);
kvm_save_gc0_pwfield(cop0); kvm_save_gc0_pwfield(cop0);
kvm_save_gc0_pwsize(cop0); kvm_save_gc0_pwsize(cop0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment