diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c
index 997a7f4117c5..1c825ef957db 100644
--- a/arch/x86/kernel/cpu/sgx/driver.c
+++ b/arch/x86/kernel/cpu/sgx/driver.c
@@ -6,6 +6,7 @@
 #include <linux/mman.h>
 #include <linux/security.h>
 #include <linux/suspend.h>
+#include <linux/anon_inodes.h>
 #include <asm/traps.h>
 #include "driver.h"
 #include "encl.h"
@@ -21,35 +22,7 @@ u64 sgx_attributes_reserved_mask;
 u64 sgx_xfrm_reserved_mask = ~0x3;
 u32 sgx_xsave_size_tbl[64];
 
-static int sgx_open(struct inode *inode, struct file *file)
-{
-	struct sgx_encl *encl;
-	int ret;
-
-	encl = kzalloc(sizeof(*encl), GFP_KERNEL);
-	if (!encl)
-		return -ENOMEM;
-
-	atomic_set(&encl->flags, 0);
-	kref_init(&encl->refcount);
-	INIT_LIST_HEAD(&encl->va_pages);
-	INIT_RADIX_TREE(&encl->page_tree, GFP_KERNEL);
-	mutex_init(&encl->lock);
-	INIT_LIST_HEAD(&encl->mm_list);
-	spin_lock_init(&encl->mm_lock);
-
-	ret = init_srcu_struct(&encl->srcu);
-	if (ret) {
-		kfree(encl);
-		return ret;
-	}
-
-	file->private_data = encl;
-
-	return 0;
-}
-
-static int sgx_release(struct inode *inode, struct file *file)
+static int sgx_encl_file_release(struct inode *inode, struct file *file)
 {
 	struct sgx_encl *encl = file->private_data;
 	struct sgx_encl_mm *encl_mm;
@@ -84,6 +57,68 @@ static int sgx_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
+static const struct file_operations sgx_encl_file_fops = {
+	.owner			= THIS_MODULE,
+	.release		= sgx_encl_file_release,
+};
+
+static int sgx_open(struct inode *inode, struct file *file)
+{
+	struct file *encl_file = NULL;
+	struct sgx_encl *encl = NULL;
+	int ret;
+
+	encl = kzalloc(sizeof(*encl), GFP_KERNEL);
+	if (!encl) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	encl_file = anon_inode_getfile("[sgx]", &sgx_encl_file_fops, encl,
+				       O_RDWR);
+	if (IS_ERR(encl_file)) {
+		ret = PTR_ERR(encl_file);
+		goto err;
+	}
+
+	ret = init_srcu_struct(&encl->srcu);
+	if (ret)
+		goto err;
+
+	atomic_set(&encl->flags, 0);
+	kref_init(&encl->refcount);
+	INIT_LIST_HEAD(&encl->va_pages);
+	INIT_RADIX_TREE(&encl->page_tree, GFP_KERNEL);
+	mutex_init(&encl->lock);
+	INIT_LIST_HEAD(&encl->mm_list);
+	spin_lock_init(&encl->mm_lock);
+
+	file->private_data = encl_file;
+
+	return 0;
+
+err:
+	if (encl_file)
+		fput(encl_file);
+
+	kfree(encl);
+	return ret;
+}
+
+static int sgx_encl_dev_release(struct inode *inode, struct file *file)
+{
+	struct file *encl_file = file->private_data;
+
+	/*
+	 * Can be NULL when the enclave file has been handed over to the
+	 * user space.
+	 */
+	if (encl_file)
+		fput(encl_file);
+
+	return 0;
+}
+
 #ifdef CONFIG_COMPAT
 static long sgx_compat_ioctl(struct file *filep, unsigned int cmd,
 			      unsigned long arg)
@@ -94,7 +129,8 @@ static long sgx_compat_ioctl(struct file *filep, unsigned int cmd,
 
 static int sgx_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct sgx_encl *encl = file->private_data;
+	struct file *encl_file = file->private_data;
+	struct sgx_encl *encl = encl_file->private_data;
 	int ret;
 
 	ret = sgx_encl_may_map(encl, vma->vm_start, vma->vm_end,
@@ -128,10 +164,10 @@ static unsigned long sgx_get_unmapped_area(struct file *file,
 	return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
 }
 
-static const struct file_operations sgx_encl_fops = {
+static const struct file_operations sgx_encl_dev_fops = {
 	.owner			= THIS_MODULE,
 	.open			= sgx_open,
-	.release		= sgx_release,
+	.release		= sgx_encl_dev_release,
 	.unlocked_ioctl		= sgx_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl		= sgx_compat_ioctl,
@@ -148,7 +184,7 @@ static struct miscdevice sgx_dev_enclave = {
 	.minor = MISC_DYNAMIC_MINOR,
 	.name = "enclave",
 	.nodename = "sgx/enclave",
-	.fops = &sgx_encl_fops,
+	.fops = &sgx_encl_dev_fops,
 };
 
 static struct miscdevice sgx_dev_provision = {
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
index 3af0596530a8..891aa9395907 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -766,7 +766,8 @@ static long sgx_ioc_enclave_set_attribute(struct sgx_encl *encl,
 
 long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
-	struct sgx_encl *encl = filep->private_data;
+	struct file *encl_file = filep->private_data;
+	struct sgx_encl *encl = encl_file->private_data;
 	int ret, encl_flags;
 
 	encl_flags = atomic_fetch_or(SGX_ENCL_IOCTL, &encl->flags);
