Merge tag 'v4.3-rc2' into k.o/for-4.3-v1
[firefly-linux-kernel-4.4.55.git] / drivers / misc / cxl / context.c
index 1287148629c0d6f0b6e6066d4c883d8dfaebf9da..e762f85ee233a4b510390aa0ce4a5a79266b84c3 100644 (file)
@@ -126,6 +126,18 @@ static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        if (ctx->status != STARTED) {
                mutex_unlock(&ctx->status_mutex);
                pr_devel("%s: Context not started, failing problem state access\n", __func__);
+               if (ctx->mmio_err_ff) {
+                       if (!ctx->ff_page) {
+                               ctx->ff_page = alloc_page(GFP_USER);
+                               if (!ctx->ff_page)
+                                       return VM_FAULT_OOM;
+                               memset(page_address(ctx->ff_page), 0xff, PAGE_SIZE);
+                       }
+                       get_page(ctx->ff_page);
+                       vmf->page = ctx->ff_page;
+                       vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
+                       return 0;
+               }
                return VM_FAULT_SIGBUS;
        }
 
@@ -193,7 +205,11 @@ int __detach_context(struct cxl_context *ctx)
        if (status != STARTED)
                return -EBUSY;
 
-       WARN_ON(cxl_detach_process(ctx));
+       /* Only warn if we detached while the link was OK.
+        * If detach fails when hw is down, we don't care.
+        */
+       WARN_ON(cxl_detach_process(ctx) &&
+               cxl_adapter_link_ok(ctx->afu->adapter));
        flush_work(&ctx->fault_work); /* Only needed for dedicated process */
        put_pid(ctx->pid);
        cxl_ctx_put();
@@ -253,7 +269,11 @@ static void reclaim_ctx(struct rcu_head *rcu)
        struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu);
 
        free_page((u64)ctx->sstp);
+       if (ctx->ff_page)
+               __free_page(ctx->ff_page);
        ctx->sstp = NULL;
+       if (ctx->kernelapi)
+               kfree(ctx->mapping);
 
        kfree(ctx);
 }