KVM: MIPS: Don't leak FPU/DSP to guest
[firefly-linux-kernel-4.4.55.git] / arch / mips / kvm / mips.c
index e3b21e51ff7e926ba00f4c4183c4ff146a26a775..e97b907840311d2bffa258443e2d72483605ac61 100644 (file)
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/bootmem.h>
+#include <asm/fpu.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
+#include <asm/pgtable.h>
 
 #include <linux/kvm_host.h>
 
@@ -378,6 +380,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                vcpu->mmio_needed = 0;
        }
 
+       lose_fpu(1);
+
        local_irq_disable();
        /* Check if we have any exceptions/interrupts pending */
        kvm_mips_deliver_interrupts(vcpu,
@@ -385,8 +389,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
        kvm_guest_enter();
 
+       /* Disable hardware page table walking while in guest */
+       htw_stop();
+
        r = __kvm_mips_vcpu_run(run, vcpu);
 
+       /* Re-enable HTW before enabling interrupts */
+       htw_start();
+
        kvm_guest_exit();
        local_irq_enable();
 
@@ -832,9 +842,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        return -ENOIOCTLCMD;
 }
 
-int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
+void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
-       return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
@@ -980,9 +989,6 @@ static void kvm_mips_set_c0_status(void)
 {
        uint32_t status = read_c0_status();
 
-       if (cpu_has_fpu)
-               status |= (ST0_CU1);
-
        if (cpu_has_dsp)
                status |= (ST0_MX);
 
@@ -1002,6 +1008,9 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
        enum emulation_result er = EMULATE_DONE;
        int ret = RESUME_GUEST;
 
+       /* re-enable HTW before enabling interrupts */
+       htw_start();
+
        /* Set a default exit reason */
        run->exit_reason = KVM_EXIT_UNKNOWN;
        run->ready_for_interrupt_injection = 1;
@@ -1136,6 +1145,9 @@ skip_emul:
                }
        }
 
+       /* Disable HTW before returning to guest or host */
+       htw_stop();
+
        return ret;
 }