diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-07-04 14:35:11 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-07-05 10:09:14 -0400 |
commit | 70e92c7ee94094d2db8bfe225a8c9b1bde89c26d (patch) | |
tree | be4f2ba4705ed81862392378fb220d6d0b840fd1 /arch/mips/kvm | |
parent | d85ebff0073c783f0c74dc0e08c348f6f2d807c7 (diff) |
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: James 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: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/mips/kvm')
-rw-r--r-- | arch/mips/kvm/entry.c | 16 | ||||
-rw-r--r-- | arch/mips/kvm/mips.c | 6 |
2 files changed, 10 insertions, 12 deletions
diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c index de8b6ec5573f..75ba7c2ecb3d 100644 --- a/arch/mips/kvm/entry.c +++ b/arch/mips/kvm/entry.c | |||
@@ -178,12 +178,6 @@ void *kvm_mips_build_vcpu_run(void *addr) | |||
178 | UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), K1); | 178 | UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), K1); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Save hi/lo */ | ||
182 | uasm_i_mflo(&p, V0); | ||
183 | UASM_i_SW(&p, V0, offsetof(struct pt_regs, lo), K1); | ||
184 | uasm_i_mfhi(&p, V1); | ||
185 | UASM_i_SW(&p, V1, offsetof(struct pt_regs, hi), K1); | ||
186 | |||
187 | /* Save host status */ | 181 | /* Save host status */ |
188 | uasm_i_mfc0(&p, V0, C0_STATUS); | 182 | uasm_i_mfc0(&p, V0, C0_STATUS); |
189 | UASM_i_SW(&p, V0, offsetof(struct pt_regs, cp0_status), K1); | 183 | 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 | UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); | 301 | UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); |
308 | } | 302 | } |
309 | 303 | ||
304 | #ifndef CONFIG_CPU_MIPSR6 | ||
310 | /* Restore hi/lo */ | 305 | /* Restore hi/lo */ |
311 | UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, hi), K1); | 306 | UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, hi), K1); |
312 | uasm_i_mthi(&p, K0); | 307 | uasm_i_mthi(&p, K0); |
313 | 308 | ||
314 | UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, lo), K1); | 309 | UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, lo), K1); |
315 | uasm_i_mtlo(&p, K0); | 310 | uasm_i_mtlo(&p, K0); |
311 | #endif | ||
316 | 312 | ||
317 | /* Restore the guest's k0/k1 registers */ | 313 | /* Restore the guest's k0/k1 registers */ |
318 | UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, gprs[K0]), K1); | 314 | 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 | UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); | 404 | UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1); |
409 | } | 405 | } |
410 | 406 | ||
407 | #ifndef CONFIG_CPU_MIPSR6 | ||
411 | /* We need to save hi/lo and restore them on the way out */ | 408 | /* We need to save hi/lo and restore them on the way out */ |
412 | uasm_i_mfhi(&p, T0); | 409 | uasm_i_mfhi(&p, T0); |
413 | UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, hi), K1); | 410 | UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, hi), K1); |
414 | 411 | ||
415 | uasm_i_mflo(&p, T0); | 412 | uasm_i_mflo(&p, T0); |
416 | UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, lo), K1); | 413 | UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, lo), K1); |
414 | #endif | ||
417 | 415 | ||
418 | /* Finally save guest k1 to VCPU */ | 416 | /* Finally save guest k1 to VCPU */ |
419 | uasm_i_ehb(&p); | 417 | uasm_i_ehb(&p); |
@@ -663,12 +661,6 @@ static void *kvm_mips_build_ret_to_host(void *addr) | |||
663 | UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), K1); | 661 | UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), K1); |
664 | } | 662 | } |
665 | 663 | ||
666 | UASM_i_LW(&p, K0, offsetof(struct pt_regs, hi), K1); | ||
667 | uasm_i_mthi(&p, K0); | ||
668 | |||
669 | UASM_i_LW(&p, K0, offsetof(struct pt_regs, lo), K1); | ||
670 | uasm_i_mtlo(&p, K0); | ||
671 | |||
672 | /* Restore RDHWR access */ | 664 | /* Restore RDHWR access */ |
673 | UASM_i_LA_mostly(&p, K0, (long)&hwrena); | 665 | UASM_i_LA_mostly(&p, K0, (long)&hwrena); |
674 | uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0); | 666 | uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0); |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 7c76768ff364..414b00074e29 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
@@ -521,8 +521,10 @@ static u64 kvm_mips_get_one_regs[] = { | |||
521 | KVM_REG_MIPS_R30, | 521 | KVM_REG_MIPS_R30, |
522 | KVM_REG_MIPS_R31, | 522 | KVM_REG_MIPS_R31, |
523 | 523 | ||
524 | #ifndef CONFIG_CPU_MIPSR6 | ||
524 | KVM_REG_MIPS_HI, | 525 | KVM_REG_MIPS_HI, |
525 | KVM_REG_MIPS_LO, | 526 | KVM_REG_MIPS_LO, |
527 | #endif | ||
526 | KVM_REG_MIPS_PC, | 528 | KVM_REG_MIPS_PC, |
527 | 529 | ||
528 | KVM_REG_MIPS_CP0_INDEX, | 530 | KVM_REG_MIPS_CP0_INDEX, |
@@ -666,12 +668,14 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
666 | case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: | 668 | case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: |
667 | v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; | 669 | v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; |
668 | break; | 670 | break; |
671 | #ifndef CONFIG_CPU_MIPSR6 | ||
669 | case KVM_REG_MIPS_HI: | 672 | case KVM_REG_MIPS_HI: |
670 | v = (long)vcpu->arch.hi; | 673 | v = (long)vcpu->arch.hi; |
671 | break; | 674 | break; |
672 | case KVM_REG_MIPS_LO: | 675 | case KVM_REG_MIPS_LO: |
673 | v = (long)vcpu->arch.lo; | 676 | v = (long)vcpu->arch.lo; |
674 | break; | 677 | break; |
678 | #endif | ||
675 | case KVM_REG_MIPS_PC: | 679 | case KVM_REG_MIPS_PC: |
676 | v = (long)vcpu->arch.pc; | 680 | v = (long)vcpu->arch.pc; |
677 | break; | 681 | break; |
@@ -887,12 +891,14 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
887 | case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31: | 891 | case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31: |
888 | vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v; | 892 | vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v; |
889 | break; | 893 | break; |
894 | #ifndef CONFIG_CPU_MIPSR6 | ||
890 | case KVM_REG_MIPS_HI: | 895 | case KVM_REG_MIPS_HI: |
891 | vcpu->arch.hi = v; | 896 | vcpu->arch.hi = v; |
892 | break; | 897 | break; |
893 | case KVM_REG_MIPS_LO: | 898 | case KVM_REG_MIPS_LO: |
894 | vcpu->arch.lo = v; | 899 | vcpu->arch.lo = v; |
895 | break; | 900 | break; |
901 | #endif | ||
896 | case KVM_REG_MIPS_PC: | 902 | case KVM_REG_MIPS_PC: |
897 | vcpu->arch.pc = v; | 903 | vcpu->arch.pc = v; |
898 | break; | 904 | break; |