Merge tag 'xfs-5.18-merge-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-2.6-microblaze.git] / arch / powerpc / kvm / powerpc.c
index 2ad0ccd..9772b17 100644 (file)
@@ -307,9 +307,31 @@ int kvmppc_emulate_mmio(struct kvm_vcpu *vcpu)
                u32 last_inst;
 
                kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst);
-               /* XXX Deliver Program interrupt to guest. */
-               pr_emerg("%s: emulation failed (%08x)\n", __func__, last_inst);
-               r = RESUME_HOST;
+               kvm_debug_ratelimited("Guest access to device memory using unsupported instruction (opcode: %#08x)\n",
+                                     last_inst);
+
+               /*
+                * Injecting a Data Storage here is a bit more
+                * accurate since the instruction that caused the
+                * access could still be a valid one.
+                */
+               if (!IS_ENABLED(CONFIG_BOOKE)) {
+                       ulong dsisr = DSISR_BADACCESS;
+
+                       if (vcpu->mmio_is_write)
+                               dsisr |= DSISR_ISSTORE;
+
+                       kvmppc_core_queue_data_storage(vcpu, vcpu->arch.vaddr_accessed, dsisr);
+               } else {
+                       /*
+                        * BookE does not send a SIGBUS on a bad
+                        * fault, so use a Program interrupt instead
+                        * to avoid a fault loop.
+                        */
+                       kvmppc_core_queue_program(vcpu, 0);
+               }
+
+               r = RESUME_GUEST;
                break;
        }
        default:
@@ -431,6 +453,8 @@ int kvm_arch_check_processor_compat(void *opaque)
 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 {
        struct kvmppc_ops *kvm_ops = NULL;
+       int r;
+
        /*
         * if we have both HV and PR enabled, default is HV
         */
@@ -452,11 +476,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        } else
                goto err_out;
 
-       if (kvm_ops->owner && !try_module_get(kvm_ops->owner))
+       if (!try_module_get(kvm_ops->owner))
                return -ENOENT;
 
        kvm->arch.kvm_ops = kvm_ops;
-       return kvmppc_core_init_vm(kvm);
+       r = kvmppc_core_init_vm(kvm);
+       if (r)
+               module_put(kvm_ops->owner);
+       return r;
 err_out:
        return -EINVAL;
 }
@@ -755,7 +782,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 
        rcuwait_init(&vcpu->arch.wait);
        vcpu->arch.waitp = &vcpu->arch.wait;
-       kvmppc_create_vcpu_debugfs(vcpu, vcpu->vcpu_id);
        return 0;
 
 out_vcpu_uninit:
@@ -772,8 +798,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
        /* Make sure we're not using the vcpu anymore */
        hrtimer_cancel(&vcpu->arch.dec_timer);
 
-       kvmppc_remove_vcpu_debugfs(vcpu);
-
        switch (vcpu->arch.irq_type) {
        case KVMPPC_IRQ_MPIC:
                kvmppc_mpic_disconnect_vcpu(vcpu->arch.mpic, vcpu);
@@ -1114,10 +1138,8 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu)
        struct kvm_run *run = vcpu->run;
        u64 gpr;
 
-       if (run->mmio.len > sizeof(gpr)) {
-               printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
+       if (run->mmio.len > sizeof(gpr))
                return;
-       }
 
        if (!vcpu->arch.mmio_host_swabbed) {
                switch (run->mmio.len) {
@@ -1236,10 +1258,8 @@ static int __kvmppc_handle_load(struct kvm_vcpu *vcpu,
                host_swabbed = !is_default_endian;
        }
 
-       if (bytes > sizeof(run->mmio.data)) {
-               printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
-                      run->mmio.len);
-       }
+       if (bytes > sizeof(run->mmio.data))
+               return EMULATE_FAIL;
 
        run->mmio.phys_addr = vcpu->arch.paddr_accessed;
        run->mmio.len = bytes;
@@ -1325,10 +1345,8 @@ int kvmppc_handle_store(struct kvm_vcpu *vcpu,
                host_swabbed = !is_default_endian;
        }
 
-       if (bytes > sizeof(run->mmio.data)) {
-               printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
-                      run->mmio.len);
-       }
+       if (bytes > sizeof(run->mmio.data))
+               return EMULATE_FAIL;
 
        run->mmio.phys_addr = vcpu->arch.paddr_accessed;
        run->mmio.len = bytes;
@@ -1499,7 +1517,7 @@ int kvmppc_handle_vmx_load(struct kvm_vcpu *vcpu,
 {
        enum emulation_result emulated = EMULATE_DONE;
 
-       if (vcpu->arch.mmio_vsx_copy_nums > 2)
+       if (vcpu->arch.mmio_vmx_copy_nums > 2)
                return EMULATE_FAIL;
 
        while (vcpu->arch.mmio_vmx_copy_nums) {
@@ -1596,7 +1614,7 @@ int kvmppc_handle_vmx_store(struct kvm_vcpu *vcpu,
        unsigned int index = rs & KVM_MMIO_REG_MASK;
        enum emulation_result emulated = EMULATE_DONE;
 
-       if (vcpu->arch.mmio_vsx_copy_nums > 2)
+       if (vcpu->arch.mmio_vmx_copy_nums > 2)
                return EMULATE_FAIL;
 
        vcpu->arch.io_gpr = rs;
@@ -1841,6 +1859,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 #ifdef CONFIG_ALTIVEC
 out:
 #endif
+
+       /*
+        * We're already returning to userspace, don't pass the
+        * RESUME_HOST flags along.
+        */
+       if (r > 0)
+               r = 0;
+
        vcpu_put(vcpu);
        return r;
 }
@@ -2497,3 +2523,16 @@ int kvm_arch_init(void *opaque)
 }
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr);
+
+void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry)
+{
+       if (vcpu->kvm->arch.kvm_ops->create_vcpu_debugfs)
+               vcpu->kvm->arch.kvm_ops->create_vcpu_debugfs(vcpu, debugfs_dentry);
+}
+
+int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+{
+       if (kvm->arch.kvm_ops->create_vm_debugfs)
+               kvm->arch.kvm_ops->create_vm_debugfs(kvm);
+       return 0;
+}