kernel-release 4.16.7-1 (x86_64) 2018-4361
-9999

Status rejected
Submitter tpgxyz [@T] gmail.com
Platform 3.0
Repository main
URL https://abf.openmandriva.org/build_lists/168863
Packages
bootsplash-packer-4.16.7-1.x86_64.binary
bootsplash-packer-4.16.7-1.x86_64.binary
cpupower-4.16.7-1.x86_64.binary
cpupower-4.16.7-1.x86_64.binary
cpupower-devel-4.16.7-1.x86_64.binary
cpupower-devel-4.16.7-1.x86_64.binary
kernel-release-4.16.7-1.x86_64.source
kernel-release-4.16.7-1.x86_64.source
kernel-release-desktop-4.16.7-1omv-1-1.x86_64.binary
kernel-release-desktop-4.16.7-1omv-1-1.x86_64.binary
kernel-release-desktop-devel-4.16.7-1omv-1-1.x86_64.binary
kernel-release-desktop-devel-4.16.7-1omv-1-1.x86_64.binary
kernel-release-desktop-devel-latest-4.16.7-1.x86_64.binary
kernel-release-desktop-devel-latest-4.16.7-1.x86_64.binary
kernel-release-desktop-latest-4.16.7-1.x86_64.binary
kernel-release-desktop-latest-4.16.7-1.x86_64.binary
kernel-release-headers-1:4.16.7-1.x86_64.binary
kernel-release-headers-1:4.16.7-1.x86_64.binary
kernel-release-server-4.16.7-1omv-1-1.x86_64.binary
kernel-release-server-4.16.7-1omv-1-1.x86_64.binary
kernel-release-server-devel-4.16.7-1omv-1-1.x86_64.binary
kernel-release-server-devel-4.16.7-1omv-1-1.x86_64.binary
kernel-release-server-devel-latest-4.16.7-1.x86_64.binary
kernel-release-server-devel-latest-4.16.7-1.x86_64.binary
kernel-release-server-latest-4.16.7-1.x86_64.binary
kernel-release-server-latest-4.16.7-1.x86_64.binary
kernel-release-source-4.16.7-1omv-1-1.x86_64.binary
kernel-release-source-4.16.7-1omv-1-1.x86_64.binary
kernel-release-source-latest-4.16.7-1.x86_64.binary
kernel-release-source-latest-4.16.7-1.x86_64.binary
turbostat-4.16.7-1.x86_64.binary
turbostat-4.16.7-1.x86_64.binary
x86_energy_perf_policy-4.16.7-1.x86_64.binary
x86_energy_perf_policy-4.16.7-1.x86_64.binary
Build Date 2018-05-07 16:09:33 +0000 UTC
Last Updated 2018-05-12 08:08:37.303403312 +0000 UTC
$ git diff --patch-with-stat --summary 266fb3416fae537f42128ba94263b18ca8b155d0..8d10a5c0672aa74da1d40880ca4f11bb285bf73b

 .abf.yml                                           |    8 +-
 ...sible-to-disable-SWIOTLB-code-on-admgpu-a.patch |  206 ++
 0109-init_task-faster-timerslack.patch             |   26 +-
 ...6-Return-memory-from-guest-to-host-kernel.patch |   92 +-
 arm-common.config                                  |   31 +
 arm64-common.config                                |   37 +
 common.config                                      |   88 +-
 hauppauge-hvr-1975.patch                           |  193 +-
 i386-common.config                                 |   21 +-
 kernel-release.spec                                |  278 +-
 nouveau-pascal-backlight.patch                     |   11 +
 saa716x-driver-integration.patch                   |   55 +-
 uksm-4.15.patch => uksm-4.16.patch                 |   66 +-
 ...ib-Add-support-for-ZSTD-compressed-kernel.patch |  721 ++++
 ...86-Add-support-for-ZSTD-compressed-kernel.patch |  106 +
 ...ualBox-guest-shared-folder-vboxsf-support.patch | 3430 ++++++++++++++++++++
 x86_64-common.config                               |   23 +-
 17 files changed, 5012 insertions(+), 380 deletions(-)
 create mode 100644 0001-Make-it-possible-to-disable-SWIOTLB-code-on-admgpu-a.patch
 create mode 100644 nouveau-pascal-backlight.patch
 rename uksm-4.15.patch => uksm-4.16.patch (99%)
 create mode 100644 v2-1-2-lib-Add-support-for-ZSTD-compressed-kernel.patch
 create mode 100644 v2-2-2-x86-Add-support-for-ZSTD-compressed-kernel.patch
 create mode 100644 v7-fs-Add-VirtualBox-guest-shared-folder-vboxsf-support.patch

diff --git a/.abf.yml b/.abf.yml
index 03d737b..b92f35f 100644
--- a/.abf.yml
+++ b/.abf.yml
@@ -1,5 +1,5 @@
 sources:
-  linux-4.15.tar.sign: 4ec662ae15c98e2342cdafedfa8ed4512fd69c5a
-  linux-4.15.tar.xz: 5cf2693d2c6bf1e69a9216dceca6183c60eb11d5
-  saa716x-driver.tar.xz: 603d6e561f6c09b19b05ca53b55458caad849c97
-  patch-4.15.18.xz: 69765b2685a775547d29fe1de7175ec4ec98b006
+  linux-4.16.tar.xz: 76b3c8a7bf9a61d6e6bf0761ac3491e6281001f7
+  linux-4.16.tar.sign: 4341f793d6fbd2ab136dcb9edd3c46c76236488b
+  saa716x-driver.tar.xz: f9b6ef1cd6f1f71f53d9a8aadfba2cf6b5c3d7b6
+  patch-4.16.7.xz: c40f537e308ae5b94d9d4610cd4ad4ca800f3ef2
diff --git a/0001-Make-it-possible-to-disable-SWIOTLB-code-on-admgpu-a.patch b/0001-Make-it-possible-to-disable-SWIOTLB-code-on-admgpu-a.patch
new file mode 100644
index 0000000..1d988b3
--- /dev/null
+++ b/0001-Make-it-possible-to-disable-SWIOTLB-code-on-admgpu-a.patch
@@ -0,0 +1,206 @@
+From 6aa339bd361e862edb7724a4c61969ed72f3035f Mon Sep 17 00:00:00 2001
+From: Gabriel Craciunescu <nix.or.die@gmail.com>
+Date: Thu, 12 Apr 2018 03:20:06 +0200
+Subject: [PATCH] Make it possible to disable SWIOTLB code on admgpu and radeon
+
+ added admgpu.swiotlb and radeon.swiotlb option, defaults to disabled
+ since new the code doesn't seems to work good or work at all on some HW.
+
+ https://lkml.org/lkml/2018/4/5/737
+ https://bugzilla.kernel.org/show_bug.cgi?id=198511
+ https://bugs.freedesktop.org/show_bug.cgi?id=105038
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 ++++++++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 20 +++++++++++++-------
+ drivers/gpu/drm/radeon/radeon.h         |  1 +
+ drivers/gpu/drm/radeon/radeon_drv.c     |  9 +++++++++
+ drivers/gpu/drm/radeon/radeon_ttm.c     | 20 +++++++++++++-------
+ 6 files changed, 47 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 74edba18b159..8371b06e5ecf 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -127,6 +127,7 @@ extern int amdgpu_job_hang_limit;
+ extern int amdgpu_lbpw;
+ extern int amdgpu_compute_multipipe;
+ extern int amdgpu_gpu_recovery;
++extern int amdgpu_swiotlb;
+ 
+ #ifdef CONFIG_DRM_AMDGPU_SI
+ extern int amdgpu_si_support;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 50afcf65181a..d67c411fbaad 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -129,6 +129,8 @@ int amdgpu_job_hang_limit = 0;
+ int amdgpu_lbpw = -1;
+ int amdgpu_compute_multipipe = -1;
+ int amdgpu_gpu_recovery = -1; /* auto */
++int amdgpu_swiotlb = 0;
++
+ 
+ MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
+ module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
+@@ -284,6 +286,9 @@ module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444);
+ MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto");
+ module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444);
+ 
++MODULE_PARM_DESC(swiotlb, "Enable new SWIOTLB code , (1 = enable , 0 = disable ( default )");
++module_param_named(swiotlb, amdgpu_swiotlb, int, 0444);
++
+ #ifdef CONFIG_DRM_AMDGPU_SI
+ 
+ #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
+@@ -918,6 +923,11 @@ static int __init amdgpu_init(void)
+ 		return -EINVAL;
+ 	}
+ 	DRM_INFO("amdgpu kernel modesetting enabled.\n");
++
++	if(amdgpu_swiotlb) {
++		DRM_INFO("amdgpu new SWIOTLB code enabled.\n");
++	}
++
+ 	driver = &kms_driver;
+ 	pdriver = &amdgpu_kms_pci_driver;
+ 	driver->num_ioctls = amdgpu_max_kms_ioctl;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index e4bb435e614b..58cd95c35a54 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -1018,8 +1018,10 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
+ 	}
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (swiotlb_nr_tbl()) {
+-		return ttm_dma_populate(&gtt->ttm, adev->dev, ctx);
++	if (amdgpu_swiotlb) {
++		if (swiotlb_nr_tbl()) {
++			return ttm_dma_populate(&gtt->ttm, adev->dev, ctx);
++		}
+ 	}
+ #endif
+ 
+@@ -1045,9 +1047,11 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
+ 	adev = amdgpu_ttm_adev(ttm->bdev);
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (swiotlb_nr_tbl()) {
+-		ttm_dma_unpopulate(&gtt->ttm, adev->dev);
+-		return;
++	if (amdgpu_swiotlb) {
++		if (swiotlb_nr_tbl()) {
++			ttm_dma_unpopulate(&gtt->ttm, adev->dev);
++			return;
++		}
+ 	}
+ #endif
+ 
+@@ -2010,8 +2014,10 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev)
+ 	count = ARRAY_SIZE(amdgpu_ttm_debugfs_list);
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (!swiotlb_nr_tbl())
+-		--count;
++	if (amdgpu_swiotlb) {
++		if (!swiotlb_nr_tbl())
++			--count;
++	}
+ #endif
+ 
+ 	return amdgpu_debugfs_add_files(adev, amdgpu_ttm_debugfs_list, count);
+diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
+index d34887873dea..d614de12e30c 100644
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -117,6 +117,7 @@ extern int radeon_uvd;
+ extern int radeon_vce;
+ extern int radeon_si_support;
+ extern int radeon_cik_support;
++extern int radeon_swiotlb;
+ 
+ /*
+  * Copy from radeon_drv.h so we don't have to include both and have conflicting
+diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
+index 31dd04f6baa1..20b1110e4698 100644
+--- a/drivers/gpu/drm/radeon/radeon_drv.c
++++ b/drivers/gpu/drm/radeon/radeon_drv.c
+@@ -196,6 +196,7 @@ int radeon_auxch = -1;
+ int radeon_mst = 0;
+ int radeon_uvd = 1;
+ int radeon_vce = 1;
++int radeon_swiotlb = 0;
+ 
+ MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
+ module_param_named(no_wb, radeon_no_wb, int, 0444);
+@@ -301,6 +302,9 @@ int radeon_cik_support = 1;
+ MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
+ module_param_named(cik_support, radeon_cik_support, int, 0444);
+ 
++MODULE_PARM_DESC(swiotlb, "Enable new SWIOTLB code , (1 = enable, 0 = disable ( default )");
++module_param_named(swiotlb, radeon_swiotlb, int, 0444);
++
+ static struct pci_device_id pciidlist[] = {
+ 	radeon_PCI_IDS
+ };
+@@ -620,6 +624,11 @@ static int __init radeon_init(void)
+ 
+ 	if (radeon_modeset == 1) {
+ 		DRM_INFO("radeon kernel modesetting enabled.\n");
++
++		if(radeon_swiotlb) {
++			DRM_INFO("radeon new SWIOTLB code enabled.\n");
++		}
++
+ 		driver = &kms_driver;
+ 		pdriver = &radeon_kms_pci_driver;
+ 		driver->driver_features |= DRIVER_MODESET;
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index a0a839bc39bf..952b1216c729 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -756,8 +756,10 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm,
+ #endif
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (swiotlb_nr_tbl()) {
+-		return ttm_dma_populate(&gtt->ttm, rdev->dev, ctx);
++	if (radeon_swiotlb) {
++		if (swiotlb_nr_tbl()) {
++			return ttm_dma_populate(&gtt->ttm, rdev->dev, ctx);
++		}
+ 	}
+ #endif
+ 
+@@ -788,9 +790,11 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
+ #endif
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (swiotlb_nr_tbl()) {
+-		ttm_dma_unpopulate(&gtt->ttm, rdev->dev);
+-		return;
++	if (radeon_swiotlb) {
++		if (swiotlb_nr_tbl()) {
++			ttm_dma_unpopulate(&gtt->ttm, rdev->dev);
++			return;
++		}
+ 	}
+ #endif
+ 
+@@ -1155,8 +1159,10 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
+ 	count = ARRAY_SIZE(radeon_ttm_debugfs_list);
+ 
+ #ifdef CONFIG_SWIOTLB
+-	if (!swiotlb_nr_tbl())
+-		--count;
++	if (radeon_swiotlb) {
++		if (!swiotlb_nr_tbl())
++			--count;
++	}
+ #endif
+ 
+ 	return radeon_debugfs_add_files(rdev, radeon_ttm_debugfs_list, count);
+-- 
+2.17.0
+
diff --git a/0109-init_task-faster-timerslack.patch b/0109-init_task-faster-timerslack.patch
index 9c908e7..fc6e62e 100644
--- a/0109-init_task-faster-timerslack.patch
+++ b/0109-init_task-faster-timerslack.patch
@@ -16,18 +16,14 @@ for where the patch goes work out better here
  include/linux/init_task.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-diff --git a/include/linux/init_task.h b/include/linux/init_task.h
-index 8062e6cc607c..2903519e2462 100644
---- a/include/linux/init_task.h
-+++ b/include/linux/init_task.h
-@@ -275,7 +275,7 @@ extern struct cred init_cred;
- 	.journal_info	= NULL,						\
- 	INIT_CPU_TIMERS(tsk)						\
- 	.pi_lock	= __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),	\
--	.timer_slack_ns = 50000, /* 50 usec default slack */		\
-+	.timer_slack_ns = 1000, /* 1 usec default slack */		\
- 	.pids = {							\
- 		[PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),		\
- 		[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),		\
--- 
-2.15.0
+--- linux-4.15/init/init_task.c.0405~	2018-02-12 12:32:24.237374059 +0100
++++ linux-4.15/init/init_task.c	2018-02-12 12:32:42.764417715 +0100
+@@ -109,7 +109,7 @@ struct task_struct init_task
+ 	.journal_info	= NULL,
+ 	INIT_CPU_TIMERS(init_task)
+ 	.pi_lock	= __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock),
+-	.timer_slack_ns = 50000, /* 50 usec default slack */
++	.timer_slack_ns = 1000, /* 1 usec default slack */
+ 	.pids = {
+ 		[PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),
+ 		[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),
diff --git a/0153-x86-Return-memory-from-guest-to-host-kernel.patch b/0153-x86-Return-memory-from-guest-to-host-kernel.patch
index 16333f0..9409ded 100644
--- a/0153-x86-Return-memory-from-guest-to-host-kernel.patch
+++ b/0153-x86-Return-memory-from-guest-to-host-kernel.patch
@@ -1,62 +1,6 @@
-From 9d487e5b95627e54c5ba256363ab6d1c5eaa592d Mon Sep 17 00:00:00 2001
-From: Sebastien Boeuf <sebastien.boeuf@intel.com>
-Date: Mon, 23 Jan 2017 15:26:13 -0800
-Subject: [PATCH 153/154] x86: Return memory from guest to host kernel
-
-All virtual machines need memory to perform various tasks, but this
-memory is not released to the host after it is not used anymore. We
-have to wait for the termination of the virtual machine to get this
-memory back into the host.
-
-Ballooning mechanism is close but not designed for the same purpose.
-In case we hit memory limits of the system, the host predicts how much
-memory can be asked back from a guest, and it issues an hypercall to
-retrieve this memory.
-
-The solution proposed is different because it does not wait for host
-needs before to return memory, and it knows precisely how much memory
-it can return.
-
-The way to notify the host side about such a return is to rely on
-the new hypercall KVM_HC_RETURN_MEM. In order to avoid the CPU to be
-overloaded with too many hypercalls, we only return memory blocks of
-order 7 (512k blocks) and higher. This value has been found running
-memory tests using multiple threads allocating/freeing high amount
-of memory. Those tests were run for different order values, and 7 was
-the best tradeoff between the number of hypercalls issued and the
-amount of memory returned to the host.
-
-In order to limit performances impact related to this code addition,
-we check for blocks of order 7 or higher. This means it only costs an
-additional function call and a branch to perform this check.
-
-Furthermore, this code has been added to the "merge" codepath of the
-buddy allocator, which is not as sensitive as the "free" codepath.
-Not all blocks going through the "free" codepath will end up in the
-"merge" codepath because some of them won't find their free buddy.
-But this is a negligible amount since the kernel does not use many
-high order blocks directly. Instead, those bigger blocks are often
-broken into smaller chunks used as low order blocks. At the time
-those small blocks are released, they go through the merge path.
-
-Benchmarks such as ebizzy and will-it-scale have been run in order
-to make sure this patch does not affect kernel performances and no
-significant differences were observed.
-
-Suggested-by: Arjan van de Ven <arjan.van.de.ven@intel.com>
-Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
----
- arch/x86/include/asm/kvm_para.h | 22 ++++++++++++++++++++++
- arch/x86/kernel/kvm.c           | 10 ++++++++++
- include/linux/mm-arch-hooks.h   |  8 ++++++++
- mm/page_alloc.c                 |  2 ++
- 4 files changed, 42 insertions(+)
-
-diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
-index c373e44049b1..847f17ff111c 100644
---- a/arch/x86/include/asm/kvm_para.h
-+++ b/arch/x86/include/asm/kvm_para.h
-@@ -93,6 +93,28 @@ void kvm_async_pf_task_wait(u32 token, int interrupt_kernel);
+--- linux-4.15/arch/x86/include/asm/kvm_para.h.0421~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/arch/x86/include/asm/kvm_para.h	2018-02-12 12:34:24.909687261 +0100
+@@ -92,6 +92,28 @@ void kvm_async_pf_task_wait(u32 token, i
  void kvm_async_pf_task_wake(u32 token);
  u32 kvm_read_and_reset_pf_reason(void);
  extern void kvm_disable_steal_time(void);
@@ -85,13 +29,11 @@ index c373e44049b1..847f17ff111c 100644
  
  #ifdef CONFIG_PARAVIRT_SPINLOCKS
  void __init kvm_spinlock_init(void);
-diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
-index 8bb9594d0761..696319728469 100644
---- a/arch/x86/kernel/kvm.c
-+++ b/arch/x86/kernel/kvm.c
-@@ -563,6 +563,16 @@ static __init int activate_jump_labels(void)
+--- linux-4.15/arch/x86/kernel/kvm.c.0421~	2018-02-12 12:34:24.909687261 +0100
++++ linux-4.15/arch/x86/kernel/kvm.c	2018-02-12 13:19:43.422948592 +0100
+@@ -645,6 +645,16 @@ static __init int kvm_setup_pv_tlb_flush
  }
- arch_initcall(activate_jump_labels);
+ arch_initcall(kvm_setup_pv_tlb_flush);
  
 +void kvm_arch_return_memory(struct page *page, unsigned int order)
 +{
@@ -106,10 +48,8 @@ index 8bb9594d0761..696319728469 100644
  #ifdef CONFIG_PARAVIRT_SPINLOCKS
  
  /* Kick a cpu by its apicid. Used to wake up a halted vcpu */
-diff --git a/include/linux/mm-arch-hooks.h b/include/linux/mm-arch-hooks.h
-index 4efc3f56e6df..26eb3a05a8a3 100644
---- a/include/linux/mm-arch-hooks.h
-+++ b/include/linux/mm-arch-hooks.h
+--- linux-4.15/include/linux/mm-arch-hooks.h.0421~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/include/linux/mm-arch-hooks.h	2018-02-12 12:34:24.909687261 +0100
 @@ -12,6 +12,7 @@
  #define _LINUX_MM_ARCH_HOOKS_H
  
@@ -118,7 +58,7 @@ index 4efc3f56e6df..26eb3a05a8a3 100644
  
  #ifndef arch_remap
  static inline void arch_remap(struct mm_struct *mm,
-@@ -22,4 +23,11 @@ static inline void arch_remap(struct mm_struct *mm,
+@@ -22,4 +23,11 @@ static inline void arch_remap(struct mm_
  #define arch_remap arch_remap
  #endif
  
@@ -130,11 +70,9 @@ index 4efc3f56e6df..26eb3a05a8a3 100644
 +#endif
 +
  #endif /* _LINUX_MM_ARCH_HOOKS_H */
-diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index 77e4d3c5c57b..b14190aeedff 100644
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -65,6 +65,7 @@
+--- linux-4.15/mm/page_alloc.c.0421~	2018-02-12 12:34:24.721686723 +0100
++++ linux-4.15/mm/page_alloc.c	2018-02-12 12:34:24.910687264 +0100
+@@ -64,6 +64,7 @@
  #include <linux/page_owner.h>
  #include <linux/kthread.h>
  #include <linux/memcontrol.h>
@@ -142,7 +80,7 @@ index 77e4d3c5c57b..b14190aeedff 100644
  #include <linux/ftrace.h>
  #include <linux/lockdep.h>
  #include <linux/nmi.h>
-@@ -869,6 +870,7 @@ static inline void __free_one_page(struct page *page,
+@@ -879,6 +880,7 @@ continue_merging:
  	}
  
  done_merging:
@@ -150,5 +88,3 @@ index 77e4d3c5c57b..b14190aeedff 100644
  	set_page_order(page, order);
  
  	/*
--- 
-2.15.0
diff --git a/arm-common.config b/arm-common.config
index 1716f3b..a9beda9 100644
--- a/arm-common.config
+++ b/arm-common.config
@@ -2680,3 +2680,34 @@ CONFIG_UNIPHIER_EFUSE=m
 CONFIG_MESON_MX_EFUSE=m
 CONFIG_NVMEM_SNVS_LPGPR=m
 # CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
+CONFIG_CACHE_B15_RAC=y
+CONFIG_PCIE_CADENCE_HOST=y
+CONFIG_PCIE_CADENCE_EP=y
+CONFIG_PCIE_ARTPEC6_HOST=y
+CONFIG_PCIE_ARTPEC6_EP=y
+CONFIG_ARM_ARMADA_37XX_CPUFREQ=m
+CONFIG_MTD_NAND_MARVELL=m
+CONFIG_GEMINI_ETHERNET=m
+CONFIG_HNS3_HCLGEVF=m
+CONFIG_SNI_AVE=m
+CONFIG_SFP=m
+CONFIG_PINCTRL_AXP209=m
+CONFIG_PINCTRL_MSM8998=m
+CONFIG_FTWDT010_WATCHDOG=m
+CONFIG_DRM_PANEL_ILITEK_IL9322=m
+CONFIG_SND_SOC_UNIPHIER=m
+CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC=m
+CONFIG_MMC_SDHI_SYS_DMAC=m
+CONFIG_LEDS_LM3692X=m
+CONFIG_EDAC_TI=m
+CONFIG_RTC_DRV_MXC_V2=m
+CONFIG_TEGRA_VDE=m
+CONFIG_MELLANOX_PLATFORM=y
+CONFIG_STUB_CLK_HI3660=y
+CONFIG_QCOM_A53PLL=m
+CONFIG_QCOM_CLK_APCS_MSM8916=m
+CONFIG_SPMI_PMIC_CLKDIV=m
+CONFIG_TI_EMIF_SRAM=m
+CONFIG_SD_ADC_MODULATOR=m
+CONFIG_ARM_PTDUMP_DEBUGFS=y
+CONFIG_MLXREG_HOTPLUG=m
diff --git a/arm64-common.config b/arm64-common.config
index b233cd2..e6ef10a 100644
--- a/arm64-common.config
+++ b/arm64-common.config
@@ -1557,3 +1557,40 @@ CONFIG_MESON_MX_EFUSE=m
 CONFIG_TPS68470_PMIC_OPREGION=y
 CONFIG_UNMAP_KERNEL_AT_EL0=y
 CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_PCIE_CADENCE_HOST=y
+CONFIG_PCIE_CADENCE_EP=y
+CONFIG_ARM64_RAS_EXTN=y
+CONFIG_ARM_ARMADA_37XX_CPUFREQ=m
+CONFIG_MTD_NAND_MARVELL=m
+CONFIG_CAVIUM_PTP=m
+CONFIG_GEMINI_ETHERNET=m
+CONFIG_HNS3_HCLGEVF=m
+CONFIG_SNI_AVE=m
+CONFIG_SNI_NETSEC=m
+CONFIG_SFP=m
+CONFIG_PINCTRL_AXP209=m
+CONFIG_PINCTRL_MSM8998=m
+CONFIG_PINCTRL_MT7622=y
+CONFIG_PINCTRL_MESON_AXG=y
+CONFIG_RTD119X_WATCHDOG=y
+CONFIG_SPRD_WATCHDOG=m
+CONFIG_REGULATOR_SC2731=m
+CONFIG_DRM_PANEL_ILITEK_IL9322=m
+CONFIG_SND_SOC_UNIPHIER=m
+CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC=m
+CONFIG_MMC_SDHI_INTERNAL_DMAC=m
+CONFIG_LEDS_LM3692X=m
+CONFIG_TEGRA_VDE=m
+CONFIG_STUB_CLK_HI3660=m
+CONFIG_QCOM_A53PLL=m
+CONFIG_QCOM_CLK_APCS_MSM8916=m
+CONFIG_SPMI_PMIC_CLKDIV=m
+CONFIG_SPRD_COMMON_CLK=m
+CONFIG_SPRD_SC9860_CLK=m
+CONFIG_SD_ADC_MODULATOR=m
+CONFIG_ARM_DSU_PMU=m
+CONFIG_ARM_SDE_INTERFACE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_STUB_CLK_HI3660=y
diff --git a/common.config b/common.config
index 9b2bb04..60256b9 100644
--- a/common.config
+++ b/common.config
@@ -12,10 +12,12 @@ CONFIG_HAVE_KERNEL_LZMA=y
 CONFIG_HAVE_KERNEL_XZ=y
 CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_HAVE_KERNEL_ZSTD=y
 # CONFIG_KERNEL_GZIP is not set
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
-CONFIG_KERNEL_XZ=y
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_ZSTD is not set
 # CONFIG_KERNEL_LZO is not set
 # CONFIG_KERNEL_LZ4 is not set
 CONFIG_XXHASH=y
@@ -142,6 +144,7 @@ CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
 CONFIG_RD_XZ=y
+# CONFIG_RD_ZSTD is not set
 CONFIG_RD_LZO=y
 CONFIG_RD_LZ4=y
 CONFIG_INITRAMFS_COMPRESSION=".gz"
@@ -180,6 +183,9 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_ADVISE_SYSCALLS=y
 # CONFIG_USERFAULTFD is not set
+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
+CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_MEMBARRIER=y
 CONFIG_EMBEDDED=y
@@ -256,9 +262,10 @@ CONFIG_GCC_PLUGIN_RANDSTRUCT=y
 CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE=y
 CONFIG_HAVE_CC_STACKPROTECTOR=y
 CONFIG_CC_STACKPROTECTOR=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
 # CONFIG_CC_STACKPROTECTOR_NONE is not set
-# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
-CONFIG_CC_STACKPROTECTOR_STRONG=y
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+# CONFIG_CC_STACKPROTECTOR_AUTO is not set
 CONFIG_THIN_ARCHIVES=y
 CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
 CONFIG_HAVE_CONTEXT_TRACKING=y
@@ -283,6 +290,7 @@ CONFIG_HAVE_ARCH_VMAP_STACK=y
 CONFIG_VMAP_STACK=y
 CONFIG_STRICT_KERNEL_RWX=y
 CONFIG_STRICT_MODULE_RWX=y
+CONFIG_ARCH_HAS_PHYS_TO_DMA=y
 
 #
 # GCOV-based kernel profiling
@@ -367,6 +375,7 @@ CONFIG_RWSEM_SPIN_ON_OWNER=y
 CONFIG_LOCK_SPIN_ON_OWNER=y
 CONFIG_QUEUED_SPINLOCKS=y
 CONFIG_QUEUED_RWLOCKS=y
+CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
 CONFIG_FREEZER=y
 
 #
@@ -413,6 +422,9 @@ CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
 CONFIG_SWIOTLB=y
 CONFIG_IOMMU_HELPER=y
 # CONFIG_MAXSMP is not set
+CONFIG_NR_CPUS_RANGE_BEGIN=2
+CONFIG_NR_CPUS_RANGE_END=512
+CONFIG_NR_CPUS_DEFAULT=64
 CONFIG_NR_CPUS=128
 CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
@@ -868,7 +880,7 @@ CONFIG_IPVTAP=m
 CONFIG_NETLABEL=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NET_PTP_CLASSIFY=y
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 CONFIG_NETFILTER_ADVANCED=y
@@ -1883,10 +1895,10 @@ CONFIG_MTD_ONENAND_2X_PROGRAM=y
 #
 CONFIG_MTD_LPDDR=m
 CONFIG_MTD_QINFO_PROBE=m
-CONFIG_MTD_SPI_NOR=m
+# CONFIG_MTD_SPI_NOR is not set
 # CONFIG_MTD_MT81xx_NOR is not set
 CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_SPI_INTEL_SPI_PLATFORM=m
+# CONFIG_SPI_INTEL_SPI_PLATFORM is not set
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_WL_THRESHOLD=4096
 CONFIG_MTD_UBI_BEB_LIMIT=20
@@ -3820,7 +3832,7 @@ CONFIG_HW_RANDOM_INTEL=m
 CONFIG_HW_RANDOM_AMD=m
 CONFIG_HW_RANDOM_VIA=m
 CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_HW_RANDOM_TPM=m
+CONFIG_HW_RANDOM_TPM=y
 CONFIG_NVRAM=m
 CONFIG_R3964=m
 CONFIG_APPLICOM=m
@@ -4028,6 +4040,8 @@ CONFIG_PTP_1588_CLOCK=m
 #
 # Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
 #
+
+# CONFIG_DP83640_PHY is not set
 CONFIG_PINCTRL=y
 
 #
@@ -4776,7 +4790,7 @@ CONFIG_DVB_MAX_ADAPTERS=8
 CONFIG_RC_CORE=m
 CONFIG_RC_MAP=m
 CONFIG_RC_DECODERS=y
-CONFIG_LIRC=m
+CONFIG_LIRC=y
 CONFIG_IR_LIRC_CODEC=m
 CONFIG_IR_NEC_DECODER=m
 CONFIG_IR_RC5_DECODER=m
@@ -5406,6 +5420,9 @@ CONFIG_DRM_FBDEV_EMULATION=y
 CONFIG_DRM_FBDEV_OVERALLOC=100
 CONFIG_DRM_LOAD_EDID_FIRMWARE=y
 CONFIG_DRM_TTM=m
+CONFIG_DRM_VM=y
+CONFIG_DRM_SCHED=m
+
 
 #
 # I2C encoder or helper chips
@@ -5492,6 +5509,7 @@ CONFIG_DRM_MGA=m
 CONFIG_DRM_SIS=m
 CONFIG_DRM_VIA=m
 CONFIG_DRM_SAVAGE=m
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
 
 #
 # Frame buffer Devices
@@ -9024,6 +9042,7 @@ CONFIG_SDR_PLATFORM_DRIVERS=y
 CONFIG_SND_SOC_ES8316=m
 CONFIG_SND_SOC_ZX_AUD96P22=m
 CONFIG_HID_ITE=m
+CONFIG_HID_JABRA=m
 CONFIG_HID_RETRODE=m
 CONFIG_TYPEC_UCSI=m
 CONFIG_RTC_NVMEM=y
@@ -9128,3 +9147,56 @@ CONFIG_PKCS7_TEST_KEY=m
 CONFIG_SYSTEM_TRUSTED_KEYS=""
 # CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
 # CONFIG_SECONDARY_TRUSTED_KEYRING is not set
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_IP6_NF_MATCH_SRH=m
+# CONFIG_NET_DSA_LEGACY is not set
+CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
+CONFIG_MISC_RTSX_PCI=m
+CONFIG_MISC_RTSX_USB=m
+CONFIG_SATA_MOBILE_LPM_POLICY=0
+CONFIG_DM_UNSTRIPED=m
+CONFIG_NET_VENDOR_CORTINA=y
+CONFIG_NET_VENDOR_SOCIONEXT=y
+CONFIG_MT76x2E=m
+CONFIG_NETDEVSIM=m
+CONFIG_GPIO_PCIE_IDIO_24=m
+CONFIG_SENSORS_W83773G=m
+CONFIG_MFD_CROS_EC_CHARDEV=m
+CONFIG_RAVE_SP_CORE=m
+CONFIG_LIRC=m
+CONFIG_DVB_MMAP=y
+# CONFIG_DVB_ULE_DEBUG is not set
+CONFIG_TINYDRM_ILI9225=m
+CONFIG_TINYDRM_ST7735R=m
+CONFIG_SND_SOC_MAX98373=m
+CONFIG_SND_SOC_PCM186X_I2C=m
+CONFIG_SND_SOC_PCM186X_SPI=m
+CONFIG_SND_SOC_TAS6424=m
+CONFIG_SND_SOC_TLV320AIC32X4_I2C=m
+CONFIG_SND_SOC_TLV320AIC32X4_SPI=m
+CONFIG_SND_SOC_TSCS42XX=m
+CONFIG_HID_JABRA=m
+# CONFIG_USB_XHCI_DBGCAP is not set
+CONFIG_LEDS_TRIGGER_NETDEV=m
+CONFIG_RTC_DRV_CROS_EC=m
+CONFIG_VIRTIO_MENU=y
+CONFIG_SOUNDWIRE=y
+CONFIG_XILINX_VCU=m
+CONFIG_IIO_BUFFER_HW_CONSUMER=m
+CONFIG_ST_UVIS25=m
+CONFIG_ZOPT2201=m
+CONFIG_SIOX=m
+CONFIG_SLIMBUS=m
+CONFIG_OVERLAY_FS_NFS_EXPORT=y
+CONFIG_CIFS_SMB_DIRECT=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_FIND_BIT_BENCHMARK=m
+CONFIG_HARDENED_USERCOPY_FALLBACK=y
+CONFIG_CHELSIO_IPSEC_INLINE=y
+CONFIG_NFT_FLOW_OFFLOAD=m
+CONFIG_NF_FLOW_TABLE_IPV4=m
+CONFIG_NF_FLOW_TABLE_IPV6=m
+CONFIG_RAVE_SP_WATCHDOG=m
+CONFIG_SIOX_BUS_GPIO=m
+CONFIG_SLIM_QCOM_CTRL=m
+CONFIG_NF_FLOW_TABLE_INET=m
diff --git a/hauppauge-hvr-1975.patch b/hauppauge-hvr-1975.patch
index ec26113..f080aca 100644
--- a/hauppauge-hvr-1975.patch
+++ b/hauppauge-hvr-1975.patch
@@ -1,5 +1,5 @@
---- linux-4.14/drivers/media/common/tveeprom.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/common/tveeprom.c	2017-12-25 17:39:13.302441499 +0100
+--- linux-4.15/drivers/media/common/tveeprom.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/common/tveeprom.c	2018-02-12 11:32:52.760582121 +0100
 @@ -551,7 +551,8 @@ void tveeprom_hauppauge_analog(struct tv
  				(eeprom_data[i+7] << 16)+
  				(eeprom_data[i+8] << 24);
@@ -10,8 +10,8 @@
  				tvee->MAC_address[0] = 0x00;
  				tvee->MAC_address[1] = 0x0D;
  				tvee->MAC_address[2] = 0xFE;
---- linux-4.14/drivers/media/dvb-frontends/Kconfig.0140~	2017-12-25 17:39:13.136441489 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/Kconfig	2017-12-25 17:39:13.302441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/Kconfig.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/dvb-frontends/Kconfig	2018-02-12 11:32:52.760582121 +0100
 @@ -529,6 +529,13 @@ config DVB_SI2168
  	help
  	  Say Y when you want to support this frontend.
@@ -41,9 +41,9 @@
  config DVB_LGS8GL5
  	tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
  	depends on DVB_CORE && I2C
---- linux-4.14/drivers/media/dvb-frontends/Makefile.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/Makefile	2017-12-25 17:39:13.302441499 +0100
-@@ -88,6 +88,7 @@ obj-$(CONFIG_DVB_CX24117) += cx24117.o
+--- linux-4.15/drivers/media/dvb-frontends/Makefile.0140~	2018-02-12 11:32:52.007576605 +0100
++++ linux-4.15/drivers/media/dvb-frontends/Makefile	2018-02-12 11:32:52.760582121 +0100
+@@ -87,6 +87,7 @@ obj-$(CONFIG_DVB_CX24117) += cx24117.o
  obj-$(CONFIG_DVB_CX24120) += cx24120.o
  obj-$(CONFIG_DVB_SI21XX) += si21xx.o
  obj-$(CONFIG_DVB_SI2168) += si2168.o
@@ -51,13 +51,13 @@
  obj-$(CONFIG_DVB_STV0288) += stv0288.o
  obj-$(CONFIG_DVB_STB6000) += stb6000.o
  obj-$(CONFIG_DVB_S921) += s921.o
-@@ -130,3 +131,4 @@ obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
+@@ -129,3 +130,4 @@ obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
  obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
  obj-$(CONFIG_DVB_HELENE) += helene.o
  obj-$(CONFIG_DVB_ZD1301_DEMOD) += zd1301_demod.o
 +obj-$(CONFIG_DVB_SILG) += silg.o
---- linux-4.14/drivers/media/dvb-frontends/si2168b.c.0140~	2017-12-25 17:39:13.304441499 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/si2168b.c	2017-12-25 17:39:13.304441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/si2168b.c.0140~	2018-02-12 11:32:52.764582151 +0100
++++ linux-4.15/drivers/media/dvb-frontends/si2168b.c	2018-02-12 11:32:52.764582151 +0100
 @@ -0,0 +1,6900 @@
 +/* DVB compliant Linux driver for the DVB-T/T2/C Si2168B demodulator
 +*
@@ -6959,8 +6959,8 @@
 +MODULE_AUTHOR("Henning Garbers <hgarbers@pctvsystems.com>");
 +MODULE_LICENSE("PROPRIETARY AND CONFIDENTIAL");
 +MODULE_VERSION("2015-03-09");
---- linux-4.14/drivers/media/dvb-frontends/si2168b.h.0140~	2017-12-25 17:39:13.304441499 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/si2168b.h	2017-12-25 17:39:13.304441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/si2168b.h.0140~	2018-02-12 11:32:52.764582151 +0100
++++ linux-4.15/drivers/media/dvb-frontends/si2168b.h	2018-02-12 11:32:52.764582151 +0100
 @@ -0,0 +1,70 @@
 +#ifndef SI2168B_H
 +#define SI2168B_H
@@ -7032,8 +7032,8 @@
 +#endif
 +
 +#endif
---- linux-4.14/drivers/media/dvb-frontends/si2168b_priv.h.0140~	2017-12-25 17:39:13.305441499 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/si2168b_priv.h	2017-12-25 17:39:13.305441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/si2168b_priv.h.0140~	2018-02-12 11:32:52.766582165 +0100
++++ linux-4.15/drivers/media/dvb-frontends/si2168b_priv.h	2018-02-12 11:32:52.766582165 +0100
 @@ -0,0 +1,4390 @@
 +#ifndef __SI2168B_PRIV_H__
 +#define __SI2168B_PRIV_H__
@@ -11425,8 +11425,8 @@
 +#define Si2168B_PATCH16_4_0b9_LINES (sizeof(Si2168B_PATCH16_4_0b9)/(sizeof(firmware_struct)))
 +
 +#endif /* __SI2168B_PRIV_H__ */
---- linux-4.14/drivers/media/dvb-frontends/silg.c.0140~	2017-12-25 17:39:13.306441499 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/silg.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/silg.c.0140~	2018-02-12 11:32:52.766582165 +0100
++++ linux-4.15/drivers/media/dvb-frontends/silg.c	2018-02-12 11:32:52.766582165 +0100
 @@ -0,0 +1,709 @@
 +/* DVB compliant Linux driver for dual demodulator system with
 +*  a Silicon Labs Si2168B DVB-T/T2/C demodulator
@@ -12137,8 +12137,8 @@
 +/* license is set to 'Proprietary'. */
 +MODULE_LICENSE("GPL");
 +MODULE_VERSION("1.0");
---- linux-4.14/drivers/media/dvb-frontends/silg.h.0140~	2017-12-25 17:39:13.306441499 +0100
-+++ linux-4.14/drivers/media/dvb-frontends/silg.h	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/dvb-frontends/silg.h.0140~	2018-02-12 11:32:52.767582173 +0100
++++ linux-4.15/drivers/media/dvb-frontends/silg.h	2018-02-12 11:32:52.767582173 +0100
 @@ -0,0 +1,69 @@
 +#ifndef SILG_H
 +#define SILG_H
@@ -12209,8 +12209,8 @@
 +#endif
 +
 +#endif
---- linux-4.14/drivers/media/pci/saa7164/Kconfig.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/Kconfig	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/Kconfig.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/Kconfig	2018-02-12 11:32:52.767582173 +0100
 @@ -7,7 +7,10 @@ config VIDEO_SAA7164
  	select VIDEO_TVEEPROM
  	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
@@ -12222,8 +12222,8 @@
  	---help---
  	  This is a video4linux driver for NXP SAA7164 based
  	  TV cards.
---- linux-4.14/drivers/media/pci/saa7164/saa7164-api.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-api.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-api.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-api.c	2018-02-12 11:32:52.767582173 +0100
 @@ -560,12 +560,43 @@ int saa7164_api_set_audio_std(struct saa
  		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  
@@ -12381,8 +12381,8 @@
  }
  
  /* Ensure the dif is in the correct state for the operating mode
---- linux-4.14/drivers/media/pci/saa7164/saa7164-cards.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-cards.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-cards.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-cards.c	2018-02-12 11:32:52.767582173 +0100
 @@ -634,6 +634,52 @@ struct saa7164_board saa7164_boards[] =
  			.i2c_reg_len	= REGLEN_0bit,
  		} },
@@ -12463,8 +12463,8 @@
  		hauppauge_eeprom(dev, &eeprom[0]);
  		break;
  	}
---- linux-4.14/drivers/media/pci/saa7164/saa7164-core.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-core.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-core.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-core.c	2018-02-12 11:32:52.767582173 +0100
 @@ -34,6 +34,7 @@
  MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
  MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
@@ -12473,8 +12473,8 @@
  
  /*
   *  1 Basic
---- linux-4.14/drivers/media/pci/saa7164/saa7164-dvb.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-dvb.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-dvb.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-dvb.c	2018-02-12 11:32:52.768582180 +0100
 @@ -23,6 +23,8 @@
  #include "si2157.h"
  #include "si2168.h"
@@ -12600,8 +12600,8 @@
  	default:
  		printk(KERN_ERR "%s: The frontend isn't supported\n",
  		       dev->name);
---- linux-4.14/drivers/media/pci/saa7164/saa7164-encoder.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-encoder.c	2017-12-25 17:39:13.306441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-encoder.c.0140~	2018-02-12 11:32:52.013576649 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-encoder.c	2018-02-12 11:32:52.768582180 +0100
 @@ -40,6 +40,24 @@ static struct saa7164_tvnorm saa7164_tvn
  	}, {
  		.name      = "NTSC-JP",
@@ -12645,8 +12645,8 @@
  	port->width = 720;
  	port->mux_input = 1; /* Composite */
  	port->video_format = EU_VIDEO_FORMAT_MPEG_2;
---- linux-4.14/drivers/media/pci/saa7164/saa7164-fw.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-fw.c	2017-12-25 17:39:13.307441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-fw.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-fw.c	2018-02-12 11:32:52.768582180 +0100
 @@ -26,6 +26,9 @@
  #define SAA7164_REV3_FIRMWARE		"NXP7164-2010-03-10.1.fw"
  #define SAA7164_REV3_FIRMWARE_SIZE	4019072
@@ -12675,8 +12675,8 @@
  	}
  
  	version = saa7164_getcurrentfirmwareversion(dev);
---- linux-4.14/drivers/media/pci/saa7164/saa7164.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164.h	2017-12-25 17:39:13.307441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164.h.0140~	2018-02-12 11:32:52.013576649 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164.h	2018-02-12 11:32:52.768582180 +0100
 @@ -82,6 +82,7 @@
  #define SAA7164_BOARD_HAUPPAUGE_HVR2255proto	11
  #define SAA7164_BOARD_HAUPPAUGE_HVR2255		12
@@ -12695,8 +12695,8 @@
  
  /* TV frequency range copied from tuner-core.c */
  #define SAA7164_TV_MIN_FREQ (44U * 16U)
---- linux-4.14/drivers/media/pci/saa7164/saa7164-reg.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/pci/saa7164/saa7164-reg.h	2017-12-25 17:39:13.307441499 +0100
+--- linux-4.15/drivers/media/pci/saa7164/saa7164-reg.h.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/pci/saa7164/saa7164-reg.h	2018-02-12 11:32:52.768582180 +0100
 @@ -177,7 +177,24 @@
  #define TU_STANDARD_AUTO_CONTROL	0x01
  #define TU_STANDARD_NONE		0x00
@@ -12722,9 +12722,9 @@
  #define TU_STANDARD_MANUAL		0x00
  #define TU_STANDARD_AUTO		0x01
  
---- linux-4.14/drivers/media/tuners/Kconfig.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/tuners/Kconfig	2017-12-25 17:39:13.307441499 +0100
-@@ -248,6 +248,20 @@ config MEDIA_TUNER_SI2157
+--- linux-4.15/drivers/media/tuners/Kconfig.0140~	2018-02-12 11:32:52.016576671 +0100
++++ linux-4.15/drivers/media/tuners/Kconfig	2018-02-12 11:32:52.768582180 +0100
+@@ -255,6 +255,20 @@ config MEDIA_TUNER_SI2157
  	help
  	  Silicon Labs Si2157 silicon tuner driver.
  
@@ -12745,18 +12745,17 @@
  config MEDIA_TUNER_IT913X
  	tristate "ITE Tech IT913x silicon tuner"
  	depends on MEDIA_SUPPORT && I2C
---- linux-4.14/drivers/media/tuners/Makefile.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/tuners/Makefile	2017-12-25 17:39:13.307441499 +0100
-@@ -42,6 +42,7 @@ obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t
- obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o
+--- linux-4.15/drivers/media/tuners/Makefile.0140~	2018-02-12 11:32:52.768582180 +0100
++++ linux-4.15/drivers/media/tuners/Makefile	2018-02-12 11:35:11.303551576 +0100
+@@ -43,5 +43,6 @@ obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mx
  obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o
  obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o
+ obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
 +obj-$(CONFIG_MEDIA_TUNER_SILABS_TERCAB) += silabs_tercab.o
  
- ccflags-y += -I$(srctree)/drivers/media/dvb-core
  ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
---- linux-4.14/drivers/media/tuners/silabs_tercab.c.0140~	2017-12-25 17:39:13.308441499 +0100
-+++ linux-4.14/drivers/media/tuners/silabs_tercab.c	2017-12-25 17:39:13.308441499 +0100
+--- linux-4.15/drivers/media/tuners/silabs_tercab.c.0140~	2018-02-12 11:32:52.770582195 +0100
++++ linux-4.15/drivers/media/tuners/silabs_tercab.c	2018-02-12 11:32:52.770582195 +0100
 @@ -0,0 +1,3452 @@
 +/*
 + * silabs_tercab.c - Silicon Labs terrestrial/cable hybrid tuner driver
@@ -16210,8 +16209,8 @@
 + * c-basic-offset: 8
 + * End:
 + */
---- linux-4.14/drivers/media/tuners/silabs_tercab.h.0140~	2017-12-25 17:39:13.308441499 +0100
-+++ linux-4.14/drivers/media/tuners/silabs_tercab.h	2017-12-25 17:39:13.308441499 +0100
+--- linux-4.15/drivers/media/tuners/silabs_tercab.h.0140~	2018-02-12 11:32:52.770582195 +0100
++++ linux-4.15/drivers/media/tuners/silabs_tercab.h	2018-02-12 11:32:52.770582195 +0100
 @@ -0,0 +1,102 @@
 +/*
 + * silabs_tercab.h - header for the Silicon Laboratories terrestrial/cable
@@ -16315,8 +16314,8 @@
 +#endif
 +
 +#endif /* __SILABS_TERCAB_H__ */
---- linux-4.14/drivers/media/tuners/silabs_tercab_priv.h.0140~	2017-12-25 17:39:13.310441499 +0100
-+++ linux-4.14/drivers/media/tuners/silabs_tercab_priv.h	2017-12-25 17:39:13.310441499 +0100
+--- linux-4.15/drivers/media/tuners/silabs_tercab_priv.h.0140~	2018-02-12 11:32:52.773582217 +0100
++++ linux-4.15/drivers/media/tuners/silabs_tercab_priv.h	2018-02-12 11:32:52.773582217 +0100
 @@ -0,0 +1,5651 @@
 +/*************************************************************************************
 +                  Silicon Laboratories Broadcast Si2158 Layer 1 API
@@ -21969,8 +21968,8 @@
 +#define FIRMWARE_LINES_3_0bx (sizeof(Si2177_FW_3_0bx)/(sizeof(firmware_struct)))
 +
 +#endif /* __SILABS_TERCAB_PRIV_H__ */
---- linux-4.14/drivers/media/tuners/tuner-types.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/tuners/tuner-types.c	2017-12-25 17:39:13.310441499 +0100
+--- linux-4.15/drivers/media/tuners/tuner-types.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/tuners/tuner-types.c	2018-02-12 11:32:52.773582217 +0100
 @@ -1433,6 +1433,16 @@ static struct tuner_params tuner_sony_bt
  	},
  };
@@ -22000,8 +21999,8 @@
  };
  EXPORT_SYMBOL(tuners);
  
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx-avcore.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx-avcore.c	2017-12-25 17:39:13.310441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx-avcore.c.0140~	2018-02-12 11:32:52.017576679 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx-avcore.c	2018-02-12 11:32:52.774582224 +0100
 @@ -355,6 +355,9 @@ int cx231xx_afe_update_power_control(str
  	case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
  	case CX231XX_BOARD_HAUPPAUGE_EXETER:
@@ -22041,10 +22040,10 @@
  	case CX231XX_BOARD_OTG102:
  		func_mode = 0x03;
  		break;
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx-cards.c.0140~	2017-12-25 17:39:13.139441490 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx-cards.c	2017-12-25 17:39:13.310441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx-cards.c.0140~	2018-02-12 11:32:52.017576679 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx-cards.c	2018-02-12 11:34:46.081381342 +0100
 @@ -34,6 +34,7 @@
- #include "dvb-usb-ids.h"
+ #include <media/dvb-usb-ids.h>
  #include "xc5000.h"
  #include "tda18271.h"
 +#include "si2157.h"
@@ -22175,7 +22174,7 @@
  	[CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = {
  		.name = "Hauppauge USB Live 2",
  		.tuner_type = TUNER_ABSENT,
-@@ -939,6 +1057,12 @@ struct usb_device_id cx231xx_id_table[]
+@@ -965,6 +1083,12 @@ struct usb_device_id cx231xx_id_table[]
  	 .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
  	{USB_DEVICE(0x2040, 0xb140),
  	 .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
@@ -22188,7 +22187,7 @@
  	{USB_DEVICE(0x2040, 0xc200),
  	 .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
  	/* PCTV QuatroStick 521e */
-@@ -996,7 +1120,7 @@ int cx231xx_tuner_callback(void *ptr, in
+@@ -1024,7 +1148,7 @@ int cx231xx_tuner_callback(void *ptr, in
  					       1);
  			msleep(10);
  		}
@@ -22197,7 +22196,7 @@
  		switch (command) {
  		case TDA18271_CALLBACK_CMD_AGC_ENABLE:
  			if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
-@@ -1145,7 +1269,6 @@ static int read_eeprom(struct cx231xx *d
+@@ -1173,7 +1297,6 @@ static int read_eeprom(struct cx231xx *d
  
  void cx231xx_card_setup(struct cx231xx *dev)
  {
@@ -22205,7 +22204,7 @@
  	cx231xx_set_model(dev);
  
  	dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
-@@ -1183,6 +1306,9 @@ void cx231xx_card_setup(struct cx231xx *
+@@ -1211,6 +1334,9 @@ void cx231xx_card_setup(struct cx231xx *
  	case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
  	case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
  	case CX231XX_BOARD_HAUPPAUGE_955Q:
@@ -22215,8 +22214,8 @@
  		{
  			struct eeprom {
  				struct tveeprom tvee;
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx-core.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx-core.c	2017-12-25 17:39:13.310441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx-core.c.0140~	2018-02-12 11:32:52.018576686 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx-core.c	2018-02-12 11:32:52.775582231 +0100
 @@ -720,6 +720,9 @@ int cx231xx_set_mode(struct cx231xx *dev
  			break;
  		case CX231XX_BOARD_HAUPPAUGE_EXETER:
@@ -22247,8 +22246,8 @@
  	case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
  	case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
  	case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx-dvb.c.0140~	2017-12-25 17:39:13.139441490 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx-dvb.c	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx-dvb.c.0140~	2018-02-12 11:32:52.018576686 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx-dvb.c	2018-02-12 11:32:52.775582231 +0100
 @@ -34,8 +34,11 @@
  #include "lgdt3305.h"
  #include "si2165.h"
@@ -22469,20 +22468,20 @@
  		unregister_dvb(dev->dvb);
  		dev->dvb = NULL;
  	}
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx.h	2017-12-25 17:39:13.311441499 +0100
-@@ -80,6 +80,9 @@
- #define CX231XX_BOARD_TERRATEC_GRABBY 22
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx.h.0140~	2018-02-12 11:32:52.775582231 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx.h	2018-02-12 11:34:17.881187893 +0100
+@@ -81,6 +81,9 @@
  #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23
  #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24
-+#define CX231XX_BOARD_HAUPPAUGE_EXETER_955Q 25
-+#define CX231XX_BOARD_HAUPPAUGE_935C 26
-+#define CX231XX_BOARD_HAUPPAUGE_975 27
+ #define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25
++#define CX231XX_BOARD_HAUPPAUGE_EXETER_955Q 26
++#define CX231XX_BOARD_HAUPPAUGE_935C 27
++#define CX231XX_BOARD_HAUPPAUGE_975 28
  
  /* Limits minimum and default number of buffers */
  #define CX231XX_MIN_BUF                 4
---- linux-4.14/drivers/media/usb/cx231xx/cx231xx-video.c.0140~	2017-12-25 17:39:13.139441490 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/cx231xx-video.c	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/cx231xx-video.c.0140~	2018-02-12 11:32:52.018576686 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/cx231xx-video.c	2018-02-12 11:32:52.776582239 +0100
 @@ -1094,6 +1094,18 @@ static int vidioc_s_std(struct file *fil
  	/* do mode control overrides */
  	cx231xx_do_mode_ctrl_overrides(dev);
@@ -22511,8 +22510,8 @@
  		if (dev->norm & (V4L2_STD_MN | V4L2_STD_NTSC_443))
  			if_frequency = 5400000;  /*5.4MHz	*/
  		else if (dev->norm & V4L2_STD_B)
---- linux-4.14/drivers/media/usb/cx231xx/Kconfig.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/cx231xx/Kconfig	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/cx231xx/Kconfig.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/cx231xx/Kconfig	2018-02-12 11:32:52.776582239 +0100
 @@ -45,12 +45,15 @@ config VIDEO_CX231XX_DVB
  	select VIDEOBUF_DVB
  	select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
@@ -22529,8 +22528,8 @@
  	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
  	select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT
  	select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT
---- linux-4.14/drivers/media/usb/pvrusb2/Kconfig.0140~	2017-12-25 17:39:13.311441499 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/Kconfig	2017-12-25 17:43:31.130666399 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/Kconfig.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/Kconfig	2018-02-12 11:32:52.776582239 +0100
 @@ -39,10 +39,13 @@ config VIDEO_PVRUSB2_DVB
  	select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
  	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
@@ -22545,8 +22544,8 @@
  	---help---
  	  This option enables a DVB interface for the pvrusb2 driver.
  	  If your device does not support digital television, this
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c	2018-02-12 11:32:52.776582239 +0100
 @@ -112,10 +112,35 @@ static const struct routing_scheme routi
  	.cnt = ARRAY_SIZE(routing_schemeav400),
  };
@@ -22583,8 +22582,8 @@
  };
  
  void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-devattr.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-devattr.c	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-devattr.c.0140~	2018-02-12 11:32:52.020576701 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-devattr.c	2018-02-12 11:32:52.776582239 +0100
 @@ -31,15 +31,18 @@ pvr2_device_desc structures.
  #ifdef CONFIG_VIDEO_PVRUSB2_DVB
  #include "pvrusb2-hdw-internal.h"
@@ -22824,8 +22823,8 @@
  MODULE_FIRMWARE(PVR2_FIRMWARE_73xxx);
  MODULE_FIRMWARE(PVR2_FIRMWARE_75xxx);
 +MODULE_FIRMWARE(PVR2_FIRMWARE_160xxx);
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-devattr.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-devattr.h	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-devattr.h.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-devattr.h	2018-02-12 11:32:52.776582239 +0100
 @@ -66,6 +66,7 @@ struct pvr2_string_table {
  #define PVR2_ROUTING_SCHEME_GOTVIEW 1
  #define PVR2_ROUTING_SCHEME_ONAIR 2
@@ -22834,8 +22833,8 @@
  
  #define PVR2_DIGITAL_SCHEME_NONE 0
  #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-dvb.c.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-dvb.c	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-dvb.c.0140~	2018-02-12 11:32:52.020576701 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-dvb.c	2018-02-12 11:32:52.776582239 +0100
 @@ -244,6 +244,13 @@ static int pvr2_dvb_stop_feed(struct dvb
  static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
  {
@@ -22862,8 +22861,8 @@
  	} else {
  		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
  			   "no frontend was attached!");
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h	2017-12-25 17:39:13.311441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h	2018-02-12 11:32:52.776582239 +0100
 @@ -38,6 +38,10 @@
  
  #define FX2CMD_FWPOST1          0x52u
@@ -22875,8 +22874,8 @@
  #define FX2CMD_POWER_OFF        0xdcu
  #define FX2CMD_POWER_ON         0xdeu
  
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-hdw.c.0140~	2017-12-25 17:39:13.139441490 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-hdw.c	2017-12-25 17:39:13.312441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-hdw.c.0140~	2018-02-12 11:32:52.020576701 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-hdw.c	2018-02-12 11:32:52.777582246 +0100
 @@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef
  	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
  	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
@@ -22926,7 +22925,7 @@
  	if (!pvr2_hdw_dev_ok(hdw)) return;
  
  	if (hdw->hdw_desc->signal_routing_scheme ==
-@@ -3998,6 +4017,17 @@ int pvr2_hdw_cmd_decoder_reset(struct pv
+@@ -4011,6 +4030,17 @@ int pvr2_hdw_cmd_decoder_reset(struct pv
  static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
  {
  	hdw->flag_ok = !0;
@@ -22944,8 +22943,8 @@
  	return pvr2_issue_simple_cmd(hdw,
  				     FX2CMD_HCW_DEMOD_RESETIN |
  				     (1 << 8) |
---- linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h	2017-12-25 17:39:13.312441499 +0100
+--- linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h	2018-02-12 11:32:52.777582246 +0100
 @@ -381,6 +381,9 @@ struct pvr2_hdw {
  
  	struct pvr2_ctrl *controls;
@@ -22956,8 +22955,8 @@
  };
  
  /* This function gets the current frequency */
---- linux-4.14/drivers/media/v4l2-core/tuner-core.c.0140~	2017-12-25 17:39:13.140441490 +0100
-+++ linux-4.14/drivers/media/v4l2-core/tuner-core.c	2017-12-25 17:39:13.312441499 +0100
+--- linux-4.15/drivers/media/v4l2-core/tuner-core.c.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/drivers/media/v4l2-core/tuner-core.c	2018-02-12 11:32:52.778582253 +0100
 @@ -40,6 +40,7 @@
  #include "xc5000.h"
  #include "tda18271.h"
@@ -23034,8 +23033,8 @@
  			}
  			break;
  		}
---- linux-4.14/include/media/tuner.h.0140~	2017-11-12 19:46:13.000000000 +0100
-+++ linux-4.14/include/media/tuner.h	2017-12-25 17:39:13.312441499 +0100
+--- linux-4.15/include/media/tuner.h.0140~	2018-01-28 22:20:33.000000000 +0100
++++ linux-4.15/include/media/tuner.h	2018-02-12 11:32:52.778582253 +0100
 @@ -142,6 +142,8 @@
  #define TUNER_SONY_BTF_PK467Z		90	/* NTSC_JP */
  #define TUNER_SONY_BTF_PB463Z		91	/* NTSC */
diff --git a/i386-common.config b/i386-common.config
index 40bd387..9a97ec1 100644
--- a/i386-common.config
+++ b/i386-common.config
@@ -1,3 +1,4 @@
+CONFIG_HAVE_KERNEL_ZSTD=y
 # CONFIG_64BIT is not set
 CONFIG_X86=y
 CONFIG_INSTRUCTION_DECODER=y
@@ -404,6 +405,7 @@ CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m
 CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m
 CONFIG_UCSI_ACPI=m
 CONFIG_DRM_VBOXVIDEO=m
+CONFIG_VBOXSF_FS=m
 CONFIG_WMI_BMOF=m
 CONFIG_PEAQ_WMI=m
 CONFIG_INTEL_INT0002_VGPIO=m
@@ -418,7 +420,7 @@ CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH=y
 CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
 CONFIG_INTEL_RDT=y
 CONFIG_HYPERV_VSOCKETS=m
-CONFIG_SPI_INTEL_SPI_PCI=m
+# CONFIG_SPI_INTEL_SPI_PCI is not set
 CONFIG_HINIC=m
 CONFIG_PINCTRL_DENVERTON=m
 CONFIG_PINCTRL_LEWISBURG=m
@@ -439,7 +441,7 @@ CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m
 CONFIG_THUNDERBOLT_NET=m
 CONFIG_PINCTRL_CEDARFORK=m
 CONFIG_INTEL_SOC_PMIC_CHTDC_TI=m
-CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=m
+CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
 CONFIG_LEDS_APU=m
 CONFIG_VIDEO_ATOMISP_OV5693=m
 CONFIG_VIDEO_ATOMISP_OV2722=m
@@ -454,3 +456,18 @@ CONFIG_DELL_SMBIOS_SMM=m
 CONFIG_INTEL_WMI_THUNDERBOLT=m
 CONFIG_RPMSG_VIRTIO=m
 CONFIG_RETPOLINE=y
+CONFIG_ACPI_SPCR_TABLE=y
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m
+CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH=m
+CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH=m
+CONFIG_MMC_SDHCI_F_SDH30=m
+CONFIG_VBOXGUEST=m
+CONFIG_ACER_WIRELESS=m
+CONFIG_DELL_SMBIOS_WMI=y
+CONFIG_DELL_SMBIOS_SMM=y
+CONFIG_GPD_POCKET_FAN=m
+CONFIG_INTEL_CHTDC_TI_PWRBTN=m
+CONFIG_MELLANOX_PLATFORM=y
+CONFIG_SOUNDWIRE_INTEL=m
+# CONFIG_BPF_KPROBE_OVERRIDE is not set
+CONFIG_MLXREG_HOTPLUG=m
diff --git a/kernel-release.spec b/kernel-release.spec
index 8fde669..5c7667a 100644
--- a/kernel-release.spec
+++ b/kernel-release.spec
@@ -1,13 +1,18 @@
 # utils/cpuidle-info.c:193: error: undefined reference to 'cpufreq_cpu_exists'
 %define _disable_ld_no_undefined 1
-%global optflags %optflags -O3
 
-# IMPORTNAT
+# (tpg) try to speed up things
+%global optflags %{optflags} -O3
+
+# While perf comes with python2 scripts
+%define _python_bytecompile_build 0
+
+# IMPORTANT
 # This is the place where you set kernel version i.e 4.5.0
 # compose tar.xz name and release
 %define kernelversion	4
-%define patchlevel	15
-%define sublevel	18
+%define patchlevel	16
+%define sublevel	7
 %define relc		0
 # Only ever wrong on x.0 releases...
 %define previous	%{kernelversion}.%(echo $((%{patchlevel}-1)))
@@ -22,7 +27,7 @@
 %define tar_ver   	%{kernelversion}.%(expr %{patchlevel} - 1)
 %else
 %define rpmrel		1
-%define tar_ver   	%{kernelversion}.%{patchlevel}
+%define tar_ver		%{kernelversion}.%{patchlevel}
 %endif
 %define buildrpmrel	%{rpmrel}%{rpmtag}
 
@@ -70,12 +75,12 @@
 %bcond_with cross_headers
 %endif
 
-%global	cross_header_archs	aarch64-linux armv7hl-linux i586-linux i686-linux x86_64-linux x32-linux aarch64-linuxmusl armv7hl-linuxmusl i586-linuxmusl i686-linuxmusl x86_64-linuxmusl x32-linuxmusl
+%global	cross_header_archs	aarch64-linux armv7hl-linux i686-linux x86_64-linux x32-linux riscv32-linux riscv64-linux aarch64-linuxmusl armv7hl-linuxmusl i686-linuxmusl x86_64-linuxmusl x32-linuxmusl riscv32-linuxmusl riscv64-linuxmusl aarch64-android armv7l-android armv8l-android
 %global long_cross_header_archs %(
 	for i in %{cross_header_archs}; do
 		CPU=$(echo $i |cut -d- -f1)
 		OS=$(echo $i |cut -d- -f2)
-		echo -n "$(rpm --macros %%{_usrlibrpm}/macros:%%{_usrlibrpm}/platform/${CPU}-${OS}/macros --target=${CPU} -E %%{_target_platform}) "
+		echo -n "$(rpm --target=${CPU}-${OS} -E %%{_target_platform}) "
 	done
 )
 
@@ -104,8 +109,13 @@
 %bcond_with build_cpupower
 %endif
 
-# compress modules with xz
+# compress modules with zstd
+# (tpg) currently it supports only x86 arch
+%ifnarch %{armx}
+%bcond_without build_modzstd
+%else
 %bcond_without build_modxz
+%endif
 
 # ARM builds
 %ifarch %{armx}
@@ -114,7 +124,6 @@
 %endif
 # End of user definitions
 
-
 # For the .nosrc.rpm
 %bcond_with build_nosrc
 
@@ -131,11 +140,11 @@
 ###################################################
 # Parallelize xargs invocations on smp machines
 %define kxargs xargs %([ -z "$RPM_BUILD_NCPUS" ] \\\
-	&& RPM_BUILD_NCPUS="$(/usr/bin/getconf _NPROCESSORS_ONLN)"; \\\
+	&& RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
 	[ "$RPM_BUILD_NCPUS" -gt 1 ] && echo "-P $RPM_BUILD_NCPUS")
 
 # Sparc arch wants sparc64 kernels
-%define target_arch    %(echo %{_arch} | sed -e 's/mips.*/mips/' -e 's/arm.*/arm/' -e 's/aarch64/arm64/')
+%define target_arch %(echo %{_arch} | sed -e 's/mips.*/mips/' -e 's/arm.*/arm/' -e 's/aarch64/arm64/')
 
 #
 # SRC RPM description
@@ -239,32 +248,32 @@ Patch1031:	0001-Fix-for-compilation-with-clang.patch
 # Bootsplash system
 # https://lkml.org/lkml/2017/10/25/346
 # https://patchwork.kernel.org/patch/10172665/
-Patch100:      RFC-v3-01-13-bootsplash-Initial-implementation-showing-black-screen.patch
+Patch100:	RFC-v3-01-13-bootsplash-Initial-implementation-showing-black-screen.patch
 # https://patchwork.kernel.org/patch/10172669/
-Patch101:      RFC-v3-02-13-bootsplash-Add-file-reading-and-picture-rendering.patch
+Patch101:	RFC-v3-02-13-bootsplash-Add-file-reading-and-picture-rendering.patch
 # https://patchwork.kernel.org/patch/10172715/
-Patch102:      RFC-v3-03-13-bootsplash-Flush-framebuffer-after-drawing.patch
+Patch102:	RFC-v3-03-13-bootsplash-Flush-framebuffer-after-drawing.patch
 # https://patchwork.kernel.org/patch/10172699/
-Patch103:      RFC-v3-04-13-bootsplash-Add-corner-positioning.patch
+Patch103:	RFC-v3-04-13-bootsplash-Add-corner-positioning.patch
 # https://patchwork.kernel.org/patch/10172667/
-Patch104:      RFC-v3-05-13-bootsplash-Add-animation-support.patch
+Patch104:	RFC-v3-05-13-bootsplash-Add-animation-support.patch
 # https://patchwork.kernel.org/patch/10172605/, rebased
-Patch105:      RFC-v3-06-13-vt-Redraw-bootsplash-fully-on-console_unblank.patch
+Patch105:	RFC-v3-06-13-vt-Redraw-bootsplash-fully-on-console_unblank.patch
 # https://patchwork.kernel.org/patch/10172599/
-Patch106:      RFC-v3-07-13-vt-Add-keyboard-hook-to-disable-bootsplash.patch
+Patch106:	RFC-v3-07-13-vt-Add-keyboard-hook-to-disable-bootsplash.patch
 # https://patchwork.kernel.org/patch/10172603/
-Patch107:      RFC-v3-08-13-sysrq-Disable-bootsplash-on-SAK.patch
+Patch107:	RFC-v3-08-13-sysrq-Disable-bootsplash-on-SAK.patch
 # https://patchwork.kernel.org/patch/10172601/
-Patch108:      RFC-v3-09-13-fbcon-Disable-bootsplash-on-oops.patch
+Patch108:	RFC-v3-09-13-fbcon-Disable-bootsplash-on-oops.patch
 # https://patchwork.kernel.org/patch/10172663/
-Patch109:      RFC-v3-10-13-Documentation-Add-bootsplash-main-documentation.patch
+Patch109:	RFC-v3-10-13-Documentation-Add-bootsplash-main-documentation.patch
 # https://patchwork.kernel.org/patch/10172685/
-Patch110:      RFC-v3-11-13-bootsplash-sysfs-entries-to-load-and-unload-files.patch
+Patch110:	RFC-v3-11-13-bootsplash-sysfs-entries-to-load-and-unload-files.patch
 # https://patchwork.kernel.org/patch/10172597/
-Patch111:      RFC-v3-12-13-tools-bootsplash-Add-a-basic-splash-file-creation-tool.patch
+Patch111:	RFC-v3-12-13-tools-bootsplash-Add-a-basic-splash-file-creation-tool.patch
 # https://patchwork.kernel.org/patch/10172661/
 # Contains git binary patch -- needs to be applied with git apply instead of apply_patches
-Source112:      RFC-v3-13-13-tools-bootsplash-Add-script-and-data-to-create-sample-file.patch
+Source112:	RFC-v3-13-13-tools-bootsplash-Add-script-and-data-to-create-sample-file.patch
 
 # Patches to VirtualBox and other external modules are
 # pulled in as Source: rather than Patch: because it's arch specific
@@ -274,9 +283,18 @@ Source112:      RFC-v3-13-13-tools-bootsplash-Add-script-and-data-to-create-samp
 # (tpg) http://kerneldedup.org/en/projects/uksm/download/
 # (tpg) sources can be found here https://github.com/dolohow/uksm
 # Temporarily disabled for -rc releases until ported upstream
-Patch120:	https://raw.githubusercontent.com/dolohow/uksm/master/uksm-4.15.patch
+Patch120:	https://raw.githubusercontent.com/dolohow/uksm/master/uksm-4.16.patch
 
 Patch125:	0005-crypto-Add-zstd-support.patch
+%if %{with build_modzstd}
+# https://patchwork.kernel.org/patch/10003007/
+Patch126:	v2-1-2-lib-Add-support-for-ZSTD-compressed-kernel.patch
+# https://patchwork.kernel.org/patch/10003011/
+Patch127:	v2-2-2-x86-Add-support-for-ZSTD-compressed-kernel.patch
+%endif
+
+# https://bugs.freedesktop.org/show_bug.cgi?id=100446
+Patch130:	nouveau-pascal-backlight.patch
 
 ### Additional hardware support
 ### TV tuners:
@@ -303,7 +321,15 @@ Patch146:	saa716x-4.15.patch
 #Patch200:	0001-ipc-namespace-a-generic-per-ipc-pointer-and-peripc_o.patch
 # NOT YET
 #Patch201:	0002-binder-implement-namepsace-support-for-Android-binde.patch
+
 Patch250:	4.14-C11.patch
+Patch251:	https://raw.githubusercontent.com/frugalware/frugalware-current/master/source/base/kernel/0001-Make-it-possible-to-disable-SWIOTLB-code-on-admgpu-a.patch
+
+# VirtualBox shared folders support
+# https://patchwork.kernel.org/patch/10315707/
+# For newer versions, check
+# https://patchwork.kernel.org/project/LKML/list/?submitter=582
+Patch300:	v7-fs-Add-VirtualBox-guest-shared-folder-vboxsf-support.patch
 
 # Patches to external modules
 # Marked SourceXXX instead of PatchXXX because the modules
@@ -347,8 +373,9 @@ input and output, etc. \
 This version is a preview of an upcoming kernel version, and may be helpful if you are using \
 very current hardware.
 
-
 ### Global Requires/Provides
+# do not require dracut, please it bloats dockers and other minimal instllations
+# better solution needs to be figured out
 %define requires2	dracut >= 047
 %define requires3	kmod >= 25
 %define requires4	sysfsutils >=  2.1.0-12
@@ -370,8 +397,16 @@ very current hardware.
 # nvidia173 does not support this kernel
 
 Autoreqprov:	no
-
+%if %{with build_modzstd}
+BuildRequires:	zstd
+%endif
+%if %{with build_modxz}
+BuildRequires:	xz
+%endif
+BuildRequires:	findutils
 BuildRequires:	bc
+BuildRequires:	flex
+BuildRequires:	bison
 BuildRequires:	binutils
 BuildRequires:	gcc >= 7.2.1_2017.11-3
 BuildRequires:	gcc-plugin-devel >= 7.2.1_2017.11-3
@@ -456,8 +491,8 @@ Release:	%{fakerel}				\
 Provides:	%kprovides1 %kprovides2			\
 %{expand:%%{?kprovides_%{1}:Provides: %{kprovides_%{1}}}} \
 Provides:	%{kname}-%{1}				\
-Requires(pre):	%requires2 %requires3 %requires4	\
-Requires:	%requires2 %requires5			\
+Requires(pre):	%requires3 %requires4			\
+Requires:	%requires5				\
 Obsoletes:	%kobsoletes1 %kobsoletes2 %kobsoletes3	\
 Conflicts:	%kconflicts1 %kconflicts2 %kconflicts3	\
 Conflicts:	%kconflicts4 %kconflicts5		\
@@ -699,7 +734,7 @@ Version:	%{kversion}
 Release:	%{rpmrel}
 Summary:	The cpupower tools
 Group:		System/Kernel and hardware
-Requires(post): 	rpm-helper >= 0.24.0-3
+Requires(post):		rpm-helper >= 0.24.0-3
 Requires(preun):	rpm-helper >= 0.24.0-3
 Obsoletes:	cpufreq < 2.0-3
 Provides:	cpufreq = 2.0-3
@@ -826,6 +861,7 @@ git apply %{SOURCE112}
 # merge SAA716x DVB driver from extra tarball
 sed -i -e '/saa7164/isource "drivers/media/pci/saa716x/Kconfig"' drivers/media/pci/Kconfig
 sed -i -e '/saa7164/iobj-$(CONFIG_SAA716X_CORE) += saa716x/' drivers/media/pci/Makefile
+find drivers/media/tuners drivers/media/dvb-frontends -name "*.c" -o -name "*.h" |xargs sed -i -e 's,"dvb_frontend.h",<media/dvb_frontend.h>,g'
 
 %if %{with build_debug}
 %define debug --debug
@@ -840,24 +876,12 @@ LC_ALL=C sed -i -e "s/^SUBLEVEL.*/SUBLEVEL = %{sublevel}/" Makefile
 %if %mdvver >= 3000000
 %ifarch %{ix86} x86_64
 # === VirtualBox guest additions ===
-# VirtualBox video driver
-cp -a $(ls --sort=time -1d /usr/src/vboxadditions-*|head -n1)/vboxvideo drivers/gpu/drm/
+# VBoxVideo is upstreamed -- let's fix it instead of copying the dkms driver
 # 800x600 is too small to be useful -- even calamares doesn't
 # fit into that anymore
-sed -i -e 's|800, 600|1024, 768|g' drivers/gpu/drm/vboxvideo/vbox_mode.c
-sed -i -e 's,\$(KBUILD_EXTMOD),drivers/gpu/drm/vboxvideo,g' drivers/gpu/drm/vboxvideo/Makefile*
-sed -i -e "s,^KERN_DIR.*,KERN_DIR := $(pwd)," drivers/gpu/drm/vboxvideo/Makefile*
-echo 'obj-m += vboxvideo/' >>drivers/gpu/drm/Makefile
-# VirtualBox shared folders
-cp -a $(ls --sort=time -1d /usr/src/vboxadditions-*|head -n1)/vboxsf fs/
-sed -i -e 's,\$(KBUILD_EXTMOD),fs/vboxsf,g' fs/vboxsf/Makefile*
-sed -i -e "s,^KERN_DIR.*,KERN_DIR := $(pwd)," fs/vboxsf/Makefile*
-echo 'obj-m += vboxsf/' >>fs/Makefile
-# VirtualBox Guest-side communication
-cp -a $(ls --sort=time -1d /usr/src/vboxadditions-*|head -n1)/vboxguest drivers/bus/
-sed -i -e 's,\$(KBUILD_EXTMOD),drivers/bus/vboxguest,g' drivers/bus/vboxguest/Makefile*
-sed -i -e "s,^KERN_DIR.*,KERN_DIR := $(pwd)," drivers/bus/vboxguest/Makefile*
-echo 'obj-m += vboxguest/' >>drivers/bus/Makefile
+sed -i -e 's|800, 600|1024, 768|g' drivers/staging/vboxvideo/vbox_mode.c
+# VBoxGuest is upstreamed -- no need to do anything for it
+# VirtualBox shared folders now come in through patch 300
 
 # === VirtualBox host modules ===
 # VirtualBox
@@ -884,9 +908,9 @@ echo 'obj-m += vboxpci/' >>drivers/pci/Makefile
 %endif
 
 # get rid of unwanted files
-find . -name '*~' -o -name '*.orig' -o -name '*.append' | %kxargs rm -f
+find . -name '*~' -o -name '*.orig' -o -name '*.append' -delete
 # wipe all .gitignore/.get_maintainer.ignore files
-find . -name "*.g*ignore" -exec rm {} \;
+find . -name "*.g*ignore" -delete
 
 # fix missing exec flag on file introduced in 4.14.10-rc1
 chmod 755 tools/objtool/sync-check.sh
@@ -908,7 +932,7 @@ export PYTHON=%{__python2}
 %define _kerneldir /usr/src/linux-%{kversion}-%{buildrpmrel}
 %define _bootdir /boot
 %define _modulesdir /lib/modules
-%define _efidir %{_bootdir}/efi/mandriva
+%define _efidir %{_bootdir}/efi/EFI/openmandriva
 
 # Directories definition needed for building
 %define temp_root %{build_dir}/temp-root
@@ -927,6 +951,15 @@ CreateConfig() {
 	CLANG_EXTRAS=""
 %endif
 
+%if %{with build_modxz}
+sed -i -e "s/^# CONFIG_KERNEL_XZ is not set/CONFIG_KERNEL_XZ=y/g" %{_sourcedir}/common.config
+%endif
+
+%if %{with build_modzstd}
+sed -i -e "s/^# CONFIG_KERNEL_ZSTD is not set/CONFIG_KERNEL_ZSTD=y/g" %{_sourcedir}/common.config
+sed -i -e "s/^# CONFIG_RD_ZSTD is not set/CONFIG_RD_ZSTD=y/g" %{_sourcedir}/common.config
+%endif
+
 	for i in common common-${type} ${arch}-common ${arch}-${type} $CLANG_EXTRAS; do
 		[ -e %{_sourcedir}/$i.config ] || continue
 		if [ -e .config ]; then
@@ -945,7 +978,7 @@ PrepareKernel() {
     name=$1
     extension=$2
     config_dir=%{_sourcedir}
-    printf '%s\n'  "Make config for kernel $extension"
+    printf '%s\n' "Make config for kernel $extension"
     %{smake} -s mrproper
     CreateConfig %{target_arch} ${flavour}
     # make sure EXTRAVERSION says what we want it to say
@@ -975,14 +1008,21 @@ BuildKernel() {
     install -d %{temp_boot}
     install -m 644 System.map %{temp_boot}/System.map-$KernelVer
     install -m 644 .config %{temp_boot}/config-$KernelVer
+
 %if %{with build_modxz}
 %ifarch %{ix86} %{armx}
     xz -5 -T0 -c Module.symvers > %{temp_boot}/symvers-$KernelVer.xz
 %else
     xz -7 -T0 -c Module.symvers > %{temp_boot}/symvers-$KernelVer.xz
 %endif
+%endif
+
+%if %{with build_modzstd}
+%ifarch %{ix86} %{armx}
+    zstd -15 -q -T0 -c Module.symvers > %{temp_boot}/symvers-$KernelVer.zst
 %else
-    gzip -9 -c Module.symvers > %{temp_boot}/symvers-$KernelVer.gz
+    zstd -10 -q -T0 -c Module.symvers > %{temp_boot}/symvers-$KernelVer.zst
+%endif
 %endif
 
 %ifarch %{arm}
@@ -1056,7 +1096,6 @@ SaveDevel() {
     cp -fR drivers/media/common/btcx-risc.h $TempDevelRoot/drivers/media/common/
 
 # Needed for external dvb tree (#41418)
-    cp -fR drivers/media/dvb-core/*.h $TempDevelRoot/drivers/media/dvb-core/
     cp -fR drivers/media/dvb-frontends/lgdt330x.h $TempDevelRoot/drivers/media/dvb-frontends/
 
 # add acpica header files, needed for fglrx build
@@ -1071,16 +1110,10 @@ SaveDevel() {
     cp -fR tools/scripts/utilities.mak $TempDevelRoot/tools/scripts
 
     for i in alpha arc avr32 blackfin c6x cris frv h8300 hexagon ia64 m32r m68k m68knommu metag microblaze \
-		 mips mn10300 nios2 openrisc parisc powerpc riscv s390 score sh sparc tile unicore32 xtensa; do
+		 mips mn10300 nios2 openrisc parisc powerpc s390 score sh sparc tile unicore32 xtensa; do
 	rm -rf $TempDevelRoot/arch/$i
     done
 
-%ifnarch %{armx}
-   rm -rf $TempDevelRoot/arch/arm*
-   rm -rf $TempDevelRoot/include/kvm/arm*
-   rm -rf $TempDevelRoot/include/soc
-%endif
-
 # Clean the scripts tree, and make sure everything is ok (sanity check)
 # running prepare+scripts (tree was already "prepared" in build)
     cd $TempDevelRoot >/dev/null
@@ -1100,10 +1133,9 @@ cat > $kernel_devel_files <<EOF
 %dir $DevelRoot/arch
 %dir $DevelRoot/include
 $DevelRoot/Documentation
-%ifarch %{armx}
 $DevelRoot/arch/arm
 $DevelRoot/arch/arm64
-%endif
+$DevelRoot/arch/riscv
 $DevelRoot/arch/um
 $DevelRoot/arch/x86
 $DevelRoot/block
@@ -1133,9 +1165,7 @@ $DevelRoot/include/pcmcia
 $DevelRoot/include/ras
 $DevelRoot/include/rdma
 $DevelRoot/include/scsi
-%ifarch %{armx}
 $DevelRoot/include/soc
-%endif
 $DevelRoot/include/sound
 $DevelRoot/include/target
 $DevelRoot/include/trace
@@ -1199,7 +1229,7 @@ SaveDebug() {
     echo "%{_bootdir}/vmlinux-%{kversion}-$debug_flavour-%{buildrpmrel}" >> $kernel_debug_files
 
     find %{temp_modules}/%{kversion}-$debug_flavour-%{buildrpmrel}/kernel -name "*.ko" | %kxargs -I '{}' objcopy --only-keep-debug '{}' '{}'.debug
-    find %{temp_modules}/%{kversion}-$debug_flavour-%{buildrpmrel}/kernel -name "*.ko" | %kxargs -I '{}' sh -c 'cd $(dirname {}); objcopy --add-gnu-debuglink=$(basename {}).debug --strip-debug $(basename {})'
+    find %{temp_modules}/%{kversion}-$debug_flavour-%{buildrpmrel}/kernel -name "*.ko" | %kxargs -I '{}' sh -c 'cd `dirname {}`; objcopy --add-gnu-debuglink=`basename {}`.debug --strip-debug `basename {}`'
 
     cd %{temp_modules}
     find %{kversion}-$debug_flavour-%{buildrpmrel}/kernel -name "*.ko.debug" > debug_module_list
@@ -1217,7 +1247,7 @@ ker="vmlinuz"
 ### Create the kernel_files.*
 cat > $kernel_files <<EOF
 %{_bootdir}/System.map-%{kversion}-$kernel_flavour-%{buildrpmrel}
-%{_bootdir}/symvers-%{kversion}-$kernel_flavour-%{buildrpmrel}.*z
+%{_bootdir}/symvers-%{kversion}-$kernel_flavour-%{buildrpmrel}.[gxz]*
 %{_bootdir}/config-%{kversion}-$kernel_flavour-%{buildrpmrel}
 %{_bootdir}/$ker-%{kversion}-$kernel_flavour-%{buildrpmrel}
 # device tree binary
@@ -1231,7 +1261,7 @@ cat > $kernel_files <<EOF
 EOF
 
 %if %{with build_debug}
-    cat kernel_exclude_debug_files.$kernel_flavour >> $kernel_files
+cat kernel_exclude_debug_files.$kernel_flavour >> $kernel_files
 %endif
 
 ### Create kernel Post script
@@ -1252,7 +1282,6 @@ if [ -e initrd-%{kversion}-$kernel_flavour-%{buildrpmrel}.img ]; then
 fi
 
 cd - > /dev/null
-
 %if %{with build_devel}
 # create kernel-devel symlinks if matching -devel- rpm is installed
 if [ -d /usr/src/linux-%{kversion}-$kernel_flavour-%{buildrpmrel} ]; then
@@ -1356,15 +1385,15 @@ for i in arm arm64 i386 x86_64; do
 done
 if [ -s newconfigs ]; then
 	set +x
-	echo "New config options have been added - please update the *.config files."
-	echo "New config options you need to take care of:"
+	printf '%s\n' "New config options have been added - please update the *.config files."
+	printf '%s\n' "New config options you need to take care of:"
 	if [ -e newconfigs.common ]; then
-		echo "For common.config:"
+		printf '%s\n' "For common.config:"
 		cat newconfigs.common
 	fi
 	for i in arm arm64 i386 x86_64; do
 		[ -e newconfigs.${i}only ] || continue
-		echo "For $i-common.config:"
+		printf '%s\n' "For $i-common.config:"
 		cat newconfigs.${i}only
 	done
 	exit 1
@@ -1407,6 +1436,9 @@ for a in arm arm64 i386 x86_64; do
 					[ "$a" != "x86_64" ] && continue
 					SARCH=x86
 					;;
+				riscv*)
+					SARCH=riscv
+					;;
 				*)
 					[ "$a" != "$TripletArch" ] && continue
 					;;
@@ -1428,9 +1460,9 @@ CreateKernel server
 %endif
 
 # how to build own flavour
-# %if %build_nrjQL_desktop
+# if %build_nrjQL_desktop
 # CreateKernel nrjQL-desktop
-# %endif
+# endif
 
 # set extraversion to match srpm to get nice version reported by the tools
 sed -ri "s|^(EXTRAVERSION =).*|\1 -%{rpmrel}|" Makefile
@@ -1486,44 +1518,6 @@ install -m 644 %{SOURCE4} .
 rm -rf %{buildroot}
 cp -a %{temp_root} %{buildroot}
 
-# Create directories infastructure
-%if %{with build_source}
-install -d %{target_source}
-tar cf - . | tar xf - -C %{target_source}
-chmod -R a+rX %{target_source}
-
-# File lists aren't needed
-rm -f %{target_source}/*_files.* %{target_source}/README.kernel-sources
-
-# we remove all the source files that we don't ship
-# first architecture files
-for i in alpha arc avr32 blackfin c6x cris frv h8300 hexagon ia64 m32r m68k m68knommu metag microblaze \
-	 mips nios2 openrisc parisc powerpc riscv s390 score sh sh64 sparc tile unicore32 v850 xtensa mn10300; do
-	rm -rf %{target_source}/arch/$i
-done
-%ifnarch %{arm}
-    rm -rf %{target_source}/include/kvm/arm*
-%endif
-
-# other misc files
-rm -f %{target_source}/{.config.old,.config.cmd,.gitignore,.lst,.mailmap,.gitattributes}
-rm -f %{target_source}/{.missing-syscalls.d,arch/.gitignore,firmware/.gitignore}
-rm -rf %{target_source}/.tmp_depmod/
-
-# more cleaning
-cd %{target_source}
-# lots of gitignore files
-find -iname ".gitignore" -delete
-# clean tools tree
-%smake -C tools clean
-%smake -C tools/build clean
-%smake -C tools/build/feature clean
-rm -f .cache.mk
-cd -
-
-#endif %{with build_source}
-%endif
-
 # compressing modules
 %if %{with build_modxz}
 %ifarch %{ix86} %{armx}
@@ -1535,6 +1529,14 @@ find %{target_modules} -name "*.ko" | %kxargs xz -7 -T0
 find %{target_modules} -name "*.ko" | %kxargs gzip -9
 %endif
 
+#if %{with build_modzstd}
+#ifarch %{ix86} %{armx}
+#find %{target_modules} -name "*.ko" | %kxargs zstd -10 -q -T0 --rm
+#else
+#find %{target_modules} -name "*.ko" | %kxargs zstd -15 -q -T0 --rm
+#endif
+#endif
+
 # We used to have a copy of PrepareKernel here
 # Now, we make sure that the thing in the linux dir is what we want it to be
 for i in %{target_modules}/*; do
@@ -1550,9 +1552,9 @@ for i in *; do
 done
 
 for i in *; do
-    pushd "$i"
+    pushd $i
     printf '%s\n' "Creating modules.description for $i"
-    modules=$(find . -name "*.ko.[gx]z")
+    modules=$(find . -name "*.ko.[gxz]*[z|st]")
     echo $modules | %kxargs /sbin/modinfo | perl -lne 'print "$name\t$1" if $name && /^description:\s*(.*)/; $name = $1 if m!^filename:\s*(.*)\.k?o!; $name =~ s!.*/!!' > modules.description
     popd
 done
@@ -1560,8 +1562,8 @@ popd
 
 # need to set extraversion to match srpm again to avoid rebuild
 sed -ri "s|^(EXTRAVERSION =).*|\1 -%{rpmrel}|" Makefile
-
 %if %{with build_perf}
+
 # perf tool binary and supporting scripts/binaries
 make -C tools/perf -s CC=%{__cc} V=1 DESTDIR=%{buildroot} WERROR=0 PYTHON=%{__python2} HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} install
 
@@ -1596,6 +1598,52 @@ mkdir -p %{buildroot}%{_bindir} %{buildroot}%{_mandir}/man8
 %endif
 %endif
 
+# Create directories infastructure
+%if %{with build_source}
+install -d %{target_source}
+
+# Package what remains
+tar cf - . | tar xf - -C %{target_source}
+chmod -R a+rX %{target_source}
+
+rm %{target_source}/*.lang
+
+# File lists aren't needed
+rm -f %{target_source}/*_files.* %{target_source}/README.kernel-sources
+
+# we remove all the source files that we don't ship
+# first architecture files
+for i in alpha arc avr32 blackfin c6x cris frv h8300 hexagon ia64 m32r m68k m68knommu metag microblaze \
+    mips nios2 openrisc parisc powerpc s390 score sh sh64 sparc tile unicore32 v850 xtensa mn10300; do
+    rm -rf %{target_source}/arch/$i
+done
+
+# other misc files
+rm -f %{target_source}/{.config.old,.config.cmd,.gitignore,.lst,.mailmap,.gitattributes}
+rm -f %{target_source}/{.missing-syscalls.d,arch/.gitignore,firmware/.gitignore}
+rm -rf %{target_source}/.tmp_depmod/
+
+# more cleaning
+cd %{target_source}
+# lots of gitignore files
+find -iname ".gitignore" -delete
+# clean tools tree
+%smake -C tools clean
+%smake -C tools/build clean
+%smake -C tools/build/feature clean
+rm -f .cache.mk
+# Drop script binaries that can be rebuilt
+find tools scripts -executable |while read r; do
+    if file $r |grep -q ELF; then
+	rm -f $r
+    fi
+done
+cd -
+
+#endif %{with build_source}
+%endif
+
+
 ############################################################
 ### Linker start4 > Check point to build for omv or rosa ###
 ############################################################
@@ -1612,6 +1660,7 @@ mkdir -p %{buildroot}%{_bindir} %{buildroot}%{_mandir}/man8
 %{_kerneldir}/arch/Kconfig
 %{_kerneldir}/arch/arm
 %{_kerneldir}/arch/arm64
+%{_kerneldir}/arch/riscv
 %{_kerneldir}/arch/um
 %{_kerneldir}/arch/x86
 %{_kerneldir}/block
@@ -1662,6 +1711,7 @@ mkdir -p %{buildroot}%{_bindir} %{buildroot}%{_mandir}/man8
 %{_kerneldir}/CREDITS
 %{_kerneldir}/Kbuild
 %{_kerneldir}/Kconfig
+%{_kerneldir}/LICENSES
 %{_kerneldir}/MAINTAINERS
 %{_kerneldir}/Makefile
 %{_kerneldir}/README
diff --git a/nouveau-pascal-backlight.patch b/nouveau-pascal-backlight.patch
new file mode 100644
index 0000000..754d982
--- /dev/null
+++ b/nouveau-pascal-backlight.patch
@@ -0,0 +1,11 @@
+diff -up linux-4.16/drivers/gpu/drm/nouveau/nouveau_backlight.c.omv~ linux-4.16/drivers/gpu/drm/nouveau/nouveau_backlight.c
+--- linux-4.16/drivers/gpu/drm/nouveau/nouveau_backlight.c.omv~	2018-04-06 01:04:34.573357055 +0200
++++ linux-4.16/drivers/gpu/drm/nouveau/nouveau_backlight.c	2018-04-06 01:05:46.985579248 +0200
+@@ -287,6 +287,7 @@ nouveau_backlight_init(struct drm_device
+ 		case NV_DEVICE_INFO_V0_FERMI:
+ 		case NV_DEVICE_INFO_V0_KEPLER:
+ 		case NV_DEVICE_INFO_V0_MAXWELL:
++		case NV_DEVICE_INFO_V0_PASCAL:
+ 			return nv50_backlight_init(connector);
+ 		default:
+ 			break;
diff --git a/saa716x-driver-integration.patch b/saa716x-driver-integration.patch
index bb17092..5f52477 100644
--- a/saa716x-driver-integration.patch
+++ b/saa716x-driver-integration.patch
@@ -1,13 +1,6 @@
---- linux-4.12/drivers/media/pci/saa716x/saa716x_pci.c.omv~	2017-08-17 21:26:53.478283067 +0200
-+++ linux-4.12/drivers/media/pci/saa716x/saa716x_pci.c	2017-08-17 21:27:06.915275600 +0200
-@@ -1,3 +1,4 @@
-+#include <linux/spinlock.h>
- #include <asm/io.h>
- #include <asm/pgtable.h>
- #include <asm/page.h>
---- linux-4.12/drivers/media/dvb-frontends/Kconfig.omv~	2017-08-18 02:41:52.026404582 +0200
-+++ linux-4.12/drivers/media/dvb-frontends/Kconfig	2017-08-18 02:46:38.007922490 +0200
-@@ -789,6 +789,13 @@ config DVB_ISL6421
+--- linux-4.15/drivers/media/dvb-frontends/Kconfig.0145~	2018-02-12 11:36:11.230946240 +0100
++++ linux-4.15/drivers/media/dvb-frontends/Kconfig	2018-02-12 11:36:11.311946764 +0100
+@@ -817,6 +817,13 @@ config DVB_ISL6421
  	help
  	  An SEC control chip.
  
@@ -21,7 +14,7 @@
  config DVB_ISL6423
  	tristate "ISL6423 SEC controller"
  	depends on DVB_CORE && I2C
-@@ -870,6 +877,21 @@ config DVB_AF9033
+@@ -898,6 +905,21 @@ config DVB_AF9033
  	select REGMAP_I2C
  	default m if !MEDIA_SUBDRV_AUTOSELECT
  
@@ -43,8 +36,8 @@
  config DVB_HORUS3A
  	tristate "Sony Horus3A tuner"
  	depends on DVB_CORE && I2C
---- linux-4.12/drivers/media/dvb-frontends/Makefile.omv~	2017-08-18 02:41:29.266442339 +0200
-+++ linux-4.12/drivers/media/dvb-frontends/Makefile	2017-08-18 02:45:21.472052705 +0200
+--- linux-4.15/drivers/media/dvb-frontends/Makefile.0145~	2018-02-12 11:36:11.230946240 +0100
++++ linux-4.15/drivers/media/dvb-frontends/Makefile	2018-02-12 11:36:11.311946764 +0100
 @@ -98,6 +98,7 @@ obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
  obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
  obj-$(CONFIG_DVB_MN88472) += mn88472.o
@@ -53,7 +46,7 @@
  obj-$(CONFIG_DVB_ISL6423) += isl6423.o
  obj-$(CONFIG_DVB_EC100) += ec100.o
  obj-$(CONFIG_DVB_DS3000) += ds3000.o
-@@ -123,6 +124,7 @@ obj-$(CONFIG_DVB_AF9033) += af9033.o
+@@ -126,6 +127,7 @@ obj-$(CONFIG_DVB_AF9033) += af9033.o
  obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
  obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
  obj-$(CONFIG_DVB_TC90522) += tc90522.o
@@ -61,17 +54,24 @@
  obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
  obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
  obj-$(CONFIG_DVB_HELENE) += helene.o
---- linux-4.12/drivers/media/pci/saa716x/Makefile.omv~	2017-08-18 02:31:50.197351755 +0200
-+++ linux-4.12/drivers/media/pci/saa716x/Makefile	2017-08-18 02:32:17.255308528 +0200
+--- linux-4.15/drivers/media/pci/saa716x/Makefile.0145~	2018-02-12 11:26:41.101399793 +0100
++++ linux-4.15/drivers/media/pci/saa716x/Makefile	2018-02-12 11:36:11.311946764 +0100
 @@ -27,4 +27,4 @@ obj-$(CONFIG_DVB_SAA716X_BUDGET)  += saa
  obj-$(CONFIG_DVB_SAA716X_HYBRID)  += saa716x_hybrid.o
  obj-$(CONFIG_DVB_SAA716X_FF)	  += saa716x_ff.o
  
 -EXTRA_CFLAGS = -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ -Idrivers/media/tuners/
 +EXTRA_CFLAGS = -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ -Idrivers/media/tuners/ -Idrivers/media/pci/ttpci
---- linux-4.12/drivers/media/tuners/Kconfig.omv~	2017-08-18 02:47:44.578808669 +0200
-+++ linux-4.12/drivers/media/tuners/Kconfig	2017-08-18 02:49:58.991577524 +0200
-@@ -291,4 +291,18 @@ config MEDIA_TUNER_QM1D1C0042
+--- linux-4.15/drivers/media/pci/saa716x/saa716x_pci.c.0145~	2018-02-12 11:26:41.105399834 +0100
++++ linux-4.15/drivers/media/pci/saa716x/saa716x_pci.c	2018-02-12 11:36:11.311946764 +0100
+@@ -1,3 +1,4 @@
++#include <linux/spinlock.h>
+ #include <asm/io.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+--- linux-4.15/drivers/media/tuners/Kconfig.0145~	2018-02-12 11:36:11.238946291 +0100
++++ linux-4.15/drivers/media/tuners/Kconfig	2018-02-12 11:36:11.311946764 +0100
+@@ -298,4 +298,18 @@ config MEDIA_TUNER_QM1D1C0042
  	default m if !MEDIA_SUBDRV_AUTOSELECT
  	help
  	  Sharp QM1D1C0042 trellis coded 8PSK tuner driver.
@@ -90,19 +90,18 @@
 +	help
 +	  ST Microelectronics STV6120 dual silicon tuner driver.
  endmenu
---- linux-4.12/drivers/media/tuners/Makefile.omv~	2017-08-18 02:46:50.034901964 +0200
-+++ linux-4.12/drivers/media/tuners/Makefile	2017-08-18 02:47:41.783813458 +0200
-@@ -41,6 +41,8 @@ obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t
- obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o
- obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o
+--- linux-4.15/drivers/media/tuners/Makefile.0145~	2018-02-12 11:36:11.311946764 +0100
++++ linux-4.15/drivers/media/tuners/Makefile	2018-02-12 12:30:29.572145559 +0100
+@@ -44,5 +44,7 @@ obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) +=
  obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o
+ obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
+ obj-$(CONFIG_MEDIA_TUNER_SILABS_TERCAB) += silabs_tercab.o
 +obj-$(CONFIG_MEDIA_TUNER_AV201X) += av201x.o
 +obj-$(CONFIG_MEDIA_TUNER_STV6120) += stv6120.o
- obj-$(CONFIG_MEDIA_TUNER_SILABS_TERCAB) += silabs_tercab.o
  
- ccflags-y += -I$(srctree)/drivers/media/dvb-core
---- linux-4.12/drivers/media/tuners/tda18212.c.omv~	2017-08-18 02:34:52.651077211 +0200
-+++ linux-4.12/drivers/media/tuners/tda18212.c	2017-08-18 02:35:01.360063881 +0200
+ ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
+--- linux-4.15/drivers/media/tuners/tda18212.c.0145~	2018-02-12 11:36:11.260946434 +0100
++++ linux-4.15/drivers/media/tuners/tda18212.c	2018-02-12 11:36:11.312946771 +0100
 @@ -153,7 +153,7 @@ static int tda18212_set_params(struct dv
  
  	buf[0] = 0x02;
diff --git a/uksm-4.15.patch b/uksm-4.16.patch
similarity index 99%
rename from uksm-4.15.patch
rename to uksm-4.16.patch
index e84093f..363a215 100644
--- a/uksm-4.15.patch
+++ b/uksm-4.16.patch
@@ -1,5 +1,5 @@
 diff --git a/Documentation/vm/00-INDEX b/Documentation/vm/00-INDEX
-index 11d3d8dcb449..5269998fef8a 100644
+index 11d3d8dcb..5269998fe 100644
 --- a/Documentation/vm/00-INDEX
 +++ b/Documentation/vm/00-INDEX
 @@ -20,6 +20,8 @@ idle_page_tracking.txt
@@ -13,7 +13,7 @@ index 11d3d8dcb449..5269998fef8a 100644
  numa_memory_policy.txt
 diff --git a/Documentation/vm/uksm.txt b/Documentation/vm/uksm.txt
 new file mode 100644
-index 000000000000..be19a3127001
+index 000000000..be19a3127
 --- /dev/null
 +++ b/Documentation/vm/uksm.txt
 @@ -0,0 +1,61 @@
@@ -79,7 +79,7 @@ index 000000000000..be19a3127001
 +2016-09-10 UKSM 0.1.2.5 Fix a bug in dedup ratio calculation.
 +2017-02-26 UKSM 0.1.2.6 Fix a bug in hugetlbpage handling and a race bug with page migration.
 diff --git a/fs/exec.c b/fs/exec.c
-index 7eb8d21bcab9..bcd4e80a7eca 100644
+index 7eb8d21bc..bcd4e80a7 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -62,6 +62,7 @@
@@ -99,7 +99,7 @@ index 7eb8d21bcab9..bcd4e80a7eca 100644
  }
  EXPORT_SYMBOL(setup_new_exec);
 diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
-index 6bb20f864259..3208972b4752 100644
+index 6bb20f864..3208972b4 100644
 --- a/fs/proc/meminfo.c
 +++ b/fs/proc/meminfo.c
 @@ -118,6 +118,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
@@ -114,10 +114,10 @@ index 6bb20f864259..3208972b4752 100644
  	show_val_kb(m, "Quicklists:     ", quicklist_total_size());
  #endif
 diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
-index 868e68561f91..7b8c119bbbdf 100644
+index bfbb44a5a..8dcd7f167 100644
 --- a/include/asm-generic/pgtable.h
 +++ b/include/asm-generic/pgtable.h
-@@ -774,12 +774,25 @@ extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+@@ -781,12 +781,25 @@ extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
  extern void untrack_pfn_moved(struct vm_area_struct *vma);
  #endif
  
@@ -144,7 +144,7 @@ index 868e68561f91..7b8c119bbbdf 100644
  }
  
  #define my_zero_pfn(addr)	page_to_pfn(ZERO_PAGE(addr))
-@@ -788,7 +801,7 @@ static inline int is_zero_pfn(unsigned long pfn)
+@@ -795,7 +808,7 @@ static inline int is_zero_pfn(unsigned long pfn)
  static inline int is_zero_pfn(unsigned long pfn)
  {
  	extern unsigned long zero_pfn;
@@ -154,7 +154,7 @@ index 868e68561f91..7b8c119bbbdf 100644
  
  static inline unsigned long my_zero_pfn(unsigned long addr)
 diff --git a/include/linux/ksm.h b/include/linux/ksm.h
-index 44368b19b27e..0ae04f09f48d 100644
+index 44368b19b..0ae04f09f 100644
 --- a/include/linux/ksm.h
 +++ b/include/linux/ksm.h
 @@ -21,21 +21,6 @@ struct mem_cgroup;
@@ -221,10 +221,10 @@ index 44368b19b27e..0ae04f09f48d 100644
 +
  #endif /* __LINUX_KSM_H */
 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index cfd0ac4e5e0e..bd1077512bae 100644
+index fd1af6b95..8387d696d 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -339,6 +339,9 @@ struct vm_area_struct {
+@@ -333,6 +333,9 @@ struct vm_area_struct {
  	struct mempolicy *vm_policy;	/* NUMA policy for the VMA */
  #endif
  	struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
@@ -235,7 +235,7 @@ index cfd0ac4e5e0e..bd1077512bae 100644
  
  struct core_thread {
 diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
-index 67f2e3c38939..7566e28c72ad 100644
+index 7522a6987..58a55ff22 100644
 --- a/include/linux/mmzone.h
 +++ b/include/linux/mmzone.h
 @@ -148,6 +148,9 @@ enum zone_stat_item {
@@ -259,7 +259,7 @@ index 67f2e3c38939..7566e28c72ad 100644
   * @zone - pointer to struct zone variable
 diff --git a/include/linux/sradix-tree.h b/include/linux/sradix-tree.h
 new file mode 100644
-index 000000000000..d71edba6b63f
+index 000000000..d71edba6b
 --- /dev/null
 +++ b/include/linux/sradix-tree.h
 @@ -0,0 +1,77 @@
@@ -342,7 +342,7 @@ index 000000000000..d71edba6b63f
 +#endif /* _LINUX_SRADIX_TREE_H */
 diff --git a/include/linux/uksm.h b/include/linux/uksm.h
 new file mode 100644
-index 000000000000..bb8651f534f2
+index 000000000..bb8651f53
 --- /dev/null
 +++ b/include/linux/uksm.h
 @@ -0,0 +1,149 @@
@@ -496,10 +496,10 @@ index 000000000000..bb8651f534f2
 +#endif /* !CONFIG_UKSM */
 +#endif /* __LINUX_UKSM_H */
 diff --git a/kernel/fork.c b/kernel/fork.c
-index 2295fc69717f..43262fe664a0 100644
+index e5d9d405a..6dec8b7ad 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -650,7 +650,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
+@@ -448,7 +448,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
  				goto fail_nomem;
  			charge = len;
  		}
@@ -508,7 +508,7 @@ index 2295fc69717f..43262fe664a0 100644
  		if (!tmp)
  			goto fail_nomem;
  		*tmp = *mpnt;
-@@ -709,7 +709,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
+@@ -507,7 +507,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
  		__vma_link_rb(mm, tmp, rb_link, rb_parent);
  		rb_link = &tmp->vm_rb.rb_right;
  		rb_parent = &tmp->vm_rb;
@@ -518,7 +518,7 @@ index 2295fc69717f..43262fe664a0 100644
  		if (!(tmp->vm_flags & VM_WIPEONFORK))
  			retval = copy_page_range(mm, oldmm, mpnt);
 diff --git a/lib/Makefile b/lib/Makefile
-index d11c48ec8ffd..fb69ccafa8b5 100644
+index a90d4fcd7..3a3be2029 100644
 --- a/lib/Makefile
 +++ b/lib/Makefile
 @@ -18,7 +18,7 @@ KCOV_INSTRUMENT_debugobjects.o := n
@@ -532,7 +532,7 @@ index d11c48ec8ffd..fb69ccafa8b5 100644
  	 flex_proportions.o ratelimit.o show_mem.o \
 diff --git a/lib/sradix-tree.c b/lib/sradix-tree.c
 new file mode 100644
-index 000000000000..ab21e6309b93
+index 000000000..ab21e6309
 --- /dev/null
 +++ b/lib/sradix-tree.c
 @@ -0,0 +1,476 @@
@@ -1013,7 +1013,7 @@ index 000000000000..ab21e6309b93
 +	return 0;
 +}
 diff --git a/mm/Kconfig b/mm/Kconfig
-index 03ff7703d322..3958bef82b50 100644
+index c782e8fb7..396522f2a 100644
 --- a/mm/Kconfig
 +++ b/mm/Kconfig
 @@ -315,6 +315,32 @@ config KSM
@@ -1050,7 +1050,7 @@ index 03ff7703d322..3958bef82b50 100644
  config DEFAULT_MMAP_MIN_ADDR
          int "Low address space to protect from user allocation"
 diff --git a/mm/Makefile b/mm/Makefile
-index e669f02c5a54..e2695e9a21c2 100644
+index e669f02c5..e2695e9a2 100644
 --- a/mm/Makefile
 +++ b/mm/Makefile
 @@ -65,7 +65,8 @@ obj-$(CONFIG_SPARSEMEM)	+= sparse.o
@@ -1064,10 +1064,10 @@ index e669f02c5a54..e2695e9a21c2 100644
  obj-$(CONFIG_SLAB) += slab.o
  obj-$(CONFIG_SLUB) += slub.o
 diff --git a/mm/memory.c b/mm/memory.c
-index 793004608332..c981d26e3d7d 100644
+index 5fcfc2490..211a4ce99 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -129,6 +129,25 @@ EXPORT_SYMBOL(zero_pfn);
+@@ -128,6 +128,25 @@ EXPORT_SYMBOL(zero_pfn);
  
  unsigned long highest_memmap_pfn __read_mostly;
  
@@ -1093,7 +1093,7 @@ index 793004608332..c981d26e3d7d 100644
  /*
   * CONFIG_MMU architectures set up ZERO_PAGE in their paging_init()
   */
-@@ -140,6 +159,7 @@ static int __init init_zero_pfn(void)
+@@ -139,6 +158,7 @@ static int __init init_zero_pfn(void)
  core_initcall(init_zero_pfn);
  
  
@@ -1101,7 +1101,7 @@ index 793004608332..c981d26e3d7d 100644
  #if defined(SPLIT_RSS_COUNTING)
  
  void sync_mm_rss(struct mm_struct *mm)
-@@ -1036,6 +1056,9 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+@@ -1039,6 +1059,9 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
  		get_page(page);
  		page_dup_rmap(page, false);
  		rss[mm_counter(page)]++;
@@ -1111,7 +1111,7 @@ index 793004608332..c981d26e3d7d 100644
  	} else if (pte_devmap(pte)) {
  		page = pte_page(pte);
  
-@@ -1049,6 +1072,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+@@ -1052,6 +1075,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
  			page_dup_rmap(page, false);
  			rss[mm_counter(page)]++;
  		}
@@ -1120,7 +1120,7 @@ index 793004608332..c981d26e3d7d 100644
  	}
  
  out_set_pte:
-@@ -1318,8 +1343,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+@@ -1321,8 +1346,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
  			ptent = ptep_get_and_clear_full(mm, addr, pte,
  							tlb->fullmm);
  			tlb_remove_tlb_entry(tlb, pte, addr);
@@ -1132,7 +1132,7 @@ index 793004608332..c981d26e3d7d 100644
  
  			if (!PageAnon(page)) {
  				if (pte_dirty(ptent)) {
-@@ -2319,8 +2346,10 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
+@@ -2336,8 +2363,10 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
  			clear_page(kaddr);
  		kunmap_atomic(kaddr);
  		flush_dcache_page(dst);
@@ -1144,7 +1144,7 @@ index 793004608332..c981d26e3d7d 100644
  }
  
  static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma)
-@@ -2469,6 +2498,7 @@ static int wp_page_copy(struct vm_fault *vmf)
+@@ -2486,6 +2515,7 @@ static int wp_page_copy(struct vm_fault *vmf)
  							      vmf->address);
  		if (!new_page)
  			goto oom;
@@ -1152,7 +1152,7 @@ index 793004608332..c981d26e3d7d 100644
  	} else {
  		new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
  				vmf->address);
-@@ -2495,7 +2525,9 @@ static int wp_page_copy(struct vm_fault *vmf)
+@@ -2512,7 +2542,9 @@ static int wp_page_copy(struct vm_fault *vmf)
  						mm_counter_file(old_page));
  				inc_mm_counter_fast(mm, MM_ANONPAGES);
  			}
@@ -1163,7 +1163,7 @@ index 793004608332..c981d26e3d7d 100644
  		}
  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 diff --git a/mm/mmap.c b/mm/mmap.c
-index 9efdc021ad22..919ad70a7fa3 100644
+index 9efdc021a..919ad70a7 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
 @@ -45,6 +45,7 @@
@@ -1323,7 +1323,7 @@ index 9efdc021ad22..919ad70a7fa3 100644
  	return vma;
  
 diff --git a/mm/rmap.c b/mm/rmap.c
-index 47db27f8049e..fdd0fd74236d 100644
+index 47db27f80..fdd0fd742 100644
 --- a/mm/rmap.c
 +++ b/mm/rmap.c
 @@ -1016,9 +1016,9 @@ void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
@@ -1340,7 +1340,7 @@ index 47db27f8049e..fdd0fd74236d 100644
  static void __page_set_anon_rmap(struct page *page,
 diff --git a/mm/uksm.c b/mm/uksm.c
 new file mode 100644
-index 000000000000..48ddb7460ca6
+index 000000000..48ddb7460
 --- /dev/null
 +++ b/mm/uksm.c
 @@ -0,0 +1,5584 @@
@@ -6929,7 +6929,7 @@ index 000000000000..48ddb7460ca6
 +#endif
 +
 diff --git a/mm/vmstat.c b/mm/vmstat.c
-index 40b2db6db6b1..6ff75d0b399d 100644
+index 33581be70..f2eb7b480 100644
 --- a/mm/vmstat.c
 +++ b/mm/vmstat.c
 @@ -1162,6 +1162,9 @@ const char * const vmstat_text[] = {
diff --git a/v2-1-2-lib-Add-support-for-ZSTD-compressed-kernel.patch b/v2-1-2-lib-Add-support-for-ZSTD-compressed-kernel.patch
new file mode 100644
index 0000000..becf4cf
--- /dev/null
+++ b/v2-1-2-lib-Add-support-for-ZSTD-compressed-kernel.patch
@@ -0,0 +1,721 @@
+diff --git a/include/linux/decompress/unzstd.h b/include/linux/decompress/unzstd.h
+new file mode 100644
+index 0000000..6f3022c
+--- /dev/null
++++ b/include/linux/decompress/unzstd.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2017 Facebook
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public
++ * License v2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
++ */
++
++#ifndef LINUX_DECOMPRESS_UNZSTD_H
++#define LINUX_DECOMPRESS_UNZSTD_H
++
++int unzstd(unsigned char *inbuf, long len,
++	   long (*fill)(void*, unsigned long),
++	   long (*flush)(void*, unsigned long),
++	   unsigned char *output,
++	   long *pos,
++	   void (*error_fn)(char *x));
++#endif
+diff --git a/init/Kconfig b/init/Kconfig
+index 78cb246..3caa314 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -127,10 +127,13 @@ config HAVE_KERNEL_LZO
+ config HAVE_KERNEL_LZ4
+ 	bool
+ 
++config HAVE_KERNEL_ZSTD
++	bool
++
+ choice
+ 	prompt "Kernel compression mode"
+ 	default KERNEL_GZIP
+-	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4
++	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 || HAVE_KERNEL_ZSTD
+ 	help
+ 	  The linux kernel is a kind of self-extracting executable.
+ 	  Several compression algorithms are available, which differ
+@@ -209,6 +212,15 @@ config KERNEL_LZ4
+ 	  is about 8% bigger than LZO. But the decompression speed is
+ 	  faster than LZO.
+ 
++config KERNEL_ZSTD
++	bool "ZSTD"
++	depends on HAVE_KERNEL_ZSTD
++	help
++	  ZSTD is a compression algorithm targeting intermediate compression
++	  with fast decompression speed. It will compress better than GZIP and
++	  decompress around the same speed as LZO, but slower than LZ4. You
++	  will need at least 192 KB RAM or more for booting.
++
+ endchoice
+ 
+ config DEFAULT_HOSTNAME
+diff --git a/lib/Kconfig b/lib/Kconfig
+index b1445b2..4d32bec 100644
+--- a/lib/Kconfig
++++ b/lib/Kconfig
+@@ -285,6 +285,10 @@ config DECOMPRESS_LZ4
+ 	select LZ4_DECOMPRESS
+ 	tristate
+ 
++config DECOMPRESS_ZSTD
++	select ZSTD_DECOMPRESS
++	tristate
++
+ #
+ # Generic allocator support is selected if needed
+ #
+diff --git a/lib/Makefile b/lib/Makefile
+index dafa796..8afcdc3 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -128,6 +128,7 @@ lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
+ lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
+ lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
+ lib-$(CONFIG_DECOMPRESS_LZ4) += decompress_unlz4.o
++lib-$(CONFIG_DECOMPRESS_ZSTD) += decompress_unzstd.o
+ 
+ obj-$(CONFIG_TEXTSEARCH) += textsearch.o
+ obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
+diff --git a/lib/decompress.c b/lib/decompress.c
+index 62696df..b17bb07 100644
+--- a/lib/decompress.c
++++ b/lib/decompress.c
+@@ -12,6 +12,7 @@
+ #include <linux/decompress/inflate.h>
+ #include <linux/decompress/unlzo.h>
+ #include <linux/decompress/unlz4.h>
++#include <linux/decompress/unzstd.h>
+ 
+ #include <linux/types.h>
+ #include <linux/string.h>
+@@ -36,6 +37,9 @@
+ #ifndef CONFIG_DECOMPRESS_LZ4
+ # define unlz4 NULL
+ #endif
++#ifndef CONFIG_DECOMPRESS_ZSTD
++# define unzstd NULL
++#endif
+ 
+ struct compress_format {
+ 	unsigned char magic[2];
+@@ -51,6 +55,7 @@ static const struct compress_format compressed_formats[] __initconst = {
+ 	{ {0xfd, 0x37}, "xz", unxz },
+ 	{ {0x89, 0x4c}, "lzo", unlzo },
+ 	{ {0x02, 0x21}, "lz4", unlz4 },
++	{ {0x28, 0xb5}, "zstd", unzstd },
+ 	{ {0, 0}, NULL, NULL }
+ };
+ 
+diff --git a/lib/decompress_unzstd.c b/lib/decompress_unzstd.c
+new file mode 100644
+index 0000000..84315dc
+--- /dev/null
++++ b/lib/decompress_unzstd.c
+@@ -0,0 +1,341 @@
++/*
++ * Copyright (C) 2017 Facebook
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public
++ * License v2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
++ */
++
++/*
++ * Important notes about in-place decompression
++ *
++ * At least on x86, the kernel is decompressed in place: the compressed data
++ * is placed to the end of the output buffer, and the decompressor overwrites
++ * most of the compressed data. There must be enough safety margin to
++ * guarantee that the write position is always behind the read position.
++ *
++ * The safety margin for ZSTD with a 128 KB block size is calculated below.
++ * Note that the margin with ZSTD is bigger than with GZIP or XZ!
++ *
++ * The worst case for in-place decompression is that the beginning of
++ * the file is compressed extremely well, and the rest of the file is
++ * uncompressible. Thus, we must look for worst-case expansion when the
++ * compressor is encoding uncompressible data.
++ *
++ * The structure of the .zst file in case of a compresed kernel is as follows.
++ * Maximum sizes (as bytes) of the fields are in parenthesis.
++ *
++ *    Frame Header: (18)
++ *    Blocks: (N)
++ *    Checksum: (4)
++ *
++ * The frame header and checksum overhead is at most 22 bytes.
++ *
++ * ZSTD stores the data in blocks. Each block has a header whose size is
++ * a 3 bytes. After the block header, there is up to 128 KB of payload.
++ * The maximum uncompressed size of the payload is 128 KB. The minimum
++ * uncompressed size of the payload is never less than the payload size
++ * (excluding the block header).
++ *
++ * The assumption, that the uncompressed size of the payload is never
++ * smaller than the payload itself, is valid only when talking about
++ * the payload as a whole. It is possible that the payload has parts where
++ * the decompressor consumes more input than it produces output. Calculating
++ * the worst case for this would be tricky. Instead of trying to do that,
++ * let's simply make sure that the decompressor never overwrites any bytes
++ * of the payload which it is currently reading.
++ *
++ * Now we have enough information to calculate the safety margin. We need
++ *   - 22 bytes for the .zst file format headers;
++ *   - 3 bytes per every 128 KiB of uncompressed size (one block header per
++ *     block); and
++ *   - 128 KiB (biggest possible zstd block size) to make sure that the
++ *     decompressor never overwrites anything from the block it is currently
++ *     reading.
++ *
++ * We get the following formula:
++ *
++ *    safety_margin = 22 + uncompressed_size * 3 / 131072 + 131072
++ *                 <= 22 + (uncompressed_size >> 15) + 131072
++ */
++
++#ifdef STATIC
++	/* Preboot environments #include "path/to/decompress_unzstd.c".
++	 * All of the source files we depend on must be #included.
++	 * zstd's only source dependeny is xxhash, which has no source
++	 * dependencies.
++	 *
++	 * zstd and xxhash both avoid declaring themselves as modules
++	 * when PREBOOT is defined.
++	 */
++#	define PREBOOT
++#	include "xxhash.c"
++#	include "zstd/entropy_common.c"
++#	include "zstd/fse_decompress.c"
++#	include "zstd/huf_decompress.c"
++#	include "zstd/zstd_common.c"
++#	include "zstd/decompress.c"
++#endif
++
++#include <linux/decompress/mm.h>
++#include <linux/kernel.h>
++#include <linux/zstd.h>
++
++/* 8 MB maximum window size */
++#define ZSTD_WINDOWSIZE_MAX	(1 << 23)
++/* Size of the input and output buffers in multi-call mdoe */
++#define ZSTD_IOBUF_SIZE		4096
++
++static int INIT handle_zstd_error(size_t ret, void (*error)(char *x))
++{
++	const int err = ZSTD_getErrorCode(ret);
++
++	if (!ZSTD_isError(ret))
++		return 0;
++
++	switch (err) {
++	case ZSTD_error_memory_allocation:
++		error("ZSTD decompressor ran out of memory");
++		break;
++	case ZSTD_error_prefix_unknown:
++		error("Input is not in the ZSTD format (wrong magic bytes)");
++		break;
++	case ZSTD_error_dstSize_tooSmall:
++	case ZSTD_error_corruption_detected:
++	case ZSTD_error_checksum_wrong:
++		error("ZSTD-compressed data is corrupt");
++		break;
++	default:
++		error("ZSTD-compressed data is probably corrupt");
++		break;
++	}
++	return -1;
++}
++
++/* Handle the case where we have the entire input and output in one segment.
++ * We can allocate less memory (no circular buffer for the sliding window),
++ * and avoid some memcpy() calls.
++ */
++static int INIT decompress_single(const u8 *in_buf, long in_len, u8 *out_buf,
++				  long out_len, long *in_pos,
++				  void (*error)(char *x))
++{
++	const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
++	void *wksp = large_malloc(wksp_size);
++	ZSTD_DCtx *dctx = ZSTD_initDCtx(wksp, wksp_size);
++	int err;
++	size_t ret;
++
++	if (dctx == NULL) {
++		error("Out of memory while allocating ZSTD_DCtx");
++		err = -1;
++		goto out;
++	}
++	/* Find out how large the frame actually is, there may be junk at
++	 * the end of the frame that ZSTD_decompressDCtx() can't handle.
++	 */
++	ret = ZSTD_findFrameCompressedSize(in_buf, in_len);
++	err = handle_zstd_error(ret, error);
++	if (err)
++		goto out;
++	in_len = (long)ret;
++
++	ret = ZSTD_decompressDCtx(dctx, out_buf, out_len, in_buf, in_len);
++	err = handle_zstd_error(ret, error);
++	if (err)
++		goto out;
++
++	if (in_pos != NULL)
++		*in_pos = in_len;
++
++	err = 0;
++out:
++	if (wksp != NULL)
++		large_free(wksp);
++	return err;
++}
++
++static int INIT __unzstd(unsigned char *in_buf, long in_len,
++			 long (*fill)(void*, unsigned long),
++			 long (*flush)(void*, unsigned long),
++			 unsigned char *out_buf, long out_len,
++			 long *in_pos,
++			 void (*error)(char *x))
++{
++	ZSTD_inBuffer in;
++	ZSTD_outBuffer out;
++	ZSTD_frameParams params;
++	void *in_allocated = NULL;
++	void *out_allocated = NULL;
++	void *wksp = NULL;
++	size_t wksp_size;
++	ZSTD_DStream *dstream;
++	int err;
++	size_t ret;
++
++	if (out_len == 0)
++		out_len = LONG_MAX; /* no limit */
++
++	if (fill == NULL && flush == NULL)
++		/* We can decompress faster and with less memory when we have a
++		 * single chunk.
++		 */
++		return decompress_single(in_buf, in_len, out_buf, out_len,
++					 in_pos, error);
++
++	/* If in_buf is not provided, we must be using fill(), so allocate
++	 * a large enough buffer. If it is provided, it must be at least
++	 * ZSTD_IOBUF_SIZE large.
++	 */
++	if (in_buf == NULL) {
++		in_allocated = malloc(ZSTD_IOBUF_SIZE);
++		if (in_allocated == NULL) {
++			error("Out of memory while allocating input buffer");
++			err = -1;
++			goto out;
++		}
++		in_buf = in_allocated;
++		in_len = 0;
++	}
++	/* Read the first chunk, since we need to decode the frame header */
++	if (fill != NULL)
++		in_len = fill(in_buf, ZSTD_IOBUF_SIZE);
++	if (in_len < 0) {
++		error("ZSTD-compressed data is truncated");
++		err = -1;
++		goto out;
++	}
++	/* Set the first non-empty input buffer */
++	in.src = in_buf;
++	in.pos = 0;
++	in.size = in_len;
++	/* Allocate the output buffer if we are using flush(). */
++	if (flush != NULL) {
++		out_allocated = malloc(ZSTD_IOBUF_SIZE);
++		if (out_allocated == NULL) {
++			error("Out of memory while allocating output buffer");
++			err = -1;
++			goto out;
++		}
++		out_buf = out_allocated;
++		out_len = ZSTD_IOBUF_SIZE;
++	}
++	/* Set the output buffer */
++	out.dst = out_buf;
++	out.pos = 0;
++	out.size = out_len;
++
++	/* We need to know the window size to allocate the ZSTD_DStream.
++	 * Since we are streaming, we need to allocate a buffer for the sliding
++	 * window. The window size varies from 1 KB to ZSTD_WINDOWSIZE_MAX
++	 * (8 MB), so it is important to use the actual value so as not to
++	 * waste memory when it is smaller.
++	 */
++	ret = ZSTD_getFrameParams(&params, in.src, in.size);
++	err = handle_zstd_error(ret, error);
++	if (err)
++		goto out;
++	if (ret != 0) {
++		error("ZSTD-compressed data has an incomplete frame header");
++		err = -1;
++		goto out;
++	}
++	if (params.windowSize > ZSTD_WINDOWSIZE_MAX) {
++		error("ZSTD-compressed data has too large a window size");
++		err = -1;
++		goto out;
++	}
++
++	/* Allocate the ZSTD_DStream now that we know how much memory is
++	 * required.
++	 */
++	wksp_size = ZSTD_DStreamWorkspaceBound(params.windowSize);
++	wksp = large_malloc(wksp_size);
++	dstream = ZSTD_initDStream(params.windowSize, wksp, wksp_size);
++	if (dstream == NULL) {
++		error("Out of memory while allocating ZSTD_DStream");
++		err = -1;
++		goto out;
++	}
++	/* Decompression loop:
++	 * Read more data if necessary (error if no more data can be read).
++	 * Call the decompression function, which returns 0 when finished.
++	 * Flush any data produced if using flush().
++	 */
++	if (in_pos != NULL)
++		*in_pos = 0;
++	do {
++		/* If we need to reload data, either we have fill() and can
++		 * try to get more data, or we don't and the input is truncated.
++		 */
++		if (in.pos == in.size) {
++			if (in_pos != NULL)
++				*in_pos += in.pos;
++			in_len = fill ? fill(in_buf, ZSTD_IOBUF_SIZE) : -1;
++			if (in_len < 0) {
++				error("ZSTD-compressed data is truncated");
++				err = -1;
++				goto out;
++			}
++			in.pos = 0;
++			in.size = in_len;
++		}
++		/* Returns zero when the frame is complete */
++		ret = ZSTD_decompressStream(dstream, &out, &in);
++		err = handle_zstd_error(ret, error);
++		if (err)
++			goto out;
++		/* Flush all of the data produced if using flush() */
++		if (flush != NULL && out.pos > 0) {
++			if (out.pos != flush(out.dst, out.pos)) {
++				error("Failed to flush()");
++				err = -1;
++				goto out;
++			}
++			out.pos = 0;
++		}
++	} while (ret != 0);
++
++	if (in_pos != NULL)
++		*in_pos += in.pos;
++
++	err = 0;
++out:
++	if (in_allocated != NULL)
++		free(in_allocated);
++	if (out_allocated != NULL)
++		free(out_allocated);
++	if (wksp != NULL)
++		large_free(wksp);
++	return err;
++}
++
++#ifndef PREBOOT
++STATIC int INIT unzstd(unsigned char *buf, long len,
++		       long (*fill)(void*, unsigned long),
++		       long (*flush)(void*, unsigned long),
++		       unsigned char *out_buf,
++		       long *pos,
++		       void (*error)(char *x))
++{
++	return __unzstd(buf, len, fill, flush, out_buf, 0, pos, error);
++}
++#else
++STATIC int INIT __decompress(unsigned char *buf, long len,
++			     long (*fill)(void*, unsigned long),
++			     long (*flush)(void*, unsigned long),
++			     unsigned char *out_buf, long out_len,
++			     long *pos,
++			     void (*error)(char *x))
++{
++	return __unzstd(buf, len, fill, flush, out_buf, out_len, pos, error);
++}
++#endif
+diff --git a/lib/xxhash.c b/lib/xxhash.c
+index aa61e2a..7f1d3cb 100644
+--- a/lib/xxhash.c
++++ b/lib/xxhash.c
+@@ -80,13 +80,11 @@ void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
+ {
+ 	memcpy(dst, src, sizeof(*dst));
+ }
+-EXPORT_SYMBOL(xxh32_copy_state);
+ 
+ void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
+ {
+ 	memcpy(dst, src, sizeof(*dst));
+ }
+-EXPORT_SYMBOL(xxh64_copy_state);
+ 
+ /*-***************************
+  * Simple Hash Functions
+@@ -151,7 +149,6 @@ uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
+ 
+ 	return h32;
+ }
+-EXPORT_SYMBOL(xxh32);
+ 
+ static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
+ {
+@@ -234,7 +231,6 @@ uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
+ 
+ 	return h64;
+ }
+-EXPORT_SYMBOL(xxh64);
+ 
+ /*-**************************************************
+  * Advanced Hash Functions
+@@ -251,7 +247,6 @@ void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
+ 	state.v4 = seed - PRIME32_1;
+ 	memcpy(statePtr, &state, sizeof(state));
+ }
+-EXPORT_SYMBOL(xxh32_reset);
+ 
+ void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
+ {
+@@ -265,7 +260,6 @@ void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
+ 	state.v4 = seed - PRIME64_1;
+ 	memcpy(statePtr, &state, sizeof(state));
+ }
+-EXPORT_SYMBOL(xxh64_reset);
+ 
+ int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
+ {
+@@ -334,7 +328,6 @@ int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
+ 
+ 	return 0;
+ }
+-EXPORT_SYMBOL(xxh32_update);
+ 
+ uint32_t xxh32_digest(const struct xxh32_state *state)
+ {
+@@ -372,7 +365,6 @@ uint32_t xxh32_digest(const struct xxh32_state *state)
+ 
+ 	return h32;
+ }
+-EXPORT_SYMBOL(xxh32_digest);
+ 
+ int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
+ {
+@@ -439,7 +431,6 @@ int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
+ 
+ 	return 0;
+ }
+-EXPORT_SYMBOL(xxh64_update);
+ 
+ uint64_t xxh64_digest(const struct xxh64_state *state)
+ {
+@@ -494,7 +485,19 @@ uint64_t xxh64_digest(const struct xxh64_state *state)
+ 
+ 	return h64;
+ }
++
++#ifndef PREBOOT
++EXPORT_SYMBOL(xxh32_copy_state);
++EXPORT_SYMBOL(xxh64_copy_state);
++EXPORT_SYMBOL(xxh32);
++EXPORT_SYMBOL(xxh64);
++EXPORT_SYMBOL(xxh32_reset);
++EXPORT_SYMBOL(xxh64_reset);
++EXPORT_SYMBOL(xxh32_update);
++EXPORT_SYMBOL(xxh32_digest);
++EXPORT_SYMBOL(xxh64_update);
+ EXPORT_SYMBOL(xxh64_digest);
+ 
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_DESCRIPTION("xxHash");
++#endif
+diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
+index b178467..b7b6599 100644
+--- a/lib/zstd/decompress.c
++++ b/lib/zstd/decompress.c
+@@ -2487,6 +2487,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB
+ 	}
+ }
+ 
++#ifndef PREBOOT
+ EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound);
+ EXPORT_SYMBOL(ZSTD_initDCtx);
+ EXPORT_SYMBOL(ZSTD_decompressDCtx);
+@@ -2526,3 +2527,4 @@ EXPORT_SYMBOL(ZSTD_insertBlock);
+ 
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_DESCRIPTION("Zstd Decompressor");
++#endif
+diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c
+index a84300e..0b35353 100644
+--- a/lib/zstd/fse_decompress.c
++++ b/lib/zstd/fse_decompress.c
+@@ -47,6 +47,7 @@
+ ****************************************************************/
+ #include "bitstream.h"
+ #include "fse.h"
++#include "zstd_internal.h"
+ #include <linux/compiler.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h> /* memcpy, memset */
+@@ -60,14 +61,6 @@
+ 		enum { FSE_static_assert = 1 / (int)(!!(c)) }; \
+ 	} /* use only *after* variable declarations */
+ 
+-/* check and forward error code */
+-#define CHECK_F(f)                  \
+-	{                           \
+-		size_t const e = f; \
+-		if (FSE_isError(e)) \
+-			return e;   \
+-	}
+-
+ /* **************************************************************
+ *  Templates
+ ****************************************************************/
+diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h
+index 1a79fab..40026c0 100644
+--- a/lib/zstd/zstd_internal.h
++++ b/lib/zstd/zstd_internal.h
+@@ -127,7 +127,13 @@ static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
+ *  Shared functions to include for inlining
+ *********************************************/
+ ZSTD_STATIC void ZSTD_copy8(void *dst, const void *src) {
+-	memcpy(dst, src, 8);
++	/* zstd relies heavily on gcc being able to analyze and inline this
++	 * memcpy() call, since it is called in a tight loop. Preboot mode
++	 * is compiled in freestanding mode, which stops gcc from analyzing
++	 * memcpy(). Use __builtin_memcpy() to tell gcc to analyze this as a
++	 * regular memcpy().
++	 */
++	__builtin_memcpy(dst, src, 8);
+ }
+ /*! ZSTD_wildcopy() :
+ *   custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
+@@ -137,6 +143,7 @@ ZSTD_STATIC void ZSTD_wildcopy(void *dst, const void *src, ptrdiff_t length)
+ 	const BYTE* ip = (const BYTE*)src;
+ 	BYTE* op = (BYTE*)dst;
+ 	BYTE* const oend = op + length;
++#if GCC_VERSION >= 70000 && GCC_VERSION < 70200
+ 	/* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388.
+ 	 * Avoid the bad case where the loop only runs once by handling the
+ 	 * special case separately. This doesn't trigger the bug because it
+@@ -144,6 +151,7 @@ ZSTD_STATIC void ZSTD_wildcopy(void *dst, const void *src, ptrdiff_t length)
+ 	 */
+ 	if (length <= 8)
+ 		return ZSTD_copy8(dst, src);
++#endif
+ 	do {
+ 		ZSTD_copy8(op, ip);
+ 		op += 8;
+diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
+index 5e975fe..807c1fa 100644
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -412,6 +412,21 @@ cmd_xzmisc = (cat $(filter-out FORCE,$^) | \
+ 	xz --check=crc32 --lzma2=dict=1MiB) > $@ || \
+ 	(rm -f $@ ; false)
+ 
++# ZSTD
++# ---------------------------------------------------------------------------
++# Appends the uncompressed size of the data using size_append. The .zst
++# format has the size information available at the beginning of the file too,
++# but it's in a more complex format and it's good to avoid changing the part
++# of the boot code that reads the uncompressed size.
++# Note that the bytes added by size_append will make the zstd tool think that
++# the file is corrupt. This is expected.
++
++quiet_cmd_zstd = ZSTD    $@
++cmd_zstd = (cat $(filter-out FORCE,$^) | \
++	zstd -19 && \
++        $(call size_append, $(filter-out FORCE,$^))) > $@ || \
++	(rm -f $@ ; false)
++
+ # ASM offsets
+ # ---------------------------------------------------------------------------
+ 
+diff --git a/usr/Kconfig b/usr/Kconfig
+index d53112fd..b63d8ee 100644
+--- a/usr/Kconfig
++++ b/usr/Kconfig
+@@ -105,6 +105,15 @@ config RD_LZ4
+ 	  Support loading of a LZ4 encoded initial ramdisk or cpio buffer
+ 	  If unsure, say N.
+ 
++config RD_ZSTD
++	bool "Support initial ramdisk/ramfs compressed using ZSTD"
++	default y
++	depends on BLK_DEV_INITRD
++	select DECOMPRESS_ZSTD
++	help
++	  Support loading of a ZSTD encoded initial ramdisk or cpio buffer.
++	  If unsure, say N.
++
+ choice
+ 	prompt "Built-in initramfs compression mode"
+ 	depends on INITRAMFS_SOURCE!=""
+@@ -213,6 +222,17 @@ config INITRAMFS_COMPRESSION_LZ4
+ 	  If you choose this, keep in mind that most distros don't provide lz4
+ 	  by default which could cause a build failure.
+ 
++config INITRAMFS_COMPRESSION_ZSTD
++	bool "ZSTD"
++	depends on RD_ZSTD
++	help
++	  ZSTD is a compression algorithm targeting intermediate compression
++	  with fast decompression speed. It will compress better than GZIP and
++	  decompress around the same speed as LZO, but slower than LZ4.
++
++	  If you choose this, keep in mind that you may need to install the zstd
++	  tool to be able to compress the initram.
++
+ endchoice
+ 
+ config INITRAMFS_COMPRESSION
+@@ -225,10 +245,12 @@ config INITRAMFS_COMPRESSION
+ 	default ".xz"   if INITRAMFS_COMPRESSION_XZ
+ 	default ".lzo"  if INITRAMFS_COMPRESSION_LZO
+ 	default ".lz4"  if INITRAMFS_COMPRESSION_LZ4
++	default ".zst"  if INITRAMFS_COMPRESSION_ZSTD
+ 	default ".gz"   if RD_GZIP
+ 	default ".lz4"  if RD_LZ4
+ 	default ".lzo"  if RD_LZO
+ 	default ".xz"   if RD_XZ
+ 	default ".lzma" if RD_LZMA
+ 	default ".bz2"  if RD_BZIP2
++	default ".zst"  if RD_ZSTD
+ 	default ""
diff --git a/v2-2-2-x86-Add-support-for-ZSTD-compressed-kernel.patch b/v2-2-2-x86-Add-support-for-ZSTD-compressed-kernel.patch
new file mode 100644
index 0000000..bffb807
--- /dev/null
+++ b/v2-2-2-x86-Add-support-for-ZSTD-compressed-kernel.patch
@@ -0,0 +1,106 @@
+diff -Naur linux-4.16/Documentation/x86/boot.txt linux-4.16.tpg/Documentation/x86/boot.txt
+--- linux-4.16/Documentation/x86/boot.txt	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/Documentation/x86/boot.txt	2018-05-05 20:55:08.101036076 +0000
+@@ -666,9 +666,9 @@
+   uncompressed data should be determined using the standard magic
+   numbers.  The currently supported compression formats are gzip
+   (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
+-  (magic number 5D 00), XZ (magic number FD 37), and LZ4 (magic number
+-  02 21).  The uncompressed payload is currently always ELF (magic
+-  number 7F 45 4C 46).
++  (magic number 5D 00), XZ (magic number FD 37), LZ4 (magic number
++  02 21) and ZSTD (magic number 28 B5). The uncompressed payload is
++  currently always ELF (magic number 7F 45 4C 46).
+ 
+ Field name:	payload_length
+ Type:		read
+diff -Naur linux-4.16/arch/x86/Kconfig linux-4.16.tpg/arch/x86/Kconfig
+--- linux-4.16/arch/x86/Kconfig	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/arch/x86/Kconfig	2018-05-05 20:55:46.258056725 +0000
+@@ -155,6 +155,7 @@
+ 	select HAVE_KERNEL_LZMA
+ 	select HAVE_KERNEL_LZO
+ 	select HAVE_KERNEL_XZ
++	select HAVE_KERNEL_ZSTD
+ 	select HAVE_KPROBES
+ 	select HAVE_KPROBES_ON_FTRACE
+ 	select HAVE_FUNCTION_ERROR_INJECTION
+diff -Naur linux-4.16/arch/x86/boot/compressed/Makefile linux-4.16.tpg/arch/x86/boot/compressed/Makefile
+--- linux-4.16/arch/x86/boot/compressed/Makefile	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/arch/x86/boot/compressed/Makefile	2018-05-05 20:57:19.610095160 +0000
+@@ -24,7 +24,7 @@
+ KCOV_INSTRUMENT		:= n
+ 
+ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+-	vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
++	vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst
+ 
+ KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ -O2
+ KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
+@@ -137,6 +137,8 @@
+ 	$(call if_changed,lzo)
+ $(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
+ 	$(call if_changed,lz4)
++$(obj)/vmlinux.bin.zst: $(vmlinux.bin.all-y) FORCE
++	$(call if_changed,zstd)
+ 
+ suffix-$(CONFIG_KERNEL_GZIP)	:= gz
+ suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
+@@ -144,6 +146,7 @@
+ suffix-$(CONFIG_KERNEL_XZ)	:= xz
+ suffix-$(CONFIG_KERNEL_LZO) 	:= lzo
+ suffix-$(CONFIG_KERNEL_LZ4) 	:= lz4
++suffix-$(CONFIG_KERNEL_ZSTD)	:= zst
+ 
+ quiet_cmd_mkpiggy = MKPIGGY $@
+       cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
+diff -Naur linux-4.16/arch/x86/boot/compressed/misc.c linux-4.16.tpg/arch/x86/boot/compressed/misc.c
+--- linux-4.16/arch/x86/boot/compressed/misc.c	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/arch/x86/boot/compressed/misc.c	2018-05-05 20:57:55.999105985 +0000
+@@ -75,6 +75,10 @@
+ #ifdef CONFIG_KERNEL_LZ4
+ #include "../../../../lib/decompress_unlz4.c"
+ #endif
++
++#ifdef CONFIG_KERNEL_ZSTD
++#include "../../../../lib/decompress_unzstd.c"
++#endif
+ /*
+  * NOTE: When adding a new decompressor, please update the analysis in
+  * ../header.S.
+diff -Naur linux-4.16/arch/x86/boot/header.S linux-4.16.tpg/arch/x86/boot/header.S
+--- linux-4.16/arch/x86/boot/header.S	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/arch/x86/boot/header.S	2018-05-05 20:59:56.498127616 +0000
+@@ -526,8 +526,14 @@
+ # the size-dependent part now grows so fast.
+ #
+ # extra_bytes = (uncompressed_size >> 8) + 65536
++#
++# ZSTD compressed data grows by at most 3 bytes per 128K, and only has a 22
++# byte fixed overhead but has a maximum block size of 128K, so it needs a
++# larger margin.
++#
++# extra_bytes = (uncompressed_size >> 8) + 131072
+ 
+-#define ZO_z_extra_bytes	((ZO_z_output_len >> 8) + 65536)
++#define ZO_z_extra_bytes	((ZO_z_output_len >> 8) + 131072)
+ #if ZO_z_output_len > ZO_z_input_len
+ # define ZO_z_extract_offset	(ZO_z_output_len + ZO_z_extra_bytes - \
+ 				 ZO_z_input_len)
+diff -Naur linux-4.16/arch/x86/include/asm/boot.h linux-4.16.tpg/arch/x86/include/asm/boot.h
+--- linux-4.16/arch/x86/include/asm/boot.h	2018-04-01 21:20:27.000000000 +0000
++++ linux-4.16.tpg/arch/x86/include/asm/boot.h	2018-05-05 21:02:11.289130418 +0000
+@@ -24,9 +24,11 @@
+ # error "Invalid value for CONFIG_PHYSICAL_ALIGN"
+ #endif
+ 
+-#ifdef CONFIG_KERNEL_BZIP2
++#if defined(CONFIG_KERNEL_BZIP2)
+ # define BOOT_HEAP_SIZE		0x400000
+-#else /* !CONFIG_KERNEL_BZIP2 */
++#elif defined(CONFIG_KERNEL_ZSTD)
++# define BOOT_HEAP_SIZE		 0x30000
++#else
+ # define BOOT_HEAP_SIZE		 0x10000
+ #endif
+ 
diff --git a/v7-fs-Add-VirtualBox-guest-shared-folder-vboxsf-support.patch b/v7-fs-Add-VirtualBox-guest-shared-folder-vboxsf-support.patch
new file mode 100644
index 0000000..3a0c344
--- /dev/null
+++ b/v7-fs-Add-VirtualBox-guest-shared-folder-vboxsf-support.patch
@@ -0,0 +1,3430 @@
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 8a1dbb9260a4..587997bd6bd5 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -14856,6 +14856,12 @@ F:	include/linux/vbox_utils.h
+ F:	include/uapi/linux/vbox*.h
+ F:	drivers/virt/vboxguest/
+ 
++VIRTUAL BOX SHARED FOLDER VFS DRIVER:
++M:	Hans de Goede <hdegoede@redhat.com>
++L:	linux-fsdevel@vger.kernel.org
++S:	Maintained
++F:	fs/vboxsf/*
++
+ VIRTUAL SERIO DEVICE DRIVER
+ M:	Stephen Chandler Paul <thatslyude@gmail.com>
+ S:	Maintained
+diff --git a/fs/Kconfig b/fs/Kconfig
+index bc821a86d965..ec7baaf9cf8f 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -251,6 +251,7 @@ source "fs/pstore/Kconfig"
+ source "fs/sysv/Kconfig"
+ source "fs/ufs/Kconfig"
+ source "fs/exofs/Kconfig"
++source "fs/vboxsf/Kconfig"
+ 
+ endif # MISC_FILESYSTEMS
+ 
+diff --git a/fs/Makefile b/fs/Makefile
+index add789ea270a..bf230c9d305b 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -128,3 +128,4 @@ obj-y				+= exofs/ # Multiple modules
+ obj-$(CONFIG_CEPH_FS)		+= ceph/
+ obj-$(CONFIG_PSTORE)		+= pstore/
+ obj-$(CONFIG_EFIVAR_FS)		+= efivarfs/
++obj-$(CONFIG_VBOXSF_FS)		+= vboxsf/
+diff --git a/fs/vboxsf/Kconfig b/fs/vboxsf/Kconfig
+new file mode 100644
+index 000000000000..b034698121ea
+--- /dev/null
++++ b/fs/vboxsf/Kconfig
+@@ -0,0 +1,10 @@
++config VBOXSF_FS
++	tristate "VirtualBox guest shared folder (vboxsf) support"
++	depends on VBOXGUEST
++	select NLS
++	help
++	  VirtualBox hosts can share folders with guests, this driver
++	  implements the Linux-guest side of this allowing folders exported
++	  by the host to be mounted under Linux.
++
++	  If you want to use shared folders in VirtualBox guests, answer Y or M.
+diff --git a/fs/vboxsf/Makefile b/fs/vboxsf/Makefile
+new file mode 100644
+index 000000000000..fcbd488f9eec
+--- /dev/null
++++ b/fs/vboxsf/Makefile
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_VBOXSF_FS) += vboxsf.o
++
++vboxsf-objs := dir.o file.o utils.o vboxsf_wrappers.o super.o
+diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c
+new file mode 100644
+index 000000000000..3d1e46079820
+--- /dev/null
++++ b/fs/vboxsf/dir.c
+@@ -0,0 +1,574 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * VirtualBox Guest Shared Folders support: Directory inode and file operations
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#include <linux/namei.h>
++#include <linux/vbox_utils.h>
++#include "vfsmod.h"
++
++/**
++ * Open a directory. Read the complete content into a buffer.
++ * Return: 0 or negative errno value.
++ * @inode	inode
++ * @file	file
++ */
++static int sf_dir_open(struct inode *inode, struct file *file)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++	struct shfl_createparms params = {};
++	struct sf_dir_info *sf_d;
++	int err;
++
++	sf_d = vboxsf_dir_info_alloc();
++	if (!sf_d)
++		return -ENOMEM;
++
++	params.handle = SHFL_HANDLE_NIL;
++	params.create_flags = 0
++	    | SHFL_CF_DIRECTORY
++	    | SHFL_CF_ACT_OPEN_IF_EXISTS
++	    | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
++
++	err = vboxsf_create_at_dentry(file_dentry(file), &params);
++	if (err == 0) {
++		if (params.result == SHFL_FILE_EXISTS) {
++			err = vboxsf_dir_read_all(sf_g, sf_d, params.handle);
++			if (!err)
++				file->private_data = sf_d;
++		} else
++			err = -ENOENT;
++
++		vboxsf_close(sf_g->root, params.handle);
++	}
++
++	if (err)
++		vboxsf_dir_info_free(sf_d);
++
++	return err;
++}
++
++/**
++ * This is called when reference count of [file] goes to zero. Notify
++ * the host that it can free whatever is associated with this directory
++ * and deallocate our own internal buffers
++ * Return: 0 or negative errno value.
++ * @inode	inode
++ * @file	file
++ */
++static int sf_dir_release(struct inode *inode, struct file *file)
++{
++	if (file->private_data)
++		vboxsf_dir_info_free(file->private_data);
++
++	return 0;
++}
++
++/**
++ * Translate RTFMODE into DT_xxx (in conjunction to rtDirType())
++ * Return: d_type
++ * @mode	file mode
++ */
++static int sf_get_d_type(u32 mode)
++{
++	int d_type;
++
++	switch (mode & SHFL_TYPE_MASK) {
++	case SHFL_TYPE_FIFO:
++		d_type = DT_FIFO;
++		break;
++	case SHFL_TYPE_DEV_CHAR:
++		d_type = DT_CHR;
++		break;
++	case SHFL_TYPE_DIRECTORY:
++		d_type = DT_DIR;
++		break;
++	case SHFL_TYPE_DEV_BLOCK:
++		d_type = DT_BLK;
++		break;
++	case SHFL_TYPE_FILE:
++		d_type = DT_REG;
++		break;
++	case SHFL_TYPE_SYMLINK:
++		d_type = DT_LNK;
++		break;
++	case SHFL_TYPE_SOCKET:
++		d_type = DT_SOCK;
++		break;
++	case SHFL_TYPE_WHITEOUT:
++		d_type = DT_WHT;
++		break;
++	default:
++		d_type = DT_UNKNOWN;
++		break;
++	}
++	return d_type;
++}
++
++/**
++ * Extract element ([dir]->f_pos) from the directory [dir] into [d_name].
++ * Return: 0 or negative errno value.
++ * @dir		Directory to get element at f_pos from
++ * @d_name	Buffer in which to return element name
++ * @d_type	Buffer in which to return element file-type
++ */
++static int sf_getdent(struct file *dir, char d_name[NAME_MAX], int *d_type)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(file_inode(dir)->i_sb);
++	struct sf_dir_info *sf_d = dir->private_data;
++	struct list_head *pos;
++	loff_t cur = 0;
++
++	list_for_each(pos, &sf_d->info_list) {
++		struct shfl_dirinfo *info;
++		struct sf_dir_buf *b;
++		loff_t i;
++
++		b = list_entry(pos, struct sf_dir_buf, head);
++		if (dir->f_pos >= cur + b->entries) {
++			cur += b->entries;
++			continue;
++		}
++
++		for (i = 0, info = b->buf; i < dir->f_pos - cur; ++i) {
++			size_t size;
++
++			size = offsetof(struct shfl_dirinfo, name.string) +
++			       info->name.size;
++			info = (struct shfl_dirinfo *)((uintptr_t) info + size);
++		}
++
++		*d_type = sf_get_d_type(info->info.attr.mode);
++
++		return vboxsf_nlscpy(sf_g, d_name, NAME_MAX,
++				     info->name.string.utf8, info->name.length);
++	}
++
++	return 1;
++}
++
++/**
++ * This is called when vfs wants to populate internal buffers with
++ * directory [dir]s contents. [opaque] is an argument to the
++ * [filldir]. [filldir] magically modifies it's argument - [opaque]
++ * and takes following additional arguments (which i in turn get from
++ * the host via sf_getdent):
++ *
++ * name : name of the entry (i must also supply it's length huh?)
++ * type : type of the entry (FILE | DIR | etc) (i ellect to use DT_UNKNOWN)
++ * pos : position/index of the entry
++ * ino : inode number of the entry (i fake those)
++ *
++ * [dir] contains:
++ * f_pos : cursor into the directory listing
++ * private_data : mean of communication with the host side
++ *
++ * Extract elements from the directory listing (incrementing f_pos
++ * along the way) and feed them to [filldir] until:
++ *
++ * a. there are no more entries (i.e. sf_getdent set done to 1)
++ * b. failure to compute fake inode number
++ * c. filldir returns an error (see comment on that)
++ * Return: 0 or negative errno value.
++ * @dir		Directory to read
++ * @ctx		Directory context in which to store read elements
++ */
++static int sf_dir_iterate(struct file *dir, struct dir_context *ctx)
++{
++	for (;;) {
++		int err;
++		ino_t fake_ino;
++		loff_t sanity;
++		char d_name[NAME_MAX];
++		int d_type = DT_UNKNOWN;
++
++		err = sf_getdent(dir, d_name, &d_type);
++		switch (err) {
++		case 1:
++			return 0;
++
++		case 0:
++			break;
++
++		case -1:
++		default:
++			/* skip erroneous entry and proceed */
++			dir->f_pos += 1;
++			ctx->pos += 1;
++			continue;
++		}
++
++		/* d_name now contains a valid entry name */
++		sanity = ctx->pos + 0xbeef;
++		fake_ino = sanity;
++		/*
++		 * On 32 bit systems pos is 64 signed, while ino is 32 bit
++		 * unsigned so fake_ino may overflow, check for this.
++		 */
++		if (sanity - fake_ino) {
++			vbg_err("vboxsf: can not compute ino\n");
++			return -EINVAL;
++		}
++		if (!dir_emit(ctx, d_name, strlen(d_name), fake_ino, d_type))
++			return 0;
++
++		dir->f_pos += 1;
++		ctx->pos += 1;
++	}
++}
++
++const struct file_operations vboxsf_dir_fops = {
++	.open = sf_dir_open,
++	.iterate = sf_dir_iterate,
++	.release = sf_dir_release,
++	.read = generic_read_dir,
++	.llseek = generic_file_llseek,
++};
++
++/*
++ * This is called during name resolution/lookup to check if the [dentry] in
++ * the cache is still valid. the job is handled by [sf_inode_revalidate].
++ */
++static int sf_dentry_revalidate(struct dentry *dentry, unsigned int flags)
++{
++	if (flags & LOOKUP_RCU)
++		return -ECHILD;
++
++	if (d_really_is_positive(dentry))
++		return vboxsf_inode_revalidate(dentry) == 0;
++	else
++		return vboxsf_stat_dentry(dentry, NULL) == -ENOENT;
++}
++
++static const struct dentry_operations sf_dentry_ops = {
++	.d_revalidate = sf_dentry_revalidate
++};
++
++/* iops */
++
++/**
++ * This is called when vfs failed to locate dentry in the cache. The
++ * job of this function is to allocate inode and link it to dentry.
++ * [dentry] contains the name to be looked in the [parent] directory.
++ * Failure to locate the name is not a "hard" error, in this case NULL
++ * inode is added to [dentry] and vfs should proceed trying to create
++ * the entry via other means.
++ * Return: NULL on success, ERR_PTR on failure.
++ * @parent	inode of the dentry parent-directory
++ * @dentry	dentry to populate
++ * @flags	flags
++ */
++static struct dentry *sf_lookup(struct inode *parent, struct dentry *dentry,
++				unsigned int flags)
++{
++	struct shfl_fsobjinfo fsinfo;
++	struct sf_inode_info *sf_i;
++	struct sf_glob_info *sf_g;
++	struct inode *inode;
++	ino_t ino;
++	int err;
++
++	sf_g = GET_GLOB_INFO(parent->i_sb);
++	sf_i = GET_INODE_INFO(parent);
++
++	err = vboxsf_stat_dentry(dentry, &fsinfo);
++	if (err) {
++		if (err != -ENOENT)
++			return ERR_PTR(err);
++		/*
++		 * -ENOENT: add NULL inode to dentry so it later can
++		 * be created via call to create/mkdir/open
++		 */
++		inode = NULL;
++	} else {
++		ino = iunique(parent->i_sb, 1);
++		inode = iget_locked(parent->i_sb, ino);
++		if (!inode)
++			return ERR_PTR(-ENOMEM);
++
++		vboxsf_init_inode(sf_g, inode, &fsinfo);
++		unlock_new_inode(inode);
++	}
++
++	dentry->d_time = jiffies;
++	d_set_d_op(dentry, &sf_dentry_ops);
++	d_add(dentry, inode);
++	return NULL;
++}
++
++/**
++ * This should allocate memory for sf_inode_info, compute a unique inode
++ * number, get an inode from vfs, initialize inode info, instantiate
++ * dentry.
++ * Return: 0 or negative errno value.
++ * @parent	inode entry of the directory
++ * @dentry	directory cache entry
++ * @info	file information
++ * @handle	handle
++ */
++static int sf_instantiate(struct inode *parent, struct dentry *dentry,
++			  struct shfl_fsobjinfo *info, u64 handle)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
++	struct sf_inode_info *sf_i;
++	struct inode *inode;
++	ino_t ino;
++
++	ino = iunique(parent->i_sb, 1);
++	inode = iget_locked(parent->i_sb, ino);
++	if (!inode) {
++		if (handle != SHFL_HANDLE_NIL)
++			vboxsf_close(sf_g->root, handle);
++		return -ENOMEM;
++	}
++
++	sf_i = GET_INODE_INFO(inode);
++	/* the host may have given us different attr then requested */
++	sf_i->force_restat = 1;
++	sf_i->handle = handle;
++	vboxsf_init_inode(sf_g, inode, info);
++
++	d_instantiate(dentry, inode);
++	unlock_new_inode(inode);
++
++	return 0;
++}
++
++/**
++ * Create a new regular file / directory.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ * @mode	file mode
++ * @is_dir	true if directory, false otherwise
++ */
++static int sf_create_aux(struct inode *parent, struct dentry *dentry,
++			 umode_t mode, int is_dir)
++{
++	struct sf_inode_info *sf_parent_i = GET_INODE_INFO(parent);
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
++	struct shfl_createparms params = {};
++	int err;
++
++	params.handle = SHFL_HANDLE_NIL;
++	params.create_flags = 0
++	    | SHFL_CF_ACT_CREATE_IF_NEW
++	    | SHFL_CF_ACT_FAIL_IF_EXISTS
++	    | SHFL_CF_ACCESS_READWRITE | (is_dir ? SHFL_CF_DIRECTORY : 0);
++	params.info.attr.mode = 0
++	    | (is_dir ? SHFL_TYPE_DIRECTORY : SHFL_TYPE_FILE)
++	    | (mode & 0777);
++	params.info.attr.additional = SHFLFSOBJATTRADD_NOTHING;
++
++	err = vboxsf_create_at_dentry(dentry, &params);
++	if (err)
++		return err;
++
++	if (params.result != SHFL_FILE_CREATED)
++		return -EPERM;
++
++	if (is_dir) {
++		vboxsf_close(sf_g->root, params.handle);
++		params.handle = SHFL_HANDLE_NIL;
++	}
++
++	err = sf_instantiate(parent, dentry, &params.info, params.handle);
++	if (err)
++		return err;
++
++	/* parent directory access/change time changed */
++	sf_parent_i->force_restat = 1;
++
++	/*
++	 * We leave the handle open. We assume that the same file is opened
++	 * with sf_reg_open() and later closed with sf_reg_close().
++	 */
++	return 0;
++}
++
++/**
++ * Create a new regular file.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ * @mode	file mode
++ * @excl	Possible O_EXCL...
++ */
++static int sf_create(struct inode *parent, struct dentry *dentry, umode_t mode,
++		     bool excl)
++{
++	return sf_create_aux(parent, dentry, mode, 0);
++}
++
++/**
++ * Create a new directory.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ * @mode	file mode
++ */
++static int sf_mkdir(struct inode *parent, struct dentry *dentry, umode_t mode)
++{
++	return sf_create_aux(parent, dentry, mode, 1);
++}
++
++/**
++ * Remove a regular file / directory.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ * @is_dir	true if directory, false otherwise
++ */
++static int sf_unlink_aux(struct inode *parent, struct dentry *dentry,
++			 int is_dir)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
++	struct sf_inode_info *sf_parent_i = GET_INODE_INFO(parent);
++	struct inode *inode = d_inode(dentry);
++	struct shfl_string *path;
++	uint32_t flags;
++	int err;
++
++	flags = is_dir ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE;
++	if (inode && (inode->i_mode & S_IFLNK) == S_IFLNK)
++		flags |= SHFL_REMOVE_SYMLINK;
++
++	path = vboxsf_path_from_dentry(sf_g, dentry);
++	if (IS_ERR(path))
++		return PTR_ERR(path);
++
++	err = vboxsf_remove(sf_g->root, path, flags);
++	__putname(path);
++	if (err)
++		return err;
++
++	/* parent directory access/change time changed */
++	sf_parent_i->force_restat = 1;
++
++	return 0;
++}
++
++/**
++ * Remove a regular file.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ */
++static int sf_unlink(struct inode *parent, struct dentry *dentry)
++{
++	return sf_unlink_aux(parent, dentry, 0);
++}
++
++/**
++ * Remove a directory.
++ * Return: 0 or negative errno value.
++ * @parent	inode of the directory
++ * @dentry	directory cache entry
++ */
++static int sf_rmdir(struct inode *parent, struct dentry *dentry)
++{
++	return sf_unlink_aux(parent, dentry, 1);
++}
++
++/**
++ * Rename a regular file / directory.
++ * Return: 0 or negative errno value.
++ * @old_parent	inode of the old parent directory
++ * @old_dentry	old directory cache entry
++ * @new_parent	inode of the new parent directory
++ * @new_dentry	new directory cache entry
++ * @flags	flags
++ */
++static int sf_rename(struct inode *old_parent, struct dentry *old_dentry,
++		     struct inode *new_parent, struct dentry *new_dentry,
++		     unsigned int flags)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(old_parent->i_sb);
++	struct sf_inode_info *sf_old_parent_i = GET_INODE_INFO(old_parent);
++	struct sf_inode_info *sf_new_parent_i = GET_INODE_INFO(new_parent);
++	u32 shfl_flags = SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS;
++	struct shfl_string *old_path, *new_path;
++	int err;
++
++	if (flags)
++		return -EINVAL;
++
++	if (sf_g != GET_GLOB_INFO(new_parent->i_sb))
++		return -EINVAL;
++
++	old_path = vboxsf_path_from_dentry(sf_g, old_dentry);
++	if (IS_ERR(old_path))
++		return PTR_ERR(old_path);
++
++	new_path = vboxsf_path_from_dentry(sf_g, new_dentry);
++	if (IS_ERR(new_path)) {
++		__putname(old_path);
++		return PTR_ERR(new_path);
++	}
++
++	if (d_inode(old_dentry)->i_mode & S_IFDIR)
++		shfl_flags = 0;
++
++	err = vboxsf_rename(sf_g->root, old_path, new_path, shfl_flags);
++	if (err == 0) {
++		/* parent directories access/change time changed */
++		sf_new_parent_i->force_restat = 1;
++		sf_old_parent_i->force_restat = 1;
++	}
++
++	__putname(new_path);
++	__putname(old_path);
++	return err;
++}
++
++static int sf_symlink(struct inode *parent, struct dentry *dentry,
++		      const char *symname)
++{
++	struct sf_inode_info *sf_parent_i = GET_INODE_INFO(parent);
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
++	int symname_size = strlen(symname) + 1;
++	struct shfl_string *path, *ssymname;
++	struct shfl_fsobjinfo info;
++	int err;
++
++	path = vboxsf_path_from_dentry(sf_g, dentry);
++	if (IS_ERR(path))
++		return PTR_ERR(path);
++
++	ssymname = kmalloc(SHFLSTRING_HEADER_SIZE + symname_size, GFP_KERNEL);
++	if (!ssymname) {
++		__putname(path);
++		return -ENOMEM;
++	}
++	ssymname->length = symname_size - 1;
++	ssymname->size = symname_size;
++	memcpy(ssymname->string.utf8, symname, symname_size);
++
++	err = vboxsf_symlink(sf_g->root, path, ssymname, &info);
++	kfree(ssymname);
++	__putname(path);
++	if (err)
++		return err;
++
++	err = sf_instantiate(parent, dentry, &info, SHFL_HANDLE_NIL);
++	if (err)
++		return err;
++
++	/* parent directory access/change time changed */
++	sf_parent_i->force_restat = 1;
++	return 0;
++}
++
++const struct inode_operations vboxsf_dir_iops = {
++	.lookup = sf_lookup,
++	.create = sf_create,
++	.mkdir = sf_mkdir,
++	.rmdir = sf_rmdir,
++	.unlink = sf_unlink,
++	.rename = sf_rename,
++	.getattr = vboxsf_getattr,
++	.setattr = vboxsf_setattr,
++	.symlink = sf_symlink
++};
+diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c
+new file mode 100644
+index 000000000000..ed78a6e8a1b0
+--- /dev/null
++++ b/fs/vboxsf/file.c
+@@ -0,0 +1,367 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * VirtualBox Guest Shared Folders support: Regular file inode and file ops.
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#include <linux/sizes.h>
++#include "vfsmod.h"
++
++/**
++ * Read from a regular file.
++ * Return: The number of bytes read on success, negative errno value otherwise
++ * @file	the file
++ * @buf		the buffer
++ * @size	length of the buffer
++ * @off		offset within the file
++ */
++static ssize_t sf_reg_read(struct file *file, char *buf, size_t size,
++			   loff_t *off)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(file_inode(file)->i_sb);
++	struct sf_reg_info *sf_r = file->private_data;
++	u64 pos = *off;
++	u32 nread;
++	int err;
++
++	if (!size)
++		return 0;
++
++	if (size > SHFL_MAX_RW_COUNT)
++		nread = SHFL_MAX_RW_COUNT;
++	else
++		nread = size;
++
++	err = vboxsf_read(sf_g->root, sf_r->handle, pos, &nread, buf, true);
++	if (err)
++		return err;
++
++	*off += nread;
++	return nread;
++}
++
++/**
++ * Write to a regular file.
++ * Return: The number of bytes written on success, negative errno val otherwise
++ * @file	the file
++ * @buf		the buffer
++ * @size	length of the buffer
++ * @off		offset within the file
++ */
++static ssize_t sf_reg_write(struct file *file, const char *buf, size_t size,
++			    loff_t *off)
++{
++	struct inode *inode = file_inode(file);
++	struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++	struct sf_reg_info *sf_r = file->private_data;
++	u32 nwritten;
++	u64 pos;
++	int err;
++
++	pos = *off;
++	if (file->f_flags & O_APPEND) {
++		pos = inode->i_size;
++		*off = pos;
++	}
++
++	if (!size)
++		return 0;
++
++	if (size > SHFL_MAX_RW_COUNT)
++		nwritten = SHFL_MAX_RW_COUNT;
++	else
++		nwritten = size;
++
++	/* Make sure any pending writes done through mmap are flushed */
++	err = filemap_fdatawait_range(inode->i_mapping, pos, pos + nwritten);
++	if (err)
++		return err;
++
++	err = vboxsf_write(sf_g->root, sf_r->handle, pos, &nwritten, buf, true);
++	if (err)
++		return err;
++
++	*off += nwritten;
++	if (*off > inode->i_size)
++		i_size_write(inode, *off);
++
++	/* Invalidate page-cache so that mmap using apps see the changes too */
++	invalidate_mapping_pages(inode->i_mapping, pos >> PAGE_SHIFT,
++				 *off >> PAGE_SHIFT);
++
++	/* mtime changed */
++	sf_i->force_restat = 1;
++	return nwritten;
++}
++
++/**
++ * Open a regular file.
++ * Return: 0 or negative errno value.
++ * @inode	inode
++ * @file	file
++ */
++static int sf_reg_open(struct inode *inode, struct file *file)
++{
++	struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++	struct shfl_createparms params = {};
++	struct sf_reg_info *sf_r;
++	int err;
++
++	sf_r = kmalloc(sizeof(*sf_r), GFP_KERNEL);
++	if (!sf_r)
++		return -ENOMEM;
++
++	/* Already open? */
++	if (sf_i->handle != SHFL_HANDLE_NIL) {
++		sf_r->handle = sf_i->handle;
++		sf_i->handle = SHFL_HANDLE_NIL;
++		sf_i->file = file;
++		file->private_data = sf_r;
++		return 0;
++	}
++
++	/*
++	 * We check the value of params.handle afterwards to find out if
++	 * the call succeeded or failed, as the API does not seem to cleanly
++	 * distinguish error and informational messages.
++	 *
++	 * Furthermore, we must set params.handle to SHFL_HANDLE_NIL to
++	 * make the shared folders host service use our mode parameter.
++	 */
++	params.handle = SHFL_HANDLE_NIL;
++	if (file->f_flags & O_CREAT) {
++		params.create_flags |= SHFL_CF_ACT_CREATE_IF_NEW;
++		/*
++		 * We ignore O_EXCL, as the Linux kernel seems to call create
++		 * beforehand itself, so O_EXCL should always fail.
++		 */
++		if (file->f_flags & O_TRUNC)
++			params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
++		else
++			params.create_flags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
++	} else {
++		params.create_flags |= SHFL_CF_ACT_FAIL_IF_NEW;
++		if (file->f_flags & O_TRUNC)
++			params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
++	}
++
++	switch (file->f_flags & O_ACCMODE) {
++	case O_RDONLY:
++		params.create_flags |= SHFL_CF_ACCESS_READ;
++		break;
++
++	case O_WRONLY:
++		params.create_flags |= SHFL_CF_ACCESS_WRITE;
++		break;
++
++	case O_RDWR:
++		params.create_flags |= SHFL_CF_ACCESS_READWRITE;
++		break;
++
++	default:
++		WARN_ON(1);
++	}
++
++	if (file->f_flags & O_APPEND)
++		params.create_flags |= SHFL_CF_ACCESS_APPEND;
++
++	params.info.attr.mode = inode->i_mode;
++
++	err = vboxsf_create_at_dentry(file_dentry(file), &params);
++	if (err == 0 && params.handle == SHFL_HANDLE_NIL)
++		err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT;
++	if (err) {
++		kfree(sf_r);
++		return err;
++	}
++
++	/* the host may have given us different attr then requested */
++	sf_i->force_restat = 1;
++	sf_r->handle = params.handle;
++	sf_i->file = file;
++	file->private_data = sf_r;
++	return 0;
++}
++
++/**
++ * Close a regular file.
++ * Return: 0 or negative errno value.
++ * @inode	inode
++ * @file	file
++ */
++static int sf_reg_release(struct inode *inode, struct file *file)
++{
++	struct sf_reg_info *sf_r;
++	struct sf_glob_info *sf_g;
++	struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++
++	sf_g = GET_GLOB_INFO(inode->i_sb);
++	sf_r = file->private_data;
++
++	filemap_write_and_wait(inode->i_mapping);
++
++	vboxsf_close(sf_g->root, sf_r->handle);
++
++	kfree(sf_r);
++	sf_i->file = NULL;
++	sf_i->handle = SHFL_HANDLE_NIL;
++	file->private_data = NULL;
++	return 0;
++}
++
++const struct file_operations vboxsf_reg_fops = {
++	.read = sf_reg_read,
++	.open = sf_reg_open,
++	.write = sf_reg_write,
++	.release = sf_reg_release,
++	.mmap = generic_file_mmap,
++	.splice_read = generic_file_splice_read,
++	.read_iter = generic_file_read_iter,
++	.write_iter = generic_file_write_iter,
++	.fsync = noop_fsync,
++	.llseek = generic_file_llseek,
++};
++
++const struct inode_operations vboxsf_reg_iops = {
++	.getattr = vboxsf_getattr,
++	.setattr = vboxsf_setattr
++};
++
++static int sf_readpage(struct file *file, struct page *page)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(file_inode(file)->i_sb);
++	struct sf_reg_info *sf_r = file->private_data;
++	loff_t off = page_offset(page);
++	u32 nread = PAGE_SIZE;
++	u8 *buf;
++	int err;
++
++	buf = kmap(page);
++
++	err = vboxsf_read(sf_g->root, sf_r->handle, off, &nread, buf, false);
++	if (err == 0) {
++		memset(&buf[nread], 0, PAGE_SIZE - nread);
++		flush_dcache_page(page);
++		SetPageUptodate(page);
++	} else {
++		SetPageError(page);
++	}
++
++	kunmap(page);
++	unlock_page(page);
++	return err;
++}
++
++static int sf_writepage(struct page *page, struct writeback_control *wbc)
++{
++	struct inode *inode = page->mapping->host;
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++	struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++	struct sf_reg_info *sf_r = sf_i->file->private_data;
++	loff_t off = page_offset(page);
++	loff_t size = i_size_read(inode);
++	u32 nwrite = PAGE_SIZE;
++	u8 *buf;
++	int err;
++
++	if (off + PAGE_SIZE > size)
++		nwrite = size & ~PAGE_MASK;
++
++	buf = kmap(page);
++	err = vboxsf_write(sf_g->root, sf_r->handle, off, &nwrite, buf, false);
++	kunmap(page);
++
++	if (err == 0) {
++		ClearPageError(page);
++		/* mtime changed */
++		sf_i->force_restat = 1;
++	} else {
++		ClearPageUptodate(page);
++	}
++
++	unlock_page(page);
++	return err;
++}
++
++int sf_write_end(struct file *file, struct address_space *mapping, loff_t pos,
++		 unsigned int len, unsigned int copied, struct page *page,
++		 void *fsdata)
++{
++	struct inode *inode = mapping->host;
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++	struct sf_reg_info *sf_r = file->private_data;
++	unsigned int from = pos & ~PAGE_MASK;
++	u32 nwritten = len;
++	u8 *buf;
++	int err;
++
++	buf = kmap(page);
++	err = vboxsf_write(sf_g->root, sf_r->handle, pos, &nwritten,
++			   buf + from, false);
++	kunmap(page);
++
++	if (err)
++		goto out;
++
++	/* mtime changed */
++	GET_INODE_INFO(inode)->force_restat = 1;
++
++	if (!PageUptodate(page) && nwritten == PAGE_SIZE)
++		SetPageUptodate(page);
++
++	pos += nwritten;
++	if (pos > inode->i_size)
++		i_size_write(inode, pos);
++
++out:
++	unlock_page(page);
++	put_page(page);
++
++	return err;
++}
++
++const struct address_space_operations vboxsf_reg_aops = {
++	.readpage = sf_readpage,
++	.writepage = sf_writepage,
++	.set_page_dirty = __set_page_dirty_nobuffers,
++	.write_begin = simple_write_begin,
++	.write_end = sf_write_end,
++};
++
++static const char *sf_get_link(struct dentry *dentry, struct inode *inode,
++			       struct delayed_call *done)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++	struct shfl_string *path;
++	char *link;
++	int err;
++
++	if (!dentry)
++		return ERR_PTR(-ECHILD);
++
++	path = vboxsf_path_from_dentry(sf_g, dentry);
++	if (IS_ERR(path))
++		return (char *)path;
++
++	link = kzalloc(PATH_MAX, GFP_KERNEL);
++	if (!link) {
++		__putname(path);
++		return ERR_PTR(-ENOMEM);
++	}
++
++	err = vboxsf_readlink(sf_g->root, path, PATH_MAX, link);
++	__putname(path);
++	if (err) {
++		kfree(link);
++		return ERR_PTR(err);
++	}
++
++	set_delayed_call(done, kfree_link, link);
++	return link;
++}
++
++const struct inode_operations vboxsf_lnk_iops = {
++	.get_link = sf_get_link
++};
+diff --git a/fs/vboxsf/shfl_hostintf.h b/fs/vboxsf/shfl_hostintf.h
+new file mode 100644
+index 000000000000..8666a5347a0b
+--- /dev/null
++++ b/fs/vboxsf/shfl_hostintf.h
+@@ -0,0 +1,919 @@
++/* SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0) */
++/*
++ * VirtualBox Shared Folders: host interface definition.
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#ifndef SHFL_HOSTINTF_H
++#define SHFL_HOSTINTF_H
++
++#include <linux/vbox_vmmdev_types.h>
++
++/* The max in/out buffer size for a FN_READ or FN_WRITE call */
++#define SHFL_MAX_RW_COUNT           (16 * SZ_1M)
++
++/*
++ * Structures shared between guest and the service
++ * can be relocated and use offsets to point to variable
++ * length parts.
++ *
++ * Shared folders protocol works with handles.
++ * Before doing any action on a file system object,
++ * one have to obtain the object handle via a SHFL_FN_CREATE
++ * request. A handle must be closed with SHFL_FN_CLOSE.
++ */
++
++/* Query mappings changes. */
++#define SHFL_FN_QUERY_MAPPINGS      (1)
++/* Query mappings changes. */
++#define SHFL_FN_QUERY_MAP_NAME      (2)
++/* Open/create object. */
++#define SHFL_FN_CREATE              (3)
++/* Close object handle. */
++#define SHFL_FN_CLOSE               (4)
++/* Read object content. */
++#define SHFL_FN_READ                (5)
++/* Write new object content. */
++#define SHFL_FN_WRITE               (6)
++/* Lock/unlock a range in the object. */
++#define SHFL_FN_LOCK                (7)
++/* List object content. */
++#define SHFL_FN_LIST                (8)
++/* Query/set object information. */
++#define SHFL_FN_INFORMATION         (9)
++/* Remove object */
++#define SHFL_FN_REMOVE              (11)
++/* Map folder (legacy) */
++#define SHFL_FN_MAP_FOLDER_OLD      (12)
++/* Unmap folder */
++#define SHFL_FN_UNMAP_FOLDER        (13)
++/* Rename object (possibly moving it to another directory) */
++#define SHFL_FN_RENAME              (14)
++/* Flush file */
++#define SHFL_FN_FLUSH               (15)
++#define SHFL_FN_SET_UTF8            (16)
++#define SHFL_CPARMS_SET_UTF8        0
++/* Map folder */
++#define SHFL_FN_MAP_FOLDER          (17)
++/* Read symlink destination (as of VBox 4.0) */
++#define SHFL_FN_READLINK            (18)
++/* Create symlink (as of VBox 4.0) */
++#define SHFL_FN_SYMLINK             (19)
++/* Ask host to show symlinks (as of VBox 4.0) */
++#define SHFL_FN_SET_SYMLINKS        (20)
++#define SHFL_CPARMS_SET_SYMLINKS    0
++
++/* Root handles for a mapping are of type u32, Root handles are unique. */
++#define SHFL_ROOT_NIL ((u32)~0)
++
++/* Shared folders handle for an opened object are of type u64. */
++#define SHFL_HANDLE_NIL  ((u64)~0LL)
++#define SHFL_HANDLE_ROOT ((u64)0LL)
++
++/* Hardcoded maximum length (in chars) of a shared folder name. */
++#define SHFL_MAX_LEN         (256)
++/* Hardcoded maximum number of shared folder mapping available to the guest. */
++#define SHFL_MAX_MAPPINGS    (64)
++
++/** Shared folder string buffer structure. */
++struct shfl_string {
++	/** Allocated size of the string member in bytes. */
++	u16 size;
++
++	/** Length of string without trailing nul in bytes. */
++	u16 length;
++
++	/** UTF-8 or UTF-16 string. Nul terminated. */
++	union {
++		u8 utf8[1];
++		u16 utf16[1];
++		u16 ucs2[1]; /* misnomer, use utf16. */
++	} string;
++};
++VMMDEV_ASSERT_SIZE(shfl_string, 6);
++
++/* The size of shfl_string w/o the string part. */
++#define SHFLSTRING_HEADER_SIZE  4
++
++/* Calculate size of the string. */
++static inline u32 shfl_string_buf_size(const struct shfl_string *string)
++{
++	return string ? SHFLSTRING_HEADER_SIZE + string->size : 0;
++}
++
++/* Set user id on execution (S_ISUID). */
++#define SHFL_UNIX_ISUID             0004000U
++/* Set group id on execution (S_ISGID). */
++#define SHFL_UNIX_ISGID             0002000U
++/* Sticky bit (S_ISVTX / S_ISTXT). */
++#define SHFL_UNIX_ISTXT             0001000U
++
++/* Owner readable (S_IRUSR). */
++#define SHFL_UNIX_IRUSR             0000400U
++/* Owner writable (S_IWUSR). */
++#define SHFL_UNIX_IWUSR             0000200U
++/* Owner executable (S_IXUSR). */
++#define SHFL_UNIX_IXUSR             0000100U
++
++/* Group readable (S_IRGRP). */
++#define SHFL_UNIX_IRGRP             0000040U
++/* Group writable (S_IWGRP). */
++#define SHFL_UNIX_IWGRP             0000020U
++/* Group executable (S_IXGRP). */
++#define SHFL_UNIX_IXGRP             0000010U
++
++/* Other readable (S_IROTH). */
++#define SHFL_UNIX_IROTH             0000004U
++/* Other writable (S_IWOTH). */
++#define SHFL_UNIX_IWOTH             0000002U
++/* Other executable (S_IXOTH). */
++#define SHFL_UNIX_IXOTH             0000001U
++
++/* Named pipe (fifo) (S_IFIFO). */
++#define SHFL_TYPE_FIFO              0010000U
++/* Character device (S_IFCHR). */
++#define SHFL_TYPE_DEV_CHAR          0020000U
++/* Directory (S_IFDIR). */
++#define SHFL_TYPE_DIRECTORY         0040000U
++/* Block device (S_IFBLK). */
++#define SHFL_TYPE_DEV_BLOCK         0060000U
++/* Regular file (S_IFREG). */
++#define SHFL_TYPE_FILE              0100000U
++/* Symbolic link (S_IFLNK). */
++#define SHFL_TYPE_SYMLINK           0120000U
++/* Socket (S_IFSOCK). */
++#define SHFL_TYPE_SOCKET            0140000U
++/* Whiteout (S_IFWHT). */
++#define SHFL_TYPE_WHITEOUT          0160000U
++/* Type mask (S_IFMT). */
++#define SHFL_TYPE_MASK              0170000U
++
++/* Checks the mode flags indicate a directory (S_ISDIR). */
++#define SHFL_IS_DIRECTORY(m)   (((m) & SHFL_TYPE_MASK) == SHFL_TYPE_DIRECTORY)
++/* Checks the mode flags indicate a symbolic link (S_ISLNK). */
++#define SHFL_IS_SYMLINK(m)     (((m) & SHFL_TYPE_MASK) == SHFL_TYPE_SYMLINK)
++
++/** The available additional information in a shfl_fsobjattr object. */
++enum shfl_fsobjattr_add {
++	/** No additional information is available / requested. */
++	SHFLFSOBJATTRADD_NOTHING = 1,
++	/**
++	 * The additional unix attributes (shfl_fsobjattr::u::unix_attr) are
++	 *  available / requested.
++	 */
++	SHFLFSOBJATTRADD_UNIX,
++	/**
++	 * The additional extended attribute size (shfl_fsobjattr::u::size) is
++	 *  available / requested.
++	 */
++	SHFLFSOBJATTRADD_EASIZE,
++	/**
++	 * The last valid item (inclusive).
++	 * The valid range is SHFLFSOBJATTRADD_NOTHING thru
++	 * SHFLFSOBJATTRADD_LAST.
++	 */
++	SHFLFSOBJATTRADD_LAST = SHFLFSOBJATTRADD_EASIZE,
++
++	/** The usual 32-bit hack. */
++	SHFLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
++};
++
++/**
++ * Additional unix Attributes, these are available when
++ * shfl_fsobjattr.additional == SHFLFSOBJATTRADD_UNIX.
++ */
++struct shfl_fsobjattr_unix {
++	/**
++	 * The user owning the filesystem object (st_uid).
++	 * This field is ~0U if not supported.
++	 */
++	u32 uid;
++
++	/**
++	 * The group the filesystem object is assigned (st_gid).
++	 * This field is ~0U if not supported.
++	 */
++	u32 gid;
++
++	/**
++	 * Number of hard links to this filesystem object (st_nlink).
++	 * This field is 1 if the filesystem doesn't support hardlinking or
++	 * the information isn't available.
++	 */
++	u32 hardlinks;
++
++	/**
++	 * The device number of the device which this filesystem object resides
++	 * on (st_dev). This field is 0 if this information is not available.
++	 */
++	u32 inode_id_device;
++
++	/**
++	 * The unique identifier (within the filesystem) of this filesystem
++	 * object (st_ino). Together with inode_id_device, this field can be
++	 * used as a OS wide unique id, when both their values are not 0.
++	 * This field is 0 if the information is not available.
++	 */
++	u64 inode_id;
++
++	/**
++	 * User flags (st_flags).
++	 * This field is 0 if this information is not available.
++	 */
++	u32 flags;
++
++	/**
++	 * The current generation number (st_gen).
++	 * This field is 0 if this information is not available.
++	 */
++	u32 generation_id;
++
++	/**
++	 * The device number of a char. or block device type object (st_rdev).
++	 * This field is 0 if the file isn't a char. or block device or when
++	 * the OS doesn't use the major+minor device idenfication scheme.
++	 */
++	u32 device;
++} __packed;
++
++/** Extended attribute size. */
++struct shfl_fsobjattr_easize {
++	/** Size of EAs. */
++	s64 cb;
++} __packed;
++
++/** Shared folder filesystem object attributes. */
++struct shfl_fsobjattr {
++	/** Mode flags (st_mode). SHFL_UNIX_*, SHFL_TYPE_*, and SHFL_DOS_*. */
++	u32 mode;
++
++	/** The additional attributes available. */
++	enum shfl_fsobjattr_add additional;
++
++	/**
++	 * Additional attributes.
++	 *
++	 * Unless explicitly specified to an API, the API can provide additional
++	 * data as it is provided by the underlying OS.
++	 */
++	union {
++		struct shfl_fsobjattr_unix unix_attr;
++		struct shfl_fsobjattr_easize size;
++	} __packed u;
++} __packed;
++VMMDEV_ASSERT_SIZE(shfl_fsobjattr, 44);
++
++struct shfl_timespec {
++	s64 ns_relative_to_unix_epoch;
++};
++
++/** Filesystem object information structure. */
++struct shfl_fsobjinfo {
++	/**
++	 * Logical size (st_size).
++	 * For normal files this is the size of the file.
++	 * For symbolic links, this is the length of the path name contained
++	 * in the symbolic link.
++	 * For other objects this fields needs to be specified.
++	 */
++	s64 size;
++
++	/** Disk allocation size (st_blocks * DEV_BSIZE). */
++	s64 allocated;
++
++	/** Time of last access (st_atime). */
++	struct shfl_timespec access_time;
++
++	/** Time of last data modification (st_mtime). */
++	struct shfl_timespec modification_time;
++
++	/**
++	 * Time of last status change (st_ctime).
++	 * If not available this is set to modification_time.
++	 */
++	struct shfl_timespec change_time;
++
++	/**
++	 * Time of file birth (st_birthtime).
++	 * If not available this is set to change_time.
++	 */
++	struct shfl_timespec birth_time;
++
++	/** Attributes. */
++	struct shfl_fsobjattr attr;
++
++} __packed;
++VMMDEV_ASSERT_SIZE(shfl_fsobjinfo, 92);
++
++/**
++ * result of an open/create request.
++ * Along with handle value the result code
++ * identifies what has happened while
++ * trying to open the object.
++ */
++enum shfl_create_result {
++	SHFL_NO_RESULT,
++	/** Specified path does not exist. */
++	SHFL_PATH_NOT_FOUND,
++	/** Path to file exists, but the last component does not. */
++	SHFL_FILE_NOT_FOUND,
++	/** File already exists and either has been opened or not. */
++	SHFL_FILE_EXISTS,
++	/** New file was created. */
++	SHFL_FILE_CREATED,
++	/** Existing file was replaced or overwritten. */
++	SHFL_FILE_REPLACED
++};
++
++/* No flags. Initialization value. */
++#define SHFL_CF_NONE                  (0x00000000)
++
++/*
++ * Only lookup the object, do not return a handle. When this is set all other
++ * flags are ignored.
++ */
++#define SHFL_CF_LOOKUP                (0x00000001)
++
++/*
++ * Open parent directory of specified object.
++ * Useful for the corresponding Windows FSD flag
++ * and for opening paths like \\dir\\*.* to search the 'dir'.
++ */
++#define SHFL_CF_OPEN_TARGET_DIRECTORY (0x00000002)
++
++/* Create/open a directory. */
++#define SHFL_CF_DIRECTORY             (0x00000004)
++
++/*
++ *  Open/create action to do if object exists
++ *  and if the object does not exists.
++ *  REPLACE file means atomically DELETE and CREATE.
++ *  OVERWRITE file means truncating the file to 0 and
++ *  setting new size.
++ *  When opening an existing directory REPLACE and OVERWRITE
++ *  actions are considered invalid, and cause returning
++ *  FILE_EXISTS with NIL handle.
++ */
++#define SHFL_CF_ACT_MASK_IF_EXISTS      (0x000000f0)
++#define SHFL_CF_ACT_MASK_IF_NEW         (0x00000f00)
++
++/* What to do if object exists. */
++#define SHFL_CF_ACT_OPEN_IF_EXISTS      (0x00000000)
++#define SHFL_CF_ACT_FAIL_IF_EXISTS      (0x00000010)
++#define SHFL_CF_ACT_REPLACE_IF_EXISTS   (0x00000020)
++#define SHFL_CF_ACT_OVERWRITE_IF_EXISTS (0x00000030)
++
++/* What to do if object does not exist. */
++#define SHFL_CF_ACT_CREATE_IF_NEW       (0x00000000)
++#define SHFL_CF_ACT_FAIL_IF_NEW         (0x00000100)
++
++/* Read/write requested access for the object. */
++#define SHFL_CF_ACCESS_MASK_RW          (0x00003000)
++
++/* No access requested. */
++#define SHFL_CF_ACCESS_NONE             (0x00000000)
++/* Read access requested. */
++#define SHFL_CF_ACCESS_READ             (0x00001000)
++/* Write access requested. */
++#define SHFL_CF_ACCESS_WRITE            (0x00002000)
++/* Read/Write access requested. */
++#define SHFL_CF_ACCESS_READWRITE	(0x00003000)
++
++/* Requested share access for the object. */
++#define SHFL_CF_ACCESS_MASK_DENY        (0x0000c000)
++
++/* Allow any access. */
++#define SHFL_CF_ACCESS_DENYNONE         (0x00000000)
++/* Do not allow read. */
++#define SHFL_CF_ACCESS_DENYREAD         (0x00004000)
++/* Do not allow write. */
++#define SHFL_CF_ACCESS_DENYWRITE        (0x00008000)
++/* Do not allow access. */
++#define SHFL_CF_ACCESS_DENYALL          (0x0000c000)
++
++/* Requested access to attributes of the object. */
++#define SHFL_CF_ACCESS_MASK_ATTR        (0x00030000)
++
++/* No access requested. */
++#define SHFL_CF_ACCESS_ATTR_NONE        (0x00000000)
++/* Read access requested. */
++#define SHFL_CF_ACCESS_ATTR_READ        (0x00010000)
++/* Write access requested. */
++#define SHFL_CF_ACCESS_ATTR_WRITE       (0x00020000)
++/* Read/Write access requested. */
++#define SHFL_CF_ACCESS_ATTR_READWRITE   (0x00030000)
++
++/*
++ * The file is opened in append mode.
++ * Ignored if SHFL_CF_ACCESS_WRITE is not set.
++ */
++#define SHFL_CF_ACCESS_APPEND           (0x00040000)
++
++/** Create parameters buffer struct for SHFL_FN_CREATE call */
++struct shfl_createparms {
++	/** Returned handle of opened object. */
++	u64 handle;
++
++	/** Returned result of the operation */
++	enum shfl_create_result result;
++
++	/** SHFL_CF_* */
++	u32 create_flags;
++
++	/**
++	 * Attributes of object to create and
++	 * returned actual attributes of opened/created object.
++	 */
++	struct shfl_fsobjinfo info;
++} __packed;
++
++/** Shared Folder directory information */
++struct shfl_dirinfo {
++	/** Full information about the object. */
++	struct shfl_fsobjinfo info;
++	/**
++	 * The length of the short field (number of UTF16 chars).
++	 * It is 16-bit for reasons of alignment.
++	 */
++	u16 short_name_len;
++	/**
++	 * The short name for 8.3 compatibility.
++	 * Empty string if not available.
++	 */
++	u16 short_name[14];
++	struct shfl_string name;
++};
++
++/** Shared folder filesystem properties. */
++struct shfl_fsproperties {
++	/**
++	 * The maximum size of a filesystem object name.
++	 * This does not include the '\\0'.
++	 */
++	u32 max_component_len;
++
++	/**
++	 * True if the filesystem is remote.
++	 * False if the filesystem is local.
++	 */
++	bool remote;
++
++	/**
++	 * True if the filesystem is case sensitive.
++	 * False if the filesystem is case insensitive.
++	 */
++	bool case_sensitive;
++
++	/**
++	 * True if the filesystem is mounted read only.
++	 * False if the filesystem is mounted read write.
++	 */
++	bool read_only;
++
++	/**
++	 * True if the filesystem can encode unicode object names.
++	 * False if it can't.
++	 */
++	bool supports_unicode;
++
++	/**
++	 * True if the filesystem is compresses.
++	 * False if it isn't or we don't know.
++	 */
++	bool compressed;
++
++	/**
++	 * True if the filesystem compresses of individual files.
++	 * False if it doesn't or we don't know.
++	 */
++	bool file_compression;
++};
++VMMDEV_ASSERT_SIZE(shfl_fsproperties, 12);
++
++struct shfl_volinfo {
++	s64 total_allocation_bytes;
++	s64 available_allocation_bytes;
++	u32 bytes_per_allocation_unit;
++	u32 bytes_per_sector;
++	u32 serial;
++	struct shfl_fsproperties properties;
++};
++
++
++/** SHFL_FN_MAP_FOLDER Parameters structure. */
++struct shfl_map_folder {
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string buffer.
++	 */
++	struct vmmdev_hgcm_function_parameter path;
++
++	/**
++	 * pointer, out: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in: UTF16
++	 * Path delimiter
++	 */
++	struct vmmdev_hgcm_function_parameter delimiter;
++
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Case senstive flag
++	 */
++	struct vmmdev_hgcm_function_parameter case_sensitive;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_MAP_FOLDER (4)
++
++
++/** SHFL_FN_UNMAP_FOLDER Parameters structure. */
++struct shfl_unmap_folder {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_UNMAP_FOLDER (1)
++
++
++/** SHFL_FN_CREATE Parameters structure. */
++struct shfl_create {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string buffer.
++	 */
++	struct vmmdev_hgcm_function_parameter path;
++
++	/**
++	 * pointer, in/out:
++	 * Points to struct shfl_createparms buffer.
++	 */
++	struct vmmdev_hgcm_function_parameter parms;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_CREATE (3)
++
++
++/** SHFL_FN_CLOSE Parameters structure. */
++struct shfl_close {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * value64, in:
++	 * SHFLHANDLE (u64) of object to close.
++	 */
++	struct vmmdev_hgcm_function_parameter handle;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_CLOSE (2)
++
++
++/** SHFL_FN_READ Parameters structure. */
++struct shfl_read {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * value64, in:
++	 * SHFLHANDLE (u64) of object to read from.
++	 */
++	struct vmmdev_hgcm_function_parameter handle;
++
++	/**
++	 * value64, in:
++	 * Offset to read from.
++	 */
++	struct vmmdev_hgcm_function_parameter offset;
++
++	/**
++	 * value64, in/out:
++	 * Bytes to read/How many were read.
++	 */
++	struct vmmdev_hgcm_function_parameter cb;
++
++	/**
++	 * pointer, out:
++	 * Buffer to place data to.
++	 */
++	struct vmmdev_hgcm_function_parameter buffer;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_READ (5)
++
++
++/** SHFL_FN_WRITE Parameters structure. */
++struct shfl_write {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * value64, in:
++	 * SHFLHANDLE (u64) of object to write to.
++	 */
++	struct vmmdev_hgcm_function_parameter handle;
++
++	/**
++	 * value64, in:
++	 * Offset to write to.
++	 */
++	struct vmmdev_hgcm_function_parameter offset;
++
++	/**
++	 * value64, in/out:
++	 * Bytes to write/How many were written.
++	 */
++	struct vmmdev_hgcm_function_parameter cb;
++
++	/**
++	 * pointer, in:
++	 * Data to write.
++	 */
++	struct vmmdev_hgcm_function_parameter buffer;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_WRITE (5)
++
++
++/*
++ * SHFL_FN_LIST
++ * Listing information includes variable length RTDIRENTRY[EX] structures.
++ */
++
++#define SHFL_LIST_NONE			0
++#define SHFL_LIST_RETURN_ONE		1
++
++/** SHFL_FN_LIST Parameters structure. */
++struct shfl_list {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * value64, in:
++	 * SHFLHANDLE (u64) of object to be listed.
++	 */
++	struct vmmdev_hgcm_function_parameter handle;
++
++	/**
++	 * value32, in:
++	 * List flags SHFL_LIST_*.
++	 */
++	struct vmmdev_hgcm_function_parameter flags;
++
++	/**
++	 * value32, in/out:
++	 * Bytes to be used for listing information/How many bytes were used.
++	 */
++	struct vmmdev_hgcm_function_parameter cb;
++
++	/**
++	 * pointer, in/optional
++	 * Points to struct shfl_string buffer that specifies a search path.
++	 */
++	struct vmmdev_hgcm_function_parameter path;
++
++	/**
++	 * pointer, out:
++	 * Buffer to place listing information to. (struct shfl_dirinfo)
++	 */
++	struct vmmdev_hgcm_function_parameter buffer;
++
++	/**
++	 * value32, in/out:
++	 * Indicates a key where the listing must be resumed.
++	 * in: 0 means start from begin of object.
++	 * out: 0 means listing completed.
++	 */
++	struct vmmdev_hgcm_function_parameter resume_point;
++
++	/**
++	 * pointer, out:
++	 * Number of files returned
++	 */
++	struct vmmdev_hgcm_function_parameter file_count;
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_LIST (8)
++
++
++/** SHFL_FN_READLINK Parameters structure. */
++struct shfl_readLink {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string buffer.
++	 */
++	struct vmmdev_hgcm_function_parameter path;
++
++	/**
++	 * pointer, out:
++	 * Buffer to place data to.
++	 */
++	struct vmmdev_hgcm_function_parameter buffer;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_READLINK (3)
++
++
++/* SHFL_FN_INFORMATION */
++
++/* Mask of Set/Get bit. */
++#define SHFL_INFO_MODE_MASK    (0x1)
++/* Get information */
++#define SHFL_INFO_GET          (0x0)
++/* Set information */
++#define SHFL_INFO_SET          (0x1)
++
++/* Get name of the object. */
++#define SHFL_INFO_NAME         (0x2)
++/* Set size of object (extend/trucate); only applies to file objects */
++#define SHFL_INFO_SIZE         (0x4)
++/* Get/Set file object info. */
++#define SHFL_INFO_FILE         (0x8)
++/* Get volume information. */
++#define SHFL_INFO_VOLUME       (0x10)
++
++/** SHFL_FN_INFORMATION Parameters structure. */
++struct shfl_information {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * value64, in:
++	 * SHFLHANDLE (u64) of object to be listed.
++	 */
++	struct vmmdev_hgcm_function_parameter handle;
++
++	/**
++	 * value32, in:
++	 * SHFL_INFO_*
++	 */
++	struct vmmdev_hgcm_function_parameter flags;
++
++	/**
++	 * value32, in/out:
++	 * Bytes to be used for information/How many bytes were used.
++	 */
++	struct vmmdev_hgcm_function_parameter cb;
++
++	/**
++	 * pointer, in/out:
++	 * Information to be set/get (shfl_fsobjinfo or shfl_string). Do not
++	 * forget to set the shfl_fsobjinfo::attr::additional for a get
++	 * operation as well.
++	 */
++	struct vmmdev_hgcm_function_parameter info;
++
++};
++
++/* Number of parameters */
++#define SHFL_CPARMS_INFORMATION (5)
++
++
++/* SHFL_FN_REMOVE */
++
++#define SHFL_REMOVE_FILE        (0x1)
++#define SHFL_REMOVE_DIR         (0x2)
++#define SHFL_REMOVE_SYMLINK     (0x4)
++
++/** SHFL_FN_REMOVE Parameters structure. */
++struct shfl_remove {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string buffer.
++	 */
++	struct vmmdev_hgcm_function_parameter path;
++
++	/**
++	 * value32, in:
++	 * remove flags (file/directory)
++	 */
++	struct vmmdev_hgcm_function_parameter flags;
++
++};
++
++#define SHFL_CPARMS_REMOVE  (3)
++
++
++/* SHFL_FN_RENAME */
++
++#define SHFL_RENAME_FILE                (0x1)
++#define SHFL_RENAME_DIR                 (0x2)
++#define SHFL_RENAME_REPLACE_IF_EXISTS   (0x4)
++
++/** SHFL_FN_RENAME Parameters structure. */
++struct shfl_rename {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string src.
++	 */
++	struct vmmdev_hgcm_function_parameter src;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string dest.
++	 */
++	struct vmmdev_hgcm_function_parameter dest;
++
++	/**
++	 * value32, in:
++	 * rename flags (file/directory)
++	 */
++	struct vmmdev_hgcm_function_parameter flags;
++
++};
++
++#define SHFL_CPARMS_RENAME  (4)
++
++
++/** SHFL_FN_SYMLINK Parameters structure. */
++struct shfl_symlink {
++	/**
++	 * pointer, in: SHFLROOT (u32)
++	 * Root handle of the mapping which name is queried.
++	 */
++	struct vmmdev_hgcm_function_parameter root;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string of path for the new symlink.
++	 */
++	struct vmmdev_hgcm_function_parameter new_path;
++
++	/**
++	 * pointer, in:
++	 * Points to struct shfl_string of destination for symlink.
++	 */
++	struct vmmdev_hgcm_function_parameter old_path;
++
++	/**
++	 * pointer, out:
++	 * Information about created symlink.
++	 */
++	struct vmmdev_hgcm_function_parameter info;
++
++};
++
++#define SHFL_CPARMS_SYMLINK  (4)
++
++#endif
+diff --git a/fs/vboxsf/super.c b/fs/vboxsf/super.c
+new file mode 100644
+index 000000000000..62d7ca4aa7e6
+--- /dev/null
++++ b/fs/vboxsf/super.c
+@@ -0,0 +1,442 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * VirtualBox Guest Shared Folders support: Virtual File System.
++ *
++ * Module initialization/finalization
++ * File system registration/deregistration
++ * Superblock reading
++ * Few utility functions
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#include <linux/magic.h>
++#include <linux/module.h>
++#include <linux/nls.h>
++#include <linux/parser.h>
++#include <linux/statfs.h>
++#include <linux/vbox_utils.h>
++#include "vfsmod.h"
++
++#define VBSF_MOUNT_SIGNATURE_BYTE_0 ('\000')
++#define VBSF_MOUNT_SIGNATURE_BYTE_1 ('\377')
++#define VBSF_MOUNT_SIGNATURE_BYTE_2 ('\376')
++#define VBSF_MOUNT_SIGNATURE_BYTE_3 ('\375')
++
++static int follow_symlinks;
++module_param(follow_symlinks, int, 0444);
++MODULE_PARM_DESC(follow_symlinks,
++		 "Let host resolve symlinks rather than showing them");
++
++struct fill_super_args {
++	const char *dev_name;
++	char *options;
++};
++
++static struct super_operations sf_super_ops; /* forward declaration */
++static struct kmem_cache *sf_inode_cachep;
++
++static char * const vboxsf_default_nls = CONFIG_NLS_DEFAULT;
++
++enum  { opt_name, opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode,
++	opt_dmask, opt_fmask, opt_error };
++
++static const match_table_t vboxsf_tokens = {
++	{ opt_nls, "nls=%s" },
++	{ opt_uid, "uid=%u" },
++	{ opt_gid, "gid=%u" },
++	{ opt_ttl, "ttl=%u" },
++	{ opt_dmode, "dmode=%o" },
++	{ opt_fmode, "fmode=%o" },
++	{ opt_dmask, "dmask=%o" },
++	{ opt_fmask, "fmask=%o" },
++	{ opt_error, NULL },
++};
++
++static int vboxsf_parse_options(struct sf_glob_info *sf_g, char *options)
++{
++	substring_t args[MAX_OPT_ARGS];
++	int value, token;
++	char *p;
++
++	if (!options)
++		goto out;
++
++	if (options[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 &&
++	    options[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 &&
++	    options[2] == VBSF_MOUNT_SIGNATURE_BYTE_2 &&
++	    options[3] == VBSF_MOUNT_SIGNATURE_BYTE_3) {
++		vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n");
++		return -EINVAL;
++	}
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		if (!*p)
++			continue;
++
++		token = match_token(p, vboxsf_tokens, args);
++		switch (token) {
++		case opt_nls:
++			if (sf_g->nls_name) {
++				vbg_err("vboxsf: Cannot change nls option\n");
++				return -EINVAL;
++			}
++			sf_g->nls_name = match_strdup(&args[0]);
++			if (!sf_g->nls_name)
++				return -ENOMEM;
++			break;
++		case opt_uid:
++			if (match_int(&args[0], &value))
++				return -EINVAL;
++			sf_g->uid = value;
++			break;
++		case opt_gid:
++			if (match_int(&args[0], &value))
++				return -EINVAL;
++			sf_g->gid = value;
++			break;
++		case opt_ttl:
++			if (match_int(&args[0], &value))
++				return -EINVAL;
++			sf_g->ttl = msecs_to_jiffies(value);
++			break;
++		case opt_dmode:
++			if (match_octal(&args[0], &value))
++				return -EINVAL;
++			sf_g->dmode = value;
++			break;
++		case opt_fmode:
++			if (match_octal(&args[0], &value))
++				return -EINVAL;
++			sf_g->fmode = value;
++			break;
++		case opt_dmask:
++			if (match_octal(&args[0], &value))
++				return -EINVAL;
++			sf_g->dmask = value;
++			break;
++		case opt_fmask:
++			if (match_octal(&args[0], &value))
++				return -EINVAL;
++			sf_g->fmask = value;
++			break;
++		default:
++			vbg_err("vboxsf: Unrecognized mount option \"%s\" or missing value\n",
++				p);
++			return -EINVAL;
++		}
++	}
++
++out:
++	if (!sf_g->nls_name)
++		sf_g->nls_name = vboxsf_default_nls;
++
++	return 0;
++}
++
++/*
++ * Called when vfs mounts the fs, should respect [flags],
++ * initializes [sb], initializes root inode and dentry.
++ */
++static int sf_fill_super(struct super_block *sb, void *data, int flags)
++{
++	struct fill_super_args *args = data;
++	struct shfl_string root_path;
++	struct sf_glob_info *sf_g;
++	struct dentry *droot;
++	struct inode *iroot;
++	size_t size;
++	int err;
++
++	if (flags & MS_REMOUNT)
++		return -EINVAL;
++
++	sf_g = kzalloc(sizeof(*sf_g), GFP_KERNEL);
++	if (!sf_g)
++		return -ENOMEM;
++
++	/* Turn dev_name into a shfl_string */
++	size = strlen(args->dev_name) + 1;
++	sf_g->name = kmalloc(SHFLSTRING_HEADER_SIZE + size, GFP_KERNEL);
++	if (!sf_g->name)
++		return -ENOMEM;
++	sf_g->name->size = size;
++	sf_g->name->length = size - 1;
++	strlcpy(sf_g->name->string.utf8, args->dev_name, size);
++
++	/* ~0 means use whatever the host gives as mode info */
++	sf_g->dmode = ~0;
++	sf_g->fmode = ~0;
++
++	err = vboxsf_parse_options(sf_g, args->options);
++	if (err)
++		goto fail_free;
++
++	/* Load nls if not utf8 */
++	if (strcmp(sf_g->nls_name, "utf8") != 0) {
++		if (sf_g->nls_name == vboxsf_default_nls)
++			sf_g->nls = load_nls_default();
++		else
++			sf_g->nls = load_nls(sf_g->nls_name);
++
++		if (!sf_g->nls) {
++			err = -EINVAL;
++			goto fail_free;
++		}
++	}
++
++	err = super_setup_bdi_name(sb, "vboxsf-%s", args->dev_name);
++	if (err)
++		goto fail_free;
++
++	err = vboxsf_map_folder(sf_g->name, &sf_g->root);
++	if (err)
++		goto fail_put_bdi;
++
++	root_path.length = 1;
++	root_path.size = 2;
++	strlcpy(root_path.string.utf8, "/",
++		sizeof(root_path) - SHFLSTRING_HEADER_SIZE);
++	err = vboxsf_stat(sf_g, &root_path, &sf_g->root_info);
++	if (err)
++		goto fail_unmap;
++
++	sb->s_magic = 0xface;
++	sb->s_blocksize = 1024;
++	sb->s_maxbytes = MAX_LFS_FILESIZE;
++	sb->s_op = &sf_super_ops;
++
++	iroot = iget_locked(sb, 0);
++	if (!iroot) {
++		err = -ENOMEM;
++		goto fail_unmap;
++	}
++	vboxsf_init_inode(sf_g, iroot, &sf_g->root_info);
++	unlock_new_inode(iroot);
++
++	droot = d_make_root(iroot);
++	if (!droot) {
++		err = -ENOMEM;
++		goto fail_unmap;
++	}
++
++	sb->s_root = droot;
++	SET_GLOB_INFO(sb, sf_g);
++	return 0;
++
++fail_unmap:
++	vboxsf_unmap_folder(sf_g->root);
++fail_put_bdi:
++	bdi_put(sb->s_bdi);
++fail_free:
++	if (sf_g->nls)
++		unload_nls(sf_g->nls);
++	if (sf_g->nls_name != vboxsf_default_nls)
++		kfree(sf_g->nls_name);
++	kfree(sf_g->name);
++	kfree(sf_g);
++	return err;
++}
++
++static void sf_inode_init_once(void *data)
++{
++	struct sf_inode_info *sf_i = (struct sf_inode_info *)data;
++
++	inode_init_once(&sf_i->vfs_inode);
++}
++
++static struct inode *sf_alloc_inode(struct super_block *sb)
++{
++	struct sf_inode_info *sf_i;
++
++	sf_i = kmem_cache_alloc(sf_inode_cachep, GFP_NOFS);
++	if (!sf_i)
++		return NULL;
++
++	sf_i->force_restat = 0;
++	sf_i->file = NULL;
++	sf_i->handle = SHFL_HANDLE_NIL;
++
++	return &sf_i->vfs_inode;
++}
++
++static void sf_i_callback(struct rcu_head *head)
++{
++	struct inode *inode = container_of(head, struct inode, i_rcu);
++
++	kmem_cache_free(sf_inode_cachep, GET_INODE_INFO(inode));
++}
++
++static void sf_destroy_inode(struct inode *inode)
++{
++	call_rcu(&inode->i_rcu, sf_i_callback);
++}
++
++/*
++ * vfs is done with [sb] (umount called) call [sf_glob_free] to unmap
++ * the folder and free [sf_g]
++ */
++static void sf_put_super(struct super_block *sb)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(sb);
++
++	generic_shutdown_super(sb);
++	vboxsf_unmap_folder(sf_g->root);
++	if (sf_g->nls)
++		unload_nls(sf_g->nls);
++	if (sf_g->nls_name != vboxsf_default_nls)
++		kfree(sf_g->nls_name);
++	kfree(sf_g->name);
++	kfree(sf_g);
++}
++
++static int sf_statfs(struct dentry *dentry, struct kstatfs *stat)
++{
++	struct super_block *sb = dentry->d_sb;
++	struct shfl_volinfo SHFLVolumeInfo;
++	struct sf_glob_info *sf_g;
++	u32 buf_len;
++	int err;
++
++	sf_g = GET_GLOB_INFO(sb);
++	buf_len = sizeof(SHFLVolumeInfo);
++	err = vboxsf_fsinfo(sf_g->root, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
++			    &buf_len, &SHFLVolumeInfo);
++	if (err)
++		return err;
++
++	stat->f_type = NFS_SUPER_MAGIC;	/* XXX vboxsf type? */
++	stat->f_bsize = SHFLVolumeInfo.bytes_per_allocation_unit;
++
++	do_div(SHFLVolumeInfo.total_allocation_bytes,
++	       SHFLVolumeInfo.bytes_per_allocation_unit);
++	stat->f_blocks = SHFLVolumeInfo.total_allocation_bytes;
++
++	do_div(SHFLVolumeInfo.available_allocation_bytes,
++	       SHFLVolumeInfo.bytes_per_allocation_unit);
++	stat->f_bfree  = SHFLVolumeInfo.available_allocation_bytes;
++	stat->f_bavail = SHFLVolumeInfo.available_allocation_bytes;
++
++	stat->f_files = 1000;
++	/*
++	 * Don't return 0 here since the guest may then think that it is not
++	 * possible to create any more files.
++	 */
++	stat->f_ffree = 1000;
++	stat->f_fsid.val[0] = 0;
++	stat->f_fsid.val[1] = 0;
++	stat->f_namelen = 255;
++	return 0;
++}
++
++static int sf_remount_fs(struct super_block *sb, int *flags, char *options)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(sb);
++	struct inode *iroot;
++	int err;
++
++	err = vboxsf_parse_options(sf_g, options);
++	if (err)
++		return err;
++
++	iroot = ilookup(sb, 0);
++	if (!iroot)
++		return -ENOENT;
++
++	/* Apply changed options to the root inode */
++	vboxsf_init_inode(sf_g, iroot, &sf_g->root_info);
++
++	return 0;
++}
++
++static struct super_operations sf_super_ops = {
++	.alloc_inode	= sf_alloc_inode,
++	.destroy_inode	= sf_destroy_inode,
++	.put_super	= sf_put_super,
++	.statfs		= sf_statfs,
++	.remount_fs	= sf_remount_fs
++};
++
++static struct dentry *sf_mount(struct file_system_type *fs_type, int flags,
++			       const char *dev_name, void *data)
++{
++	struct fill_super_args args = {
++		.dev_name = dev_name,
++		.options = data,
++	};
++
++	return mount_nodev(fs_type, flags, &args, sf_fill_super);
++}
++
++static struct file_system_type vboxsf_fs_type = {
++	.owner = THIS_MODULE,
++	.name = "vboxsf",
++	.mount = sf_mount,
++	.kill_sb = kill_anon_super
++};
++
++/* Module initialization/finalization handlers */
++static int __init init(void)
++{
++	int err;
++
++	sf_inode_cachep = kmem_cache_create("vboxsf_inode_cache",
++					     sizeof(struct sf_inode_info),
++					     0, (SLAB_RECLAIM_ACCOUNT|
++						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
++					     sf_inode_init_once);
++	if (sf_inode_cachep == NULL)
++		return -ENOMEM;
++
++	err = register_filesystem(&vboxsf_fs_type);
++	if (err)
++		return err;
++
++	err = vboxsf_connect();
++	if (err) {
++		vbg_err("vboxsf: err %d connecting to guest PCI-device\n", err);
++		vbg_err("vboxsf: make sure you are inside a VirtualBox VM\n");
++		vbg_err("vboxsf: and check dmesg for vboxguest errors\n");
++		goto fail_unregisterfs;
++	}
++
++	err = vboxsf_set_utf8();
++	if (err) {
++		vbg_err("vboxsf_setutf8 error %d\n", err);
++		goto fail_disconnect;
++	}
++
++	if (!follow_symlinks) {
++		err = vboxsf_set_symlinks();
++		if (err)
++			vbg_warn("vboxsf: Unable to show symlinks: %d\n", err);
++	}
++
++	return 0;
++
++fail_disconnect:
++	vboxsf_disconnect();
++fail_unregisterfs:
++	unregister_filesystem(&vboxsf_fs_type);
++	return err;
++}
++
++static void __exit fini(void)
++{
++	vboxsf_disconnect();
++	unregister_filesystem(&vboxsf_fs_type);
++	/*
++	 * Make sure all delayed rcu free inodes are flushed before we
++	 * destroy cache.
++	 */
++	rcu_barrier();
++	kmem_cache_destroy(sf_inode_cachep);
++}
++
++module_init(init);
++module_exit(fini);
++
++MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access");
++MODULE_AUTHOR("Oracle Corporation");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS_FS("vboxsf");
+diff --git a/fs/vboxsf/utils.c b/fs/vboxsf/utils.c
+new file mode 100644
+index 000000000000..c4bbc8ec0074
+--- /dev/null
++++ b/fs/vboxsf/utils.c
+@@ -0,0 +1,520 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * VirtualBox Guest Shared Folders support: Utility functions.
++ * Mainly conversion from/to VirtualBox/Linux data structures.
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#include <linux/namei.h>
++#include <linux/nls.h>
++#include <linux/sizes.h>
++#include <linux/vfs.h>
++#include "vfsmod.h"
++
++/* set [inode] attributes based on [info], uid/gid based on [sf_g] */
++void vboxsf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
++		       const struct shfl_fsobjinfo *info)
++{
++	const struct shfl_fsobjattr *attr;
++	s64 allocated;
++	int mode;
++
++	attr = &info->attr;
++
++#define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)
++
++	mode = mode_set(IRUSR);
++	mode |= mode_set(IWUSR);
++	mode |= mode_set(IXUSR);
++
++	mode |= mode_set(IRGRP);
++	mode |= mode_set(IWGRP);
++	mode |= mode_set(IXGRP);
++
++	mode |= mode_set(IROTH);
++	mode |= mode_set(IWOTH);
++	mode |= mode_set(IXOTH);
++
++#undef mode_set
++
++	/* We use the host-side values for these */
++	inode->i_flags |= S_NOATIME | S_NOCMTIME;
++	inode->i_mapping->a_ops = &vboxsf_reg_aops;
++
++	if (SHFL_IS_DIRECTORY(attr->mode)) {
++		inode->i_mode = sf_g->dmode != ~0 ? (sf_g->dmode & 0777) : mode;
++		inode->i_mode &= ~sf_g->dmask;
++		inode->i_mode |= S_IFDIR;
++		inode->i_op = &vboxsf_dir_iops;
++		inode->i_fop = &vboxsf_dir_fops;
++		/*
++		 * XXX: this probably should be set to the number of entries
++		 * in the directory plus two (. ..)
++		 */
++		set_nlink(inode, 1);
++	} else if (SHFL_IS_SYMLINK(attr->mode)) {
++		inode->i_mode = sf_g->fmode != ~0 ? (sf_g->fmode & 0777) : mode;
++		inode->i_mode &= ~sf_g->fmask;
++		inode->i_mode |= S_IFLNK;
++		inode->i_op = &vboxsf_lnk_iops;
++		set_nlink(inode, 1);
++	} else {
++		inode->i_mode = sf_g->fmode != ~0 ? (sf_g->fmode & 0777) : mode;
++		inode->i_mode &= ~sf_g->fmask;
++		inode->i_mode |= S_IFREG;
++		inode->i_op = &vboxsf_reg_iops;
++		inode->i_fop = &vboxsf_reg_fops;
++		set_nlink(inode, 1);
++	}
++
++	inode->i_uid = make_kuid(current_user_ns(), sf_g->uid);
++	inode->i_gid = make_kgid(current_user_ns(), sf_g->gid);
++
++	inode->i_size = info->size;
++	inode->i_blkbits = 12;
++	/* i_blocks always in units of 512 bytes! */
++	allocated = info->allocated + 511;
++	do_div(allocated, 512);
++	inode->i_blocks = allocated;
++
++	inode->i_atime = ns_to_timespec(
++				 info->access_time.ns_relative_to_unix_epoch);
++	inode->i_ctime = ns_to_timespec(
++				 info->change_time.ns_relative_to_unix_epoch);
++	inode->i_mtime = ns_to_timespec(
++			   info->modification_time.ns_relative_to_unix_epoch);
++}
++
++int vboxsf_create_at_dentry(struct dentry *dentry,
++			    struct shfl_createparms *params)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(dentry->d_sb);
++	struct shfl_string *path;
++	int err;
++
++	path = vboxsf_path_from_dentry(sf_g, dentry);
++	if (IS_ERR(path))
++		return PTR_ERR(path);
++
++	err = vboxsf_create(sf_g->root, path, params);
++	__putname(path);
++
++	return err;
++}
++
++int vboxsf_stat(struct sf_glob_info *sf_g, struct shfl_string *path,
++		struct shfl_fsobjinfo *info)
++{
++	struct shfl_createparms params = {};
++	int err;
++
++	params.handle = SHFL_HANDLE_NIL;
++	params.create_flags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
++
++	err = vboxsf_create(sf_g->root, path, &params);
++	if (err)
++		return err;
++
++	if (params.result != SHFL_FILE_EXISTS)
++		return -ENOENT;
++
++	if (info)
++		*info = params.info;
++
++	return 0;
++}
++
++int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(dentry->d_sb);
++	struct shfl_string *path;
++	int err;
++
++	path = vboxsf_path_from_dentry(sf_g, dentry);
++	if (IS_ERR(path))
++		return PTR_ERR(path);
++
++	err = vboxsf_stat(sf_g, path, info);
++	__putname(path);
++	return err;
++}
++
++int vboxsf_inode_revalidate(struct dentry *dentry)
++{
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(dentry->d_sb);
++	struct sf_inode_info *sf_i;
++	struct shfl_fsobjinfo info;
++	struct timespec prev_mtime;
++	struct inode *inode;
++	int err;
++
++	if (!dentry || !d_really_is_positive(dentry))
++		return -EINVAL;
++
++	inode = d_inode(dentry);
++	prev_mtime = inode->i_mtime;
++	sf_i = GET_INODE_INFO(inode);
++	if (!sf_i->force_restat) {
++		if (time_before(jiffies, dentry->d_time + sf_g->ttl))
++			return 0;
++	}
++
++	err = vboxsf_stat_dentry(dentry, &info);
++	if (err)
++		return err;
++
++	dentry->d_time = jiffies;
++	sf_i->force_restat = 0;
++	vboxsf_init_inode(sf_g, inode, &info);
++
++	/*
++	 * mmap()-ed files use the page-cache, if the file was changed on the
++	 * host side we need to invalidate the page-cache for it.  Note this
++	 * also gets triggered by our own writes, this is unavoidable.
++	 */
++	if (timespec_compare(&inode->i_mtime, &prev_mtime) > 0)
++		invalidate_mapping_pages(inode->i_mapping, 0, -1);
++
++	return 0;
++}
++
++int vboxsf_getattr(const struct path *path, struct kstat *kstat,
++		   u32 request_mask, unsigned int flags)
++{
++	int err;
++	struct dentry *dentry = path->dentry;
++
++	err = vboxsf_inode_revalidate(dentry);
++	if (err)
++		return err;
++
++	generic_fillattr(d_inode(dentry), kstat);
++	return 0;
++}
++
++int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr)
++{
++	struct sf_inode_info *sf_i = GET_INODE_INFO(d_inode(dentry));
++	struct sf_glob_info *sf_g = GET_GLOB_INFO(dentry->d_sb);
++	struct shfl_createparms params = {};
++	struct shfl_fsobjinfo info = {};
++	uint32_t buf_len;
++	int err;
++
++	params.handle = SHFL_HANDLE_NIL;
++	params.create_flags = SHFL_CF_ACT_OPEN_IF_EXISTS |
++			      SHFL_CF_ACT_FAIL_IF_NEW |
++			      SHFL_CF_ACCESS_ATTR_WRITE;
++
++	/* this is at least required for Posix hosts */
++	if (iattr->ia_valid & ATTR_SIZE)
++		params.create_flags |= SHFL_CF_ACCESS_WRITE;
++
++	err = vboxsf_create_at_dentry(dentry, &params);
++	if (err || params.result != SHFL_FILE_EXISTS)
++		return err ? err : -ENOENT;
++
++#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
++
++	/*
++	 * Setting the file size and setting the other attributes has to
++	 * be handled separately.
++	 */
++	if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) {
++		if (iattr->ia_valid & ATTR_MODE) {
++			info.attr.mode = mode_set(IRUSR);
++			info.attr.mode |= mode_set(IWUSR);
++			info.attr.mode |= mode_set(IXUSR);
++			info.attr.mode |= mode_set(IRGRP);
++			info.attr.mode |= mode_set(IWGRP);
++			info.attr.mode |= mode_set(IXGRP);
++			info.attr.mode |= mode_set(IROTH);
++			info.attr.mode |= mode_set(IWOTH);
++			info.attr.mode |= mode_set(IXOTH);
++
++			if (iattr->ia_mode & S_IFDIR)
++				info.attr.mode |= SHFL_TYPE_DIRECTORY;
++			else
++				info.attr.mode |= SHFL_TYPE_FILE;
++		}
++
++		if (iattr->ia_valid & ATTR_ATIME)
++			info.access_time.ns_relative_to_unix_epoch =
++					    timespec_to_ns(&iattr->ia_atime);
++
++		if (iattr->ia_valid & ATTR_MTIME)
++			info.modification_time.ns_relative_to_unix_epoch =
++					    timespec_to_ns(&iattr->ia_mtime);
++
++		/*
++		 * Ignore ctime (inode change time) as it can't be set
++		 * from userland anyway.
++		 */
++
++		buf_len = sizeof(info);
++		err = vboxsf_fsinfo(sf_g->root, params.handle,
++				   SHFL_INFO_SET | SHFL_INFO_FILE, &buf_len,
++				   &info);
++		if (err) {
++			vboxsf_close(sf_g->root, params.handle);
++			return err;
++		}
++
++		/* the host may have given us different attr then requested */
++		sf_i->force_restat = 1;
++	}
++
++#undef mode_set
++
++	if (iattr->ia_valid & ATTR_SIZE) {
++		memset(&info, 0, sizeof(info));
++		info.size = iattr->ia_size;
++		buf_len = sizeof(info);
++		err = vboxsf_fsinfo(sf_g->root, params.handle,
++				   SHFL_INFO_SET | SHFL_INFO_SIZE, &buf_len,
++				   &info);
++		if (err) {
++			vboxsf_close(sf_g->root, params.handle);
++			return err;
++		}
++
++		/* the host may have given us different attr then requested */
++		sf_i->force_restat = 1;
++	}
++
++	vboxsf_close(sf_g->root, params.handle);
++
++	/* Update the inode with what the host has actually given us. */
++	if (sf_i->force_restat)
++		vboxsf_inode_revalidate(dentry);
++
++	return 0;
++}
++
++/*
++ * [dentry] contains string encoded in coding system that corresponds
++ * to [sf_g]->nls, we must convert it to UTF8 here.
++ * Returns a shfl_string allocated through __getname (must be freed using
++ * __putname), or an ERR_PTR on error.
++ */
++struct shfl_string *vboxsf_path_from_dentry(struct sf_glob_info *sf_g,
++					    struct dentry *dentry)
++{
++	struct shfl_string *shfl_path;
++	int path_len, out_len, nb;
++	char *buf, *path;
++	wchar_t uni;
++	u8 *out;
++
++	buf = __getname();
++	if (!buf)
++		return ERR_PTR(-ENOMEM);
++
++	path = dentry_path_raw(dentry, buf, PATH_MAX);
++	if (IS_ERR(path)) {
++		__putname(buf);
++		return (struct shfl_string *)path;
++	}
++	path_len = strlen(path);
++
++	if (sf_g->nls) {
++		shfl_path = __getname();
++		if (!shfl_path) {
++			__putname(buf);
++			return ERR_PTR(-ENOMEM);
++		}
++
++		out = shfl_path->string.utf8;
++		out_len = PATH_MAX - SHFLSTRING_HEADER_SIZE - 1;
++
++		while (path_len) {
++			nb = sf_g->nls->char2uni(path, path_len, &uni);
++			if (nb < 0) {
++				__putname(shfl_path);
++				__putname(buf);
++				return ERR_PTR(-EINVAL);
++			}
++			path += nb;
++			path_len -= nb;
++
++			nb = utf32_to_utf8(uni, out, out_len);
++			if (nb < 0) {
++				__putname(shfl_path);
++				__putname(buf);
++				return ERR_PTR(-ENAMETOOLONG);
++			}
++			out += nb;
++			out_len -= nb;
++		}
++		*out = 0;
++		shfl_path->length = out - shfl_path->string.utf8;
++		shfl_path->size = shfl_path->length + 1;
++		__putname(buf);
++	} else {
++		if ((SHFLSTRING_HEADER_SIZE + path_len + 1) > PATH_MAX) {
++			__putname(buf);
++			return ERR_PTR(-ENAMETOOLONG);
++		}
++		/*
++		 * dentry_path stores the name at the end of buf, but the
++		 * shfl_string string we return must be properly aligned.
++		 */
++		shfl_path = (struct shfl_string *)buf;
++		memmove(shfl_path->string.utf8, path, path_len);
++		shfl_path->string.utf8[path_len] = 0;
++		shfl_path->length = path_len;
++		shfl_path->size = path_len + 1;
++	}
++
++	return shfl_path;
++}
++
++int vboxsf_nlscpy(struct sf_glob_info *sf_g, char *name, size_t name_bound_len,
++		  const unsigned char *utf8_name, size_t utf8_len)
++{
++	if (sf_g->nls) {
++		const char *in;
++		char *out;
++		size_t out_len;
++		size_t out_bound_len;
++		size_t in_bound_len;
++
++		in = utf8_name;
++		in_bound_len = utf8_len;
++
++		out = name;
++		out_len = 0;
++		out_bound_len = name_bound_len;
++
++		while (in_bound_len) {
++			int nb;
++			unicode_t uni;
++
++			nb = utf8_to_utf32(in, in_bound_len, &uni);
++			if (nb < 0)
++				return -EINVAL;
++
++			in += nb;
++			in_bound_len -= nb;
++
++			nb = sf_g->nls->uni2char(uni, out, out_bound_len);
++			if (nb < 0)
++				return nb;
++
++			out += nb;
++			out_bound_len -= nb;
++			out_len += nb;
++		}
++
++		*out = 0;
++	} else {
++		if (utf8_len + 1 > name_bound_len)
++			return -ENAMETOOLONG;
++
++		memcpy(name, utf8_name, utf8_len + 1);
++	}
++	return 0;
++}
++
++static struct sf_dir_buf *sf_dir_buf_alloc(struct list_head *list)
++{
++	struct sf_dir_buf *b;
++
++	b = kmalloc(sizeof(*b), GFP_KERNEL);
++	if (!b)
++		return NULL;
++
++	b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL);
++	if (!b->buf) {
++		kfree(b);
++		return NULL;
++	}
++
++	b->entries = 0;
++	b->used = 0;
++	b->free = DIR_BUFFER_SIZE;
++	list_add(&b->head, list);
++
++	return b;
++}
++
++static void sf_dir_buf_free(struct sf_dir_buf *b)
++{
++	list_del(&b->head);
++	kfree(b->buf);
++	kfree(b);
++}
++
++/**
++ * Create a new directory buffer descriptor.
++ * Return: Created sf_dir_info buffer, or NULL when malloc fails
++ */
++struct sf_dir_info *vboxsf_dir_info_alloc(void)
++{
++	struct sf_dir_info *p;
++
++	p = kmalloc(sizeof(*p), GFP_KERNEL);
++	if (!p)
++		return NULL;
++
++	INIT_LIST_HEAD(&p->info_list);
++	return p;
++}
++
++/**
++ * Free the directory buffer.
++ * @p		sf_dir_info buffer to free
++ */
++void vboxsf_dir_info_free(struct sf_dir_info *p)
++{
++	struct list_head *list, *pos, *tmp;
++
++	list = &p->info_list;
++	list_for_each_safe(pos, tmp, list) {
++		struct sf_dir_buf *b;
++
++		b = list_entry(pos, struct sf_dir_buf, head);
++		sf_dir_buf_free(b);
++	}
++	kfree(p);
++}
++
++int vboxsf_dir_read_all(struct sf_glob_info *sf_g, struct sf_dir_info *sf_d,
++			u64 handle)
++{
++	struct sf_dir_buf *b;
++	u32 entries, size;
++	int err = 0;
++	void *buf;
++
++	/* vboxsf_dirinfo returns 1 on end of dir */
++	while (err == 0) {
++		b = sf_dir_buf_alloc(&sf_d->info_list);
++		if (!b) {
++			err = -ENOMEM;
++			break;
++		}
++
++		buf = b->buf;
++		size = b->free;
++
++		err = vboxsf_dirinfo(sf_g->root, handle, NULL, 0, 0,
++				     &size, buf, &entries);
++		if (err < 0)
++			break;
++
++		b->entries += entries;
++		b->free -= size;
++		b->used += size;
++	}
++
++	if (b && b->used == 0)
++		sf_dir_buf_free(b);
++
++	/* -EILSEQ means the host could not translate a filename, ignore */
++	if (err > 0 || err == -EILSEQ)
++		err = 0;
++
++	return err;
++}
+diff --git a/fs/vboxsf/vboxsf_wrappers.c b/fs/vboxsf/vboxsf_wrappers.c
+new file mode 100644
+index 000000000000..22fdb2f3186e
+--- /dev/null
++++ b/fs/vboxsf/vboxsf_wrappers.c
+@@ -0,0 +1,370 @@
++// SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0)
++/*
++ * Wrapper functions for the shfl host calls.
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/vbox_err.h>
++#include <linux/vbox_utils.h>
++#include "vfsmod.h"
++
++static u32 vboxsf_client_id;
++
++int vboxsf_connect(void)
++{
++	struct vbg_dev *gdev;
++	struct vmmdev_hgcm_service_location loc;
++	int err, vbox_status;
++
++	loc.type = VMMDEV_HGCM_LOC_LOCALHOST_EXISTING;
++	strcpy(loc.u.localhost.service_name, "VBoxSharedFolders");
++
++	gdev = vbg_get_gdev();
++	if (IS_ERR(gdev))
++		return -ENODEV;	/* No guest-device */
++
++	err = vbg_hgcm_connect(gdev, &loc, &vboxsf_client_id, &vbox_status);
++	vbg_put_gdev(gdev);
++
++	return err ? err : vbg_status_code_to_errno(vbox_status);
++}
++
++void vboxsf_disconnect(void)
++{
++	struct vbg_dev *gdev;
++	int vbox_status;
++
++	gdev = vbg_get_gdev();
++	if (IS_ERR(gdev))
++		return;   /* guest-device is gone, already disconnected */
++
++	vbg_hgcm_disconnect(gdev, vboxsf_client_id, &vbox_status);
++	vbg_put_gdev(gdev);
++}
++
++static int vboxsf_call(u32 function, void *parms, u32 parm_count, int *status)
++{
++	struct vbg_dev *gdev;
++	int err, vbox_status;
++
++	gdev = vbg_get_gdev();
++	if (IS_ERR(gdev))
++		return -ESHUTDOWN; /* guest-dev removed underneath us */
++
++	err = vbg_hgcm_call(gdev, vboxsf_client_id, function, U32_MAX,
++			    parms, parm_count, &vbox_status);
++	vbg_put_gdev(gdev);
++
++	if (err < 0)
++		return err;
++
++	if (status)
++		*status = vbox_status;
++
++	return vbg_status_code_to_errno(vbox_status);
++}
++
++int vboxsf_map_folder(struct shfl_string *folder_name, u32 *root)
++{
++	struct shfl_map_folder parms;
++	int err, status;
++
++	parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
++	parms.path.u.pointer.size = shfl_string_buf_size(folder_name);
++	parms.path.u.pointer.u.linear_addr = (uintptr_t)folder_name;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = 0;
++
++	parms.delimiter.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.delimiter.u.value32 = '/';
++
++	parms.case_sensitive.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.case_sensitive.u.value32 = 1;
++
++	err = vboxsf_call(SHFL_FN_MAP_FOLDER, &parms, SHFL_CPARMS_MAP_FOLDER,
++			  &status);
++	if (err == -ENOSYS && status == VERR_NOT_IMPLEMENTED)
++		vbg_err("%s: Error host is too old\n", __func__);
++
++	*root = parms.root.u.value32;
++	return err;
++}
++
++int vboxsf_unmap_folder(u32 root)
++{
++	struct shfl_unmap_folder parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	return vboxsf_call(SHFL_FN_UNMAP_FOLDER, &parms,
++			   SHFL_CPARMS_UNMAP_FOLDER, NULL);
++}
++
++/**
++ * Create a new file or folder or open an existing one in a shared folder.
++ * Note this function always returns 0 / success unless an exceptional condition
++ * occurs - out of memory, invalid arguments, etc. If the file or folder could
++ * not be opened or created, create_parms->handle will be set to
++ * SHFL_HANDLE_NIL on return.  In this case the value in create_parms->result
++ * provides information as to why (e.g. SHFL_FILE_EXISTS), create_parms->result
++ * is also set on success as additional information.
++ * Return: 0 or negative errno value.
++ * @root	Root of the shared folder in which to create the file
++ * @parsed_path	The path of the file or folder relative to the shared folder
++ * @param	create_parms Parameters for file/folder creation.
++ */
++int vboxsf_create(u32 root, struct shfl_string *parsed_path,
++		  struct shfl_createparms *create_parms)
++{
++	struct shfl_create parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
++	parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
++	parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
++
++	parms.parms.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
++	parms.parms.u.pointer.size = sizeof(struct shfl_createparms);
++	parms.parms.u.pointer.u.linear_addr = (uintptr_t)create_parms;
++
++	return vboxsf_call(SHFL_FN_CREATE, &parms, SHFL_CPARMS_CREATE, NULL);
++}
++
++int vboxsf_close(u32 root, u64 handle)
++{
++	struct shfl_close parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.handle.u.value64 = handle;
++
++	return vboxsf_call(SHFL_FN_CLOSE, &parms, SHFL_CPARMS_CLOSE, NULL);
++}
++
++int vboxsf_remove(u32 root, struct shfl_string *parsed_path, u32 flags)
++{
++	struct shfl_remove parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
++	parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
++
++	parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.flags.u.value32 = flags;
++
++	return vboxsf_call(SHFL_FN_REMOVE, &parms, SHFL_CPARMS_REMOVE, NULL);
++}
++
++int vboxsf_rename(u32 root, struct shfl_string *src_path,
++		  struct shfl_string *dest_path, u32 flags)
++{
++	struct shfl_rename parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.src.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.src.u.pointer.size = shfl_string_buf_size(src_path);
++	parms.src.u.pointer.u.linear_addr = (uintptr_t)src_path;
++
++	parms.dest.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.dest.u.pointer.size = shfl_string_buf_size(dest_path);
++	parms.dest.u.pointer.u.linear_addr = (uintptr_t)dest_path;
++
++	parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.flags.u.value32 = flags;
++
++	return vboxsf_call(SHFL_FN_RENAME, &parms, SHFL_CPARMS_RENAME, NULL);
++}
++
++int vboxsf_read(u32 root, u64 handle, u64 offset,
++		u32 *buf_len, u8 *buf, bool user)
++{
++	struct shfl_read parms;
++	int err;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.handle.u.value64 = handle;
++	parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.offset.u.value64 = offset;
++	parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.cb.u.value32 = *buf_len;
++	if (user)
++		parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_OUT;
++	else
++		parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
++	parms.buffer.u.pointer.size = *buf_len;
++	parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	err = vboxsf_call(SHFL_FN_READ, &parms, SHFL_CPARMS_READ, NULL);
++
++	*buf_len = parms.cb.u.value32;
++	return err;
++}
++
++int vboxsf_write(u32 root, u64 handle, u64 offset,
++		 u32 *buf_len, const u8 *buf, bool user)
++{
++	struct shfl_write parms;
++	int err;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.handle.u.value64 = handle;
++	parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.offset.u.value64 = offset;
++	parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.cb.u.value32 = *buf_len;
++	if (user)
++		parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_IN;
++	else
++		parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.buffer.u.pointer.size = *buf_len;
++	parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	err = vboxsf_call(SHFL_FN_WRITE, &parms, SHFL_CPARMS_WRITE, NULL);
++
++	*buf_len = parms.cb.u.value32;
++	return err;
++}
++
++/* Returns 0 on success, 1 on end-of-dir, negative errno otherwise */
++int vboxsf_dirinfo(u32 root, u64 handle,
++		   struct shfl_string *parsed_path, u32 flags, u32 index,
++		   u32 *buf_len, struct shfl_dirinfo *buf, u32 *file_count)
++{
++	struct shfl_list parms;
++	int err, status;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.handle.u.value64 = handle;
++	parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.flags.u.value32 = flags;
++	parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.cb.u.value32 = *buf_len;
++	if (parsed_path) {
++		parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++		parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
++		parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
++	} else {
++		parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_IN;
++		parms.path.u.pointer.size = 0;
++		parms.path.u.pointer.u.linear_addr = 0;
++	}
++
++	parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
++	parms.buffer.u.pointer.size = *buf_len;
++	parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	parms.resume_point.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.resume_point.u.value32 = index;
++	parms.file_count.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.file_count.u.value32 = 0;	/* out parameter only */
++
++	err = vboxsf_call(SHFL_FN_LIST, &parms, SHFL_CPARMS_LIST, &status);
++	if (err == -ENODATA && status == VERR_NO_MORE_FILES)
++		err = 1;
++
++	*buf_len = parms.cb.u.value32;
++	*file_count = parms.file_count.u.value32;
++	return err;
++}
++
++int vboxsf_fsinfo(u32 root, u64 handle, u32 flags,
++		  u32 *buf_len, void *buf)
++{
++	struct shfl_information parms;
++	int err;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
++	parms.handle.u.value64 = handle;
++	parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.flags.u.value32 = flags;
++	parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.cb.u.value32 = *buf_len;
++	parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
++	parms.info.u.pointer.size = *buf_len;
++	parms.info.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	err = vboxsf_call(SHFL_FN_INFORMATION, &parms, SHFL_CPARMS_INFORMATION,
++			  NULL);
++
++	*buf_len = parms.cb.u.value32;
++	return err;
++}
++
++int vboxsf_readlink(u32 root, struct shfl_string *parsed_path,
++		    u32 buf_len, u8 *buf)
++{
++	struct shfl_readLink parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
++	parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
++
++	parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
++	parms.buffer.u.pointer.size = buf_len;
++	parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	return vboxsf_call(SHFL_FN_READLINK, &parms, SHFL_CPARMS_READLINK,
++			   NULL);
++}
++
++int vboxsf_symlink(u32 root, struct shfl_string *new_path,
++		   struct shfl_string *old_path, struct shfl_fsobjinfo *buf)
++{
++	struct shfl_symlink parms;
++
++	parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
++	parms.root.u.value32 = root;
++
++	parms.new_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.new_path.u.pointer.size = shfl_string_buf_size(new_path);
++	parms.new_path.u.pointer.u.linear_addr = (uintptr_t)new_path;
++
++	parms.old_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
++	parms.old_path.u.pointer.size = shfl_string_buf_size(old_path);
++	parms.old_path.u.pointer.u.linear_addr = (uintptr_t)old_path;
++
++	parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
++	parms.info.u.pointer.size = sizeof(struct shfl_fsobjinfo);
++	parms.info.u.pointer.u.linear_addr = (uintptr_t)buf;
++
++	return vboxsf_call(SHFL_FN_SYMLINK, &parms, SHFL_CPARMS_SYMLINK, NULL);
++}
++
++int vboxsf_set_utf8(void)
++{
++	return vboxsf_call(SHFL_FN_SET_UTF8, NULL, 0, NULL);
++}
++
++int vboxsf_set_symlinks(void)
++{
++	return vboxsf_call(SHFL_FN_SET_SYMLINKS, NULL, 0, NULL);
++}
+diff --git a/fs/vboxsf/vfsmod.h b/fs/vboxsf/vfsmod.h
+new file mode 100644
+index 000000000000..20efcb77232d
+--- /dev/null
++++ b/fs/vboxsf/vfsmod.h
+@@ -0,0 +1,133 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * VirtualBox Guest Shared Folders support: module header.
++ *
++ * Copyright (C) 2006-2016 Oracle Corporation
++ */
++
++#ifndef VFSMOD_H
++#define VFSMOD_H
++
++#include <linux/backing-dev.h>
++#include <linux/version.h>
++#include "shfl_hostintf.h"
++
++#define DIR_BUFFER_SIZE SZ_16K
++
++/* The cast is to prevent assignment of void * to pointers of arbitrary type */
++#define GET_GLOB_INFO(sb)       ((struct sf_glob_info *)(sb)->s_fs_info)
++#define SET_GLOB_INFO(sb, sf_g) ((sb)->s_fs_info = (sf_g))
++#define GET_INODE_INFO(i)       container_of(i, struct sf_inode_info, vfs_inode)
++
++/* per-shared folder information */
++struct sf_glob_info {
++	struct shfl_fsobjinfo root_info;
++	struct nls_table *nls;
++	u32 root;
++	/* mount options */
++	struct shfl_string *name;
++	char *nls_name;
++	int ttl;
++	int uid;
++	int gid;
++	int dmode;
++	int fmode;
++	int dmask;
++	int fmask;
++};
++
++/* per-inode information */
++struct sf_inode_info {
++	/* some information was changed, update data on next revalidate */
++	int force_restat;
++	/* file structure, only valid between open() and release() */
++	struct file *file;
++	/*
++	 * handle valid if a file was created with sf_create_aux until it
++	 * will be opened with sf_reg_open()
++	 */
++	u64 handle;
++	/* The VFS inode struct */
++	struct inode vfs_inode;
++};
++
++struct sf_dir_info {
++	struct list_head info_list;
++};
++
++struct sf_dir_buf {
++	size_t entries;
++	size_t free;
++	size_t used;
++	void *buf;
++	struct list_head head;
++};
++
++struct sf_reg_info {
++	u64 handle;
++};
++
++/* globals */
++extern const struct inode_operations vboxsf_dir_iops;
++extern const struct inode_operations vboxsf_lnk_iops;
++extern const struct inode_operations vboxsf_reg_iops;
++extern const struct file_operations vboxsf_dir_fops;
++extern const struct file_operations vboxsf_reg_fops;
++extern const struct address_space_operations vboxsf_reg_aops;
++
++/* from utils.c */
++void vboxsf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
++		       const struct shfl_fsobjinfo *info);
++int vboxsf_create_at_dentry(struct dentry *dentry,
++			    struct shfl_createparms *params);
++int vboxsf_stat(struct sf_glob_info *sf_g, struct shfl_string *path,
++		struct shfl_fsobjinfo *info);
++int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info);
++int vboxsf_inode_revalidate(struct dentry *dentry);
++int vboxsf_getattr(const struct path *path, struct kstat *kstat,
++		   u32 request_mask, unsigned int query_flags);
++int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr);
++struct shfl_string *vboxsf_path_from_dentry(struct sf_glob_info *sf_g,
++					    struct dentry *dentry);
++int vboxsf_nlscpy(struct sf_glob_info *sf_g, char *name, size_t name_bound_len,
++		  const unsigned char *utf8_name, size_t utf8_len);
++struct sf_dir_info *vboxsf_dir_info_alloc(void);
++void vboxsf_dir_info_free(struct sf_dir_info *p);
++int vboxsf_dir_read_all(struct sf_glob_info *sf_g, struct sf_dir_info *sf_d,
++			u64 handle);
++
++/* from vboxsf_wrappers.c */
++int vboxsf_connect(void);
++void vboxsf_disconnect(void);
++
++int vboxsf_create(u32 root, struct shfl_string *parsed_path,
++		  struct shfl_createparms *create_parms);
++
++int vboxsf_close(u32 root, u64 handle);
++int vboxsf_remove(u32 root, struct shfl_string *parsed_path, u32 flags);
++int vboxsf_rename(u32 root, struct shfl_string *src_path,
++		  struct shfl_string *dest_path, u32 flags);
++
++int vboxsf_read(u32 root, u64 handle, u64 offset,
++		u32 *buf_len, u8 *buf, bool user);
++int vboxsf_write(u32 root, u64 handle, u64 offset,
++		 u32 *buf_len, const u8 *buf, bool user);
++
++int vboxsf_dirinfo(u32 root, u64 handle,
++		   struct shfl_string *parsed_path, u32 flags, u32 index,
++		   u32 *buf_len, struct shfl_dirinfo *buf, u32 *file_count);
++int vboxsf_fsinfo(u32 root, u64 handle, u32 flags,
++		  u32 *buf_len, void *buf);
++
++int vboxsf_map_folder(struct shfl_string *folder_name, u32 *root);
++int vboxsf_unmap_folder(u32 root);
++
++int vboxsf_readlink(u32 root, struct shfl_string *parsed_path,
++		    u32 buf_len, u8 *buf);
++int vboxsf_symlink(u32 root, struct shfl_string *new_path,
++		   struct shfl_string *old_path, struct shfl_fsobjinfo *buf);
++
++int vboxsf_set_utf8(void);
++int vboxsf_set_symlinks(void);
++
++#endif
diff --git a/x86_64-common.config b/x86_64-common.config
index d0f38c1..376276b 100644
--- a/x86_64-common.config
+++ b/x86_64-common.config
@@ -185,6 +185,7 @@ CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m
 CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m
 CONFIG_UCSI_ACPI=m
 CONFIG_DRM_VBOXVIDEO=m
+CONFIG_VBOXSF_FS=m
 CONFIG_WMI_BMOF=m
 CONFIG_PEAQ_WMI=m
 CONFIG_INTEL_INT0002_VGPIO=m
@@ -204,7 +205,7 @@ CONFIG_HMM_MIRROR=y
 CONFIG_DEVICE_PRIVATE=y
 CONFIG_DEVICE_PUBLIC=y
 CONFIG_HYPERV_VSOCKETS=m
-CONFIG_SPI_INTEL_SPI_PCI=m
+# CONFIG_SPI_INTEL_SPI_PCI is not set
 CONFIG_HINIC=m
 CONFIG_PINCTRL_DENVERTON=m
 CONFIG_PINCTRL_LEWISBURG=m
@@ -242,3 +243,23 @@ CONFIG_INTEL_WMI_THUNDERBOLT=m
 CONFIG_RPMSG_VIRTIO=m
 CONFIG_PAGE_TABLE_ISOLATION=y
 CONFIG_RETPOLINE=y
+CONFIG_JAILHOUSE_GUEST=y
+CONFIG_ACPI_SPCR_TABLE=y
+CONFIG_CAVIUM_PTP=m
+CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m
+CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH=m
+CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH=m
+CONFIG_MMC_SDHCI_F_SDH30=m
+CONFIG_VBOXGUEST=m
+CONFIG_ACER_WIRELESS=m
+CONFIG_DELL_SMBIOS_WMI=y
+CONFIG_DELL_SMBIOS_SMM=y
+CONFIG_GPD_POCKET_FAN=m
+CONFIG_INTEL_CHTDC_TI_PWRBTN=m
+CONFIG_MELLANOX_PLATFORM=y
+CONFIG_SOUNDWIRE_INTEL=m
+# CONFIG_BPF_KPROBE_OVERRIDE is not set
+CONFIG_CRYPTO_DEV_SP_PSP=y
+CONFIG_KVM_AMD_SEV=y
+CONFIG_MLXREG_HOTPLUG=m
Not Available

angrypenguinpoland [@T] gmail.comno package in main/testing repo2396d 23hrs
benbullard79 [@T] cox.netNo can find packages anywhere, think log say bad rpm2393d 10hrs
cris [@T] beebgames.comNo Comment.2392d 08hrs