Message ID | 1588500367-1056-7-git-send-email-chenhc@lemote.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: MIPS: Add Loongson-3 support (Host Side) | expand |
нед, 3. мај 2020. у 12:11 Huacai Chen <chenhc@lemote.com> је написао/ла: > > 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). > > Signed-off-by: Huacai Chen <chenhc@lemote.com> > Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> > --- > arch/mips/include/asm/cpu-features.h | 3 +++ > arch/mips/kernel/cpu-probe.c | 1 + > arch/mips/kvm/vz.c | 26 +++++++++++++------------- > 3 files changed, 17 insertions(+), 13 deletions(-) > > diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h > index 400b123..e127495 100644 > --- a/arch/mips/include/asm/cpu-features.h > +++ b/arch/mips/include/asm/cpu-features.h > @@ -659,6 +659,9 @@ > #ifndef cpu_guest_has_htw > #define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW) > #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 > #define cpu_guest_has_mvh (cpu_data[0].guest.options & MIPS_CPU_MVH) > #endif > diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c > index ca2e6f1..be1b556 100644 > --- a/arch/mips/kernel/cpu-probe.c > +++ b/arch/mips/kernel/cpu-probe.c > @@ -2004,6 +2004,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) > * register, we correct it here. > */ > c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; > + c->guest.options |= MIPS_CPU_LDPTE; > c->writecombine = _CACHE_UNCACHED_ACCELERATED; > c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | > MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); > diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c > index 17932ab..422cd06 100644 > --- a/arch/mips/kvm/vz.c > +++ b/arch/mips/kvm/vz.c > @@ -1706,7 +1706,7 @@ static unsigned long kvm_vz_num_regs(struct kvm_vcpu *vcpu) > ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig); > if (cpu_guest_has_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); > if (cpu_guest_has_maar && !cpu_guest_has_dyn_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) > return -EFAULT; > 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, > sizeof(kvm_vz_get_one_regs_htw))) > return -EFAULT; > @@ -1878,17 +1878,17 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, > *v = read_gc0_segctl2(); > break; > case KVM_REG_MIPS_CP0_PWBASE: > - if (!cpu_guest_has_htw) > + 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) > + 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) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > *v = read_gc0_pwsize(); > break; > @@ -1896,7 +1896,7 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, > *v = (long)read_gc0_wired(); > break; > case KVM_REG_MIPS_CP0_PWCTL: > - if (!cpu_guest_has_htw) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > *v = read_gc0_pwctl(); > break; > @@ -2101,17 +2101,17 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, > write_gc0_segctl2(v); > break; > case KVM_REG_MIPS_CP0_PWBASE: > - if (!cpu_guest_has_htw) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > write_gc0_pwbase(v); > break; > case KVM_REG_MIPS_CP0_PWFIELD: > - if (!cpu_guest_has_htw) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > write_gc0_pwfield(v); > break; > case KVM_REG_MIPS_CP0_PWSIZE: > - if (!cpu_guest_has_htw) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > write_gc0_pwsize(v); > break; > @@ -2119,7 +2119,7 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, > change_gc0_wired(MIPSR6_WIRED_WIRED, v); > break; > case KVM_REG_MIPS_CP0_PWCTL: > - if (!cpu_guest_has_htw) > + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) > return -EINVAL; > write_gc0_pwctl(v); > break; > @@ -2580,7 +2580,7 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu) > } > > /* 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_pwfield(cop0); > kvm_restore_gc0_pwsize(cop0); > @@ -2685,8 +2685,8 @@ static int kvm_vz_vcpu_put(struct kvm_vcpu *vcpu, int cpu) > } > > /* save HTW registers if enabled in guest */ > - if (cpu_guest_has_htw && > - kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW) { > + if (cpu_guest_has_ldpte || (cpu_guest_has_htw && > + kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW)) { > kvm_save_gc0_pwbase(cop0); > kvm_save_gc0_pwfield(cop0); > kvm_save_gc0_pwsize(cop0); > -- > 2.7.0 > Reviewed-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 400b123..e127495 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -659,6 +659,9 @@ #ifndef cpu_guest_has_htw #define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW) #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 #define cpu_guest_has_mvh (cpu_data[0].guest.options & MIPS_CPU_MVH) #endif diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index ca2e6f1..be1b556 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -2004,6 +2004,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) * register, we correct it here. */ c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; + c->guest.options |= MIPS_CPU_LDPTE; c->writecombine = _CACHE_UNCACHED_ACCELERATED; c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index 17932ab..422cd06 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -1706,7 +1706,7 @@ static unsigned long kvm_vz_num_regs(struct kvm_vcpu *vcpu) ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig); if (cpu_guest_has_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); if (cpu_guest_has_maar && !cpu_guest_has_dyn_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) return -EFAULT; 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, sizeof(kvm_vz_get_one_regs_htw))) return -EFAULT; @@ -1878,17 +1878,17 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, *v = read_gc0_segctl2(); break; case KVM_REG_MIPS_CP0_PWBASE: - if (!cpu_guest_has_htw) + 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) + 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) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; *v = read_gc0_pwsize(); break; @@ -1896,7 +1896,7 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu, *v = (long)read_gc0_wired(); break; case KVM_REG_MIPS_CP0_PWCTL: - if (!cpu_guest_has_htw) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; *v = read_gc0_pwctl(); break; @@ -2101,17 +2101,17 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, write_gc0_segctl2(v); break; case KVM_REG_MIPS_CP0_PWBASE: - if (!cpu_guest_has_htw) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; write_gc0_pwbase(v); break; case KVM_REG_MIPS_CP0_PWFIELD: - if (!cpu_guest_has_htw) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; write_gc0_pwfield(v); break; case KVM_REG_MIPS_CP0_PWSIZE: - if (!cpu_guest_has_htw) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; write_gc0_pwsize(v); break; @@ -2119,7 +2119,7 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu, change_gc0_wired(MIPSR6_WIRED_WIRED, v); break; case KVM_REG_MIPS_CP0_PWCTL: - if (!cpu_guest_has_htw) + if (!cpu_guest_has_htw && !cpu_guest_has_ldpte) return -EINVAL; write_gc0_pwctl(v); break; @@ -2580,7 +2580,7 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu) } /* 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_pwfield(cop0); kvm_restore_gc0_pwsize(cop0); @@ -2685,8 +2685,8 @@ static int kvm_vz_vcpu_put(struct kvm_vcpu *vcpu, int cpu) } /* save HTW registers if enabled in guest */ - if (cpu_guest_has_htw && - kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW) { + if (cpu_guest_has_ldpte || (cpu_guest_has_htw && + kvm_read_sw_gc0_config3(cop0) & MIPS_CONF3_PW)) { kvm_save_gc0_pwbase(cop0); kvm_save_gc0_pwfield(cop0); kvm_save_gc0_pwsize(cop0);
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). Signed-off-by: Huacai Chen <chenhc@lemote.com> Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> --- arch/mips/include/asm/cpu-features.h | 3 +++ arch/mips/kernel/cpu-probe.c | 1 + arch/mips/kvm/vz.c | 26 +++++++++++++------------- 3 files changed, 17 insertions(+), 13 deletions(-)