$ 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(>t->ttm, adev->dev, ctx);
++ if (amdgpu_swiotlb) {
++ if (swiotlb_nr_tbl()) {
++ return ttm_dma_populate(>t->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(>t->ttm, adev->dev);
+- return;
++ if (amdgpu_swiotlb) {
++ if (swiotlb_nr_tbl()) {
++ ttm_dma_unpopulate(>t->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(>t->ttm, rdev->dev, ctx);
++ if (radeon_swiotlb) {
++ if (swiotlb_nr_tbl()) {
++ return ttm_dma_populate(>t->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(>t->ttm, rdev->dev);
+- return;
++ if (radeon_swiotlb) {
++ if (swiotlb_nr_tbl()) {
++ ttm_dma_unpopulate(>t->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(¶ms, 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), ¶ms);
++ 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, ¶ms);
++ 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, ¶ms.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), ¶ms);
++ 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, ¶ms);
++ 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, ¶ms);
++ 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