Commit 70e92c7e authored by James Hogan's avatar James Hogan Committed by Paolo Bonzini

MIPS: KVM: Don't save/restore lo/hi for r6

MIPSr6 doesn't have lo/hi registers, so don't bother saving or
restoring them, and don't expose them to userland with the KVM ioctl
interface either.

In fact the lo/hi registers aren't callee saved in the MIPS ABIs anyway,
so there is no need to preserve the host lo/hi values at all when
transitioning to and from the guest (which happens via a function call).
Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim KrÄmáŠ<rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent d85ebff0
...@@ -178,12 +178,6 @@ void *kvm_mips_build_vcpu_run(void *addr) ...@@ -178,12 +178,6 @@ void *kvm_mips_build_vcpu_run(void *addr)
UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), K1); UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), K1);
} }
/* Save hi/lo */
uasm_i_mflo(&p, V0);
UASM_i_SW(&p, V0, offsetof(struct pt_regs, lo), K1);
uasm_i_mfhi(&p, V1);
UASM_i_SW(&p, V1, offsetof(struct pt_regs, hi), K1);
/* Save host status */ /* Save host status */
uasm_i_mfc0(&p, V0, C0_STATUS); uasm_i_mfc0(&p, V0, C0_STATUS);
UASM_i_SW(&p, V0, offsetof(struct pt_regs, cp0_status), K1); UASM_i_SW(&p, V0, offsetof(struct pt_regs, cp0_status), K1);
...@@ -307,12 +301,14 @@ static void *kvm_mips_build_enter_guest(void *addr) ...@@ -307,12 +301,14 @@ static void *kvm_mips_build_enter_guest(void *addr)
UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1);
} }
#ifndef CONFIG_CPU_MIPSR6
/* Restore hi/lo */ /* Restore hi/lo */
UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, hi), K1); UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, hi), K1);
uasm_i_mthi(&p, K0); uasm_i_mthi(&p, K0);
UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, lo), K1); UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, lo), K1);
uasm_i_mtlo(&p, K0); uasm_i_mtlo(&p, K0);
#endif
/* Restore the guest's k0/k1 registers */ /* Restore the guest's k0/k1 registers */
UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, gprs[K0]), K1); UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, gprs[K0]), K1);
...@@ -408,12 +404,14 @@ void *kvm_mips_build_exit(void *addr) ...@@ -408,12 +404,14 @@ void *kvm_mips_build_exit(void *addr)
UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1);
} }
#ifndef CONFIG_CPU_MIPSR6
/* We need to save hi/lo and restore them on the way out */ /* We need to save hi/lo and restore them on the way out */
uasm_i_mfhi(&p, T0); uasm_i_mfhi(&p, T0);
UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, hi), K1); UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, hi), K1);
uasm_i_mflo(&p, T0); uasm_i_mflo(&p, T0);
UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, lo), K1); UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, lo), K1);
#endif
/* Finally save guest k1 to VCPU */ /* Finally save guest k1 to VCPU */
uasm_i_ehb(&p); uasm_i_ehb(&p);
...@@ -663,12 +661,6 @@ static void *kvm_mips_build_ret_to_host(void *addr) ...@@ -663,12 +661,6 @@ static void *kvm_mips_build_ret_to_host(void *addr)
UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), K1); UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), K1);
} }
UASM_i_LW(&p, K0, offsetof(struct pt_regs, hi), K1);
uasm_i_mthi(&p, K0);
UASM_i_LW(&p, K0, offsetof(struct pt_regs, lo), K1);
uasm_i_mtlo(&p, K0);
/* Restore RDHWR access */ /* Restore RDHWR access */
UASM_i_LA_mostly(&p, K0, (long)&hwrena); UASM_i_LA_mostly(&p, K0, (long)&hwrena);
uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0); uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0);
......
...@@ -521,8 +521,10 @@ static u64 kvm_mips_get_one_regs[] = { ...@@ -521,8 +521,10 @@ static u64 kvm_mips_get_one_regs[] = {
KVM_REG_MIPS_R30, KVM_REG_MIPS_R30,
KVM_REG_MIPS_R31, KVM_REG_MIPS_R31,
#ifndef CONFIG_CPU_MIPSR6
KVM_REG_MIPS_HI, KVM_REG_MIPS_HI,
KVM_REG_MIPS_LO, KVM_REG_MIPS_LO,
#endif
KVM_REG_MIPS_PC, KVM_REG_MIPS_PC,
KVM_REG_MIPS_CP0_INDEX, KVM_REG_MIPS_CP0_INDEX,
...@@ -666,12 +668,14 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, ...@@ -666,12 +668,14 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31:
v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0];
break; break;
#ifndef CONFIG_CPU_MIPSR6
case KVM_REG_MIPS_HI: case KVM_REG_MIPS_HI:
v = (long)vcpu->arch.hi; v = (long)vcpu->arch.hi;
break; break;
case KVM_REG_MIPS_LO: case KVM_REG_MIPS_LO:
v = (long)vcpu->arch.lo; v = (long)vcpu->arch.lo;
break; break;
#endif
case KVM_REG_MIPS_PC: case KVM_REG_MIPS_PC:
v = (long)vcpu->arch.pc; v = (long)vcpu->arch.pc;
break; break;
...@@ -887,12 +891,14 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, ...@@ -887,12 +891,14 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31: case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31:
vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v; vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v;
break; break;
#ifndef CONFIG_CPU_MIPSR6
case KVM_REG_MIPS_HI: case KVM_REG_MIPS_HI:
vcpu->arch.hi = v; vcpu->arch.hi = v;
break; break;
case KVM_REG_MIPS_LO: case KVM_REG_MIPS_LO:
vcpu->arch.lo = v; vcpu->arch.lo = v;
break; break;
#endif
case KVM_REG_MIPS_PC: case KVM_REG_MIPS_PC:
vcpu->arch.pc = v; vcpu->arch.pc = v;
break; break;
......
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